mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ceecaf6592 | |||
| fb831439e9 | |||
| 018d9a1064 | |||
| 4b382841a1 | |||
| 6834138270 | |||
| bf83ba40a3 | |||
| ca166d7f96 | |||
| 42669454b0 | |||
| 243f3a7516 | |||
| aadba41e66 | |||
| ce1b66cef2 | |||
| 3e18fdc34d | |||
| c09075d71e | |||
| 41b4d7851a | |||
| 92bec5eabb | |||
| 24587ecc92 | |||
| 6865515f43 | |||
| 5ee6f40e75 | |||
| 637189cc2d | |||
| 13bfc9e92b | |||
| 032c5d3a5b | |||
| a53333be20 | |||
| a966f6b19d | |||
| 70d577260b | |||
| ea12982788 | |||
| 6fca6c22c5 | |||
| e343dd017b | |||
| 70a94d772a | |||
| 2689d1e27b | |||
| 4a9b54fbaf | |||
| f10a0ce58e | |||
| 6d488ba489 | |||
| 95776e0951 | |||
| bf9cdf3053 | |||
| fa73e63a79 | |||
| bfab76ed90 | |||
| 905295ee5f | |||
| a1e707ac1b | |||
| fea51b75e9 | |||
| ff8bbf11e7 | |||
| 391e9d57f2 | |||
| dae9f8575d | |||
| 065d9be614 | |||
| 4251762553 |
@@ -354,6 +354,9 @@ final class ChatModel: ObservableObject {
|
||||
addChat(Chat(chatInfo: cInfo, chatItems: [cItem]))
|
||||
res = true
|
||||
}
|
||||
if cItem.isDeletedContent || cItem.meta.itemDeleted != nil {
|
||||
VoiceItemState.stopVoiceInChatView(cInfo, cItem)
|
||||
}
|
||||
// update current chat
|
||||
return chatId == cInfo.id ? _upsertChatItem(cInfo, cItem) : res
|
||||
}
|
||||
@@ -420,6 +423,7 @@ final class ChatModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
VoiceItemState.stopVoiceInChatView(cInfo, cItem)
|
||||
}
|
||||
|
||||
func nextChatItemData<T>(_ chatItemId: Int64, previous: Bool, map: @escaping (ChatItem) -> T?) -> T? {
|
||||
@@ -774,7 +778,7 @@ struct UnreadChatItemCounts: Equatable {
|
||||
var unreadBelow: Int
|
||||
}
|
||||
|
||||
final class Chat: ObservableObject, Identifiable {
|
||||
final class Chat: ObservableObject, Identifiable, ChatLike {
|
||||
@Published var chatInfo: ChatInfo
|
||||
@Published var chatItems: [ChatItem]
|
||||
@Published var chatStats: ChatStats
|
||||
|
||||
@@ -217,7 +217,7 @@ func apiDeleteUser(_ userId: Int64, _ delSMPQueues: Bool, viewPwd: String?) asyn
|
||||
}
|
||||
|
||||
func apiStartChat(ctrl: chat_ctrl? = nil) throws -> Bool {
|
||||
let r = chatSendCmdSync(.startChat(mainApp: true), ctrl)
|
||||
let r = chatSendCmdSync(.startChat(mainApp: true, enableSndFiles: true), ctrl)
|
||||
switch r {
|
||||
case .chatStarted: return true
|
||||
case .chatRunning: return false
|
||||
@@ -225,6 +225,15 @@ func apiStartChat(ctrl: chat_ctrl? = nil) throws -> Bool {
|
||||
}
|
||||
}
|
||||
|
||||
func apiCheckChatRunning() throws -> Bool {
|
||||
let r = chatSendCmdSync(.checkChatRunning)
|
||||
switch r {
|
||||
case .chatRunning: return true
|
||||
case .chatStopped: return false
|
||||
default: throw r
|
||||
}
|
||||
}
|
||||
|
||||
func apiStopChat() async throws {
|
||||
let r = await chatSendCmd(.apiStopChat)
|
||||
switch r {
|
||||
@@ -397,7 +406,7 @@ private func sendMessageErrorAlert(_ r: ChatResponse) {
|
||||
logger.error("send message error: \(String(describing: r))")
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title: "Error sending message",
|
||||
message: "Error: \(String(describing: r))"
|
||||
message: "Error: \(responseError(r))"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -405,7 +414,7 @@ private func createChatItemErrorAlert(_ r: ChatResponse) {
|
||||
logger.error("apiCreateChatItem error: \(String(describing: r))")
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title: "Error creating message",
|
||||
message: "Error: \(String(describing: r))"
|
||||
message: "Error: \(responseError(r))"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -699,7 +708,7 @@ func apiConnect_(incognito: Bool, connReq: String) async -> ((ConnReqType, Pendi
|
||||
message: "Please check that you used the correct link or ask your contact to send you another one."
|
||||
)
|
||||
return (nil, alert)
|
||||
case .chatCmdError(_, .errorAgent(.SMP(.AUTH))):
|
||||
case .chatCmdError(_, .errorAgent(.SMP(_, .AUTH))):
|
||||
let alert = mkAlert(
|
||||
title: "Connection error (AUTH)",
|
||||
message: "Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection."
|
||||
@@ -732,7 +741,7 @@ private func connectionErrorAlert(_ r: ChatResponse) -> Alert {
|
||||
} else {
|
||||
return mkAlert(
|
||||
title: "Connection error",
|
||||
message: "Error: \(String(describing: r))"
|
||||
message: "Error: \(responseError(r))"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -898,7 +907,7 @@ func apiAcceptContactRequest(incognito: Bool, contactReqId: Int64) async -> Cont
|
||||
let am = AlertManager.shared
|
||||
|
||||
if case let .acceptingContactRequest(_, contact) = r { return contact }
|
||||
if case .chatCmdError(_, .errorAgent(.SMP(.AUTH))) = r {
|
||||
if case .chatCmdError(_, .errorAgent(.SMP(_, .AUTH))) = r {
|
||||
am.showAlertMsg(
|
||||
title: "Connection error (AUTH)",
|
||||
message: "Sender may have deleted the connection request."
|
||||
@@ -909,7 +918,7 @@ func apiAcceptContactRequest(incognito: Bool, contactReqId: Int64) async -> Cont
|
||||
logger.error("apiAcceptContactRequest error: \(String(describing: r))")
|
||||
am.showAlertMsg(
|
||||
title: "Error accepting contact request",
|
||||
message: "Error: \(String(describing: r))"
|
||||
message: "Error: \(responseError(r))"
|
||||
)
|
||||
}
|
||||
return nil
|
||||
@@ -935,7 +944,7 @@ func uploadStandaloneFile(user: any UserLike, file: CryptoFile, ctrl: chat_ctrl?
|
||||
return (fileTransferMeta, nil)
|
||||
} else {
|
||||
logger.error("uploadStandaloneFile error: \(String(describing: r))")
|
||||
return (nil, String(describing: r))
|
||||
return (nil, responseError(r))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -945,7 +954,7 @@ func downloadStandaloneFile(user: any UserLike, url: String, file: CryptoFile, c
|
||||
return (rcvFileTransfer, nil)
|
||||
} else {
|
||||
logger.error("downloadStandaloneFile error: \(String(describing: r))")
|
||||
return (nil, String(describing: r))
|
||||
return (nil, responseError(r))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1025,7 +1034,7 @@ func apiReceiveFile(fileId: Int64, userApprovedRelays: Bool, encrypted: Bool, in
|
||||
if !auto {
|
||||
am.showAlertMsg(
|
||||
title: "Error receiving file",
|
||||
message: "Error: \(String(describing: r))"
|
||||
message: "Error: \(responseError(r))"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1091,47 +1100,6 @@ func deleteRemoteCtrl(_ rcId: Int64) async throws {
|
||||
try await sendCommandOkResp(.deleteRemoteCtrl(remoteCtrlId: rcId))
|
||||
}
|
||||
|
||||
struct ErrorAlert {
|
||||
var title: LocalizedStringKey
|
||||
var message: LocalizedStringKey
|
||||
}
|
||||
|
||||
func getNetworkErrorAlert(_ r: ChatResponse) -> ErrorAlert? {
|
||||
switch r {
|
||||
case let .chatCmdError(_, .errorAgent(.BROKER(addr, .TIMEOUT))):
|
||||
return ErrorAlert(title: "Connection timeout", message: "Please check your network connection with \(serverHostname(addr)) and try again.")
|
||||
case let .chatCmdError(_, .errorAgent(.BROKER(addr, .NETWORK))):
|
||||
return ErrorAlert(title: "Connection error", message: "Please check your network connection with \(serverHostname(addr)) and try again.")
|
||||
case let .chatCmdError(_, .errorAgent(.BROKER(addr, .HOST))):
|
||||
return ErrorAlert(title: "Connection error", message: "Server address is incompatible with network settings: \(serverHostname(addr)).")
|
||||
case let .chatCmdError(_, .errorAgent(.BROKER(addr, .TRANSPORT(.version)))):
|
||||
return ErrorAlert(title: "Connection error", message: "Server version is incompatible with your app: \(serverHostname(addr)).")
|
||||
case let .chatCmdError(_, .errorAgent(.SMP(.PROXY(proxyErr)))):
|
||||
return proxyErrorAlert(proxyErr)
|
||||
case let .chatCmdError(_, .errorAgent(.PROXY(_, _, .protocolError(.PROXY(proxyErr))))):
|
||||
return proxyErrorAlert(proxyErr)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
private func proxyErrorAlert(_ proxyErr: ProxyError) -> ErrorAlert? {
|
||||
switch proxyErr {
|
||||
case .BROKER(brokerErr: .TIMEOUT):
|
||||
return ErrorAlert(title: "Private routing error", message: "Please try later.")
|
||||
case .BROKER(brokerErr: .NETWORK):
|
||||
return ErrorAlert(title: "Private routing error", message: "Please try later.")
|
||||
case .NO_SESSION:
|
||||
return ErrorAlert(title: "Private routing error", message: "Please try later.")
|
||||
case .BROKER(brokerErr: .HOST):
|
||||
return ErrorAlert(title: "Private routing error", message: "Server address is incompatible with network settings.")
|
||||
case .BROKER(brokerErr: .TRANSPORT(.version)):
|
||||
return ErrorAlert(title: "Private routing error", message: "Server version is incompatible with network settings.")
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func networkErrorAlert(_ r: ChatResponse) -> Alert? {
|
||||
if let alert = getNetworkErrorAlert(r) {
|
||||
return mkAlert(title: alert.title, message: alert.message)
|
||||
@@ -1143,7 +1111,10 @@ func networkErrorAlert(_ r: ChatResponse) -> Alert? {
|
||||
func acceptContactRequest(incognito: Bool, contactRequest: UserContactRequest) async {
|
||||
if let contact = await apiAcceptContactRequest(incognito: incognito, contactReqId: contactRequest.apiId) {
|
||||
let chat = Chat(chatInfo: ChatInfo.direct(contact: contact), chatItems: [])
|
||||
DispatchQueue.main.async { ChatModel.shared.replaceChat(contactRequest.id, chat) }
|
||||
DispatchQueue.main.async {
|
||||
ChatModel.shared.replaceChat(contactRequest.id, chat)
|
||||
ChatModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1280,7 +1251,7 @@ func apiJoinGroup(_ groupId: Int64) async throws -> JoinGroupResult {
|
||||
let r = await chatSendCmd(.apiJoinGroup(groupId: groupId))
|
||||
switch r {
|
||||
case let .userAcceptedGroupSent(_, groupInfo, _): return .joined(groupInfo: groupInfo)
|
||||
case .chatCmdError(_, .errorAgent(.SMP(.AUTH))): return .invitationRemoved
|
||||
case .chatCmdError(_, .errorAgent(.SMP(_, .AUTH))): return .invitationRemoved
|
||||
case .chatCmdError(_, .errorStore(.groupNotFound)): return .groupNotFound
|
||||
default: throw r
|
||||
}
|
||||
@@ -1386,6 +1357,14 @@ func apiGetVersion() throws -> CoreVersionInfo {
|
||||
throw r
|
||||
}
|
||||
|
||||
func getAgentSubsTotal() throws -> (SMPServerSubs, Bool) {
|
||||
let userId = try currentUserId("getAgentSubsTotal")
|
||||
let r = chatSendCmdSync(.getAgentSubsTotal(userId: userId), log: false)
|
||||
if case let .agentSubsTotal(_, subsTotal, hasSession) = r { return (subsTotal, hasSession) }
|
||||
logger.error("getAgentSubsTotal error: \(String(describing: r))")
|
||||
throw r
|
||||
}
|
||||
|
||||
func getAgentServersSummary() throws -> PresentedServersSummary {
|
||||
let userId = try currentUserId("getAgentServersSummary")
|
||||
let r = chatSendCmdSync(.getAgentServersSummary(userId: userId), log: false)
|
||||
@@ -1469,15 +1448,16 @@ func startChat(refreshInvitations: Bool = true) throws {
|
||||
logger.debug("startChat")
|
||||
let m = ChatModel.shared
|
||||
try setNetworkConfig(getNetCfg())
|
||||
let justStarted = try apiStartChat()
|
||||
let chatRunning = try apiCheckChatRunning()
|
||||
m.users = try listUsers()
|
||||
if justStarted {
|
||||
if !chatRunning {
|
||||
try getUserChatData()
|
||||
NtfManager.shared.setNtfBadgeCount(m.totalUnreadCountForAllUsers())
|
||||
if (refreshInvitations) {
|
||||
try refreshCallInvitations()
|
||||
}
|
||||
(m.savedToken, m.tokenStatus, m.notificationMode, m.notificationServer) = apiGetNtfToken()
|
||||
_ = try apiStartChat()
|
||||
// deviceToken is set when AppDelegate.application(didRegisterForRemoteNotificationsWithDeviceToken:) is called,
|
||||
// when it is called before startChat
|
||||
if let token = m.deviceToken {
|
||||
@@ -1649,6 +1629,19 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
}
|
||||
}
|
||||
}
|
||||
case let .contactSndReady(user, contact):
|
||||
if active(user) && contact.directOrUsed {
|
||||
await MainActor.run {
|
||||
m.updateContact(contact)
|
||||
if let conn = contact.activeConn {
|
||||
m.dismissConnReqView(conn.id)
|
||||
m.removeChat(conn.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
await MainActor.run {
|
||||
m.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
case let .receivedContactRequest(user, contactRequest):
|
||||
if active(user) {
|
||||
let cInfo = ChatInfo.contactRequest(contactRequest: contactRequest)
|
||||
|
||||
@@ -36,6 +36,18 @@ private func _suspendChat(timeout: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
let seSubscriber = seMessageSubscriber {
|
||||
switch $0 {
|
||||
case let .state(state):
|
||||
switch state {
|
||||
case .inactive:
|
||||
if AppChatState.shared.value.inactive { activateChat() }
|
||||
case .sendingMessage:
|
||||
if AppChatState.shared.value.canSuspend { suspendChat() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func suspendChat() {
|
||||
suspendLockQueue.sync {
|
||||
_suspendChat(timeout: appSuspendTimeout)
|
||||
|
||||
@@ -112,7 +112,7 @@ struct ChatInfoView: View {
|
||||
case abortSwitchAddressAlert
|
||||
case syncConnectionForceAlert
|
||||
case queueInfo(info: String)
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey = "")
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey?)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@@ -155,23 +155,25 @@ struct ChatInfoView: View {
|
||||
}
|
||||
|
||||
Section {
|
||||
if let code = connectionCode { verifyCodeButton(code) }
|
||||
contactPreferencesButton()
|
||||
sendReceiptsOption()
|
||||
if let connStats = connectionStats,
|
||||
connStats.ratchetSyncAllowed {
|
||||
synchronizeConnectionButton()
|
||||
Group {
|
||||
if let code = connectionCode { verifyCodeButton(code) }
|
||||
contactPreferencesButton()
|
||||
sendReceiptsOption()
|
||||
if let connStats = connectionStats,
|
||||
connStats.ratchetSyncAllowed {
|
||||
synchronizeConnectionButton()
|
||||
}
|
||||
// } else if developerTools {
|
||||
// synchronizeConnectionButtonForce()
|
||||
// }
|
||||
}
|
||||
.disabled(!contact.ready || !contact.active)
|
||||
NavigationLink {
|
||||
ChatWallpaperEditorSheet(chat: chat)
|
||||
} label: {
|
||||
Label("Chat theme", systemImage: "photo")
|
||||
}
|
||||
// } else if developerTools {
|
||||
// synchronizeConnectionButtonForce()
|
||||
// }
|
||||
}
|
||||
.disabled(!contact.ready || !contact.active)
|
||||
|
||||
if let conn = contact.activeConn {
|
||||
Section {
|
||||
@@ -271,7 +273,7 @@ struct ChatInfoView: View {
|
||||
}
|
||||
}
|
||||
.actionSheet(isPresented: $showDeleteContactActionSheet) {
|
||||
if contact.ready && contact.active {
|
||||
if contact.sndReady && contact.active {
|
||||
return ActionSheet(
|
||||
title: Text("Delete contact?\nThis cannot be undone!"),
|
||||
buttons: [
|
||||
|
||||
@@ -9,6 +9,7 @@ import SwiftUI
|
||||
class AnimatedImageView: UIView {
|
||||
var image: UIImage? = nil
|
||||
var imageView: UIImageView? = nil
|
||||
var cMode: UIView.ContentMode = .scaleAspectFit
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
@@ -18,11 +19,12 @@ class AnimatedImageView: UIView {
|
||||
fatalError("Not implemented")
|
||||
}
|
||||
|
||||
convenience init(image: UIImage) {
|
||||
convenience init(image: UIImage, contentMode: UIView.ContentMode) {
|
||||
self.init()
|
||||
self.image = image
|
||||
self.cMode = contentMode
|
||||
imageView = UIImageView(gifImage: image)
|
||||
imageView!.contentMode = .scaleAspectFit
|
||||
imageView!.contentMode = contentMode
|
||||
self.addSubview(imageView!)
|
||||
}
|
||||
|
||||
@@ -35,7 +37,7 @@ class AnimatedImageView: UIView {
|
||||
if let subview = self.subviews.first as? UIImageView {
|
||||
if image.imageData != subview.gifImage?.imageData {
|
||||
imageView = UIImageView(gifImage: image)
|
||||
imageView!.contentMode = .scaleAspectFit
|
||||
imageView!.contentMode = contentMode
|
||||
self.addSubview(imageView!)
|
||||
subview.removeFromSuperview()
|
||||
}
|
||||
@@ -47,13 +49,15 @@ class AnimatedImageView: UIView {
|
||||
|
||||
struct SwiftyGif: UIViewRepresentable {
|
||||
private let image: UIImage
|
||||
private let contentMode: UIView.ContentMode
|
||||
|
||||
init(image: UIImage) {
|
||||
init(image: UIImage, contentMode: UIView.ContentMode = .scaleAspectFit) {
|
||||
self.image = image
|
||||
self.contentMode = contentMode
|
||||
}
|
||||
|
||||
func makeUIView(context: Context) -> AnimatedImageView {
|
||||
AnimatedImageView(image: image)
|
||||
AnimatedImageView(image: image, contentMode: contentMode)
|
||||
}
|
||||
|
||||
func updateUIView(_ imageView: AnimatedImageView, context: Context) {
|
||||
|
||||
@@ -14,39 +14,45 @@ struct CIFileView: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
let file: CIFile?
|
||||
let edited: Bool
|
||||
var smallViewSize: CGFloat?
|
||||
|
||||
var body: some View {
|
||||
let metaReserve = edited
|
||||
? " "
|
||||
: " "
|
||||
Button(action: fileAction) {
|
||||
HStack(alignment: .bottom, spacing: 6) {
|
||||
fileIndicator()
|
||||
.padding(.top, 5)
|
||||
.padding(.bottom, 3)
|
||||
if let file = file {
|
||||
let prettyFileSize = ByteCountFormatter.string(fromByteCount: file.fileSize, countStyle: .binary)
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(file.fileName)
|
||||
.lineLimit(1)
|
||||
.multilineTextAlignment(.leading)
|
||||
.foregroundColor(theme.colors.onBackground)
|
||||
Text(prettyFileSize + metaReserve)
|
||||
.font(.caption)
|
||||
.lineLimit(1)
|
||||
.multilineTextAlignment(.leading)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
if smallViewSize != nil {
|
||||
fileIndicator()
|
||||
.onTapGesture(perform: fileAction)
|
||||
} else {
|
||||
let metaReserve = edited
|
||||
? " "
|
||||
: " "
|
||||
Button(action: fileAction) {
|
||||
HStack(alignment: .bottom, spacing: 6) {
|
||||
fileIndicator()
|
||||
.padding(.top, 5)
|
||||
.padding(.bottom, 3)
|
||||
if let file = file {
|
||||
let prettyFileSize = ByteCountFormatter.string(fromByteCount: file.fileSize, countStyle: .binary)
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(file.fileName)
|
||||
.lineLimit(1)
|
||||
.multilineTextAlignment(.leading)
|
||||
.foregroundColor(theme.colors.onBackground)
|
||||
Text(prettyFileSize + metaReserve)
|
||||
.font(.caption)
|
||||
.lineLimit(1)
|
||||
.multilineTextAlignment(.leading)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
}
|
||||
} else {
|
||||
Text(metaReserve)
|
||||
}
|
||||
} else {
|
||||
Text(metaReserve)
|
||||
}
|
||||
.padding(.top, 4)
|
||||
.padding(.bottom, 6)
|
||||
.padding(.leading, 10)
|
||||
.padding(.trailing, 12)
|
||||
}
|
||||
.padding(.top, 4)
|
||||
.padding(.bottom, 6)
|
||||
.padding(.leading, 10)
|
||||
.padding(.trailing, 12)
|
||||
.disabled(!itemInteractive)
|
||||
}
|
||||
.disabled(!itemInteractive)
|
||||
}
|
||||
|
||||
private var itemInteractive: Bool {
|
||||
@@ -195,21 +201,22 @@ struct CIFileView: View {
|
||||
}
|
||||
|
||||
private func fileIcon(_ icon: String, color: Color = Color(uiColor: .tertiaryLabel), innerIcon: String? = nil, innerIconSize: CGFloat? = nil) -> some View {
|
||||
ZStack(alignment: .center) {
|
||||
let size = smallViewSize ?? 30
|
||||
return ZStack(alignment: .center) {
|
||||
Image(systemName: icon)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 30, height: 30)
|
||||
.frame(width: size, height: size)
|
||||
.foregroundColor(color)
|
||||
if let innerIcon = innerIcon,
|
||||
let innerIconSize = innerIconSize {
|
||||
let innerIconSize = innerIconSize, (smallViewSize == nil || file?.showStatusIconInSmallView == true) {
|
||||
Image(systemName: innerIcon)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(maxHeight: 16)
|
||||
.frame(width: innerIconSize, height: innerIconSize)
|
||||
.foregroundColor(.white)
|
||||
.padding(.top, 12)
|
||||
.padding(.top, size / 2.5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,22 +15,33 @@ struct CIImageView: View {
|
||||
var preview: UIImage?
|
||||
let maxWidth: CGFloat
|
||||
var imgWidth: CGFloat?
|
||||
@State private var showFullScreenImage = false
|
||||
var smallView: Bool = false
|
||||
@Binding var showFullScreenImage: Bool
|
||||
@State private var blurred: Bool = UserDefaults.standard.integer(forKey: DEFAULT_PRIVACY_MEDIA_BLUR_RADIUS) > 0
|
||||
|
||||
var body: some View {
|
||||
let file = chatItem.file
|
||||
VStack(alignment: .center, spacing: 6) {
|
||||
if let uiImage = getLoadedImage(file) {
|
||||
imageView(uiImage)
|
||||
Group { if smallView { smallViewImageView(uiImage) } else { imageView(uiImage) } }
|
||||
.fullScreenCover(isPresented: $showFullScreenImage) {
|
||||
FullScreenMediaView(chatItem: chatItem, image: uiImage, showView: $showFullScreenImage)
|
||||
}
|
||||
.if(!smallView) { view in
|
||||
view.modifier(PrivacyBlur(blurred: $blurred))
|
||||
}
|
||||
.onTapGesture { showFullScreenImage = true }
|
||||
.onChange(of: m.activeCallViewIsCollapsed) { _ in
|
||||
showFullScreenImage = false
|
||||
}
|
||||
} else if let preview {
|
||||
imageView(preview)
|
||||
Group {
|
||||
if smallView {
|
||||
smallViewImageView(preview)
|
||||
} else {
|
||||
imageView(preview).modifier(PrivacyBlur(blurred: $blurred))
|
||||
}
|
||||
}
|
||||
.onTapGesture {
|
||||
if let file = file {
|
||||
switch file.fileStatus {
|
||||
@@ -83,6 +94,9 @@ struct CIImageView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.onDisappear {
|
||||
showFullScreenImage = false
|
||||
}
|
||||
}
|
||||
|
||||
private func imageView(_ img: UIImage) -> some View {
|
||||
@@ -98,7 +112,26 @@ struct CIImageView: View {
|
||||
.frame(width: w, height: w * img.size.height / img.size.width)
|
||||
.scaledToFit()
|
||||
}
|
||||
loadingIndicator()
|
||||
if !blurred || !showDownloadButton(chatItem.file?.fileStatus) {
|
||||
loadingIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func smallViewImageView(_ img: UIImage) -> some View {
|
||||
ZStack(alignment: .topTrailing) {
|
||||
if img.imageData == nil {
|
||||
Image(uiImage: img)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: maxWidth, height: maxWidth)
|
||||
} else {
|
||||
SwiftyGif(image: img, contentMode: .scaleAspectFill)
|
||||
.frame(width: maxWidth, height: maxWidth)
|
||||
}
|
||||
if chatItem.file?.showStatusIconInSmallView == true {
|
||||
loadingIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,4 +178,12 @@ struct CIImageView: View {
|
||||
.tint(.white)
|
||||
.padding(8)
|
||||
}
|
||||
|
||||
private func showDownloadButton(_ fileStatus: CIFileStatus?) -> Bool {
|
||||
switch fileStatus {
|
||||
case .rcvInvitation: true
|
||||
case .rcvAborted: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import SimpleXChat
|
||||
struct CILinkView: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
let linkPreview: LinkPreview
|
||||
@State private var blurred: Bool = UserDefaults.standard.integer(forKey: DEFAULT_PRIVACY_MEDIA_BLUR_RADIUS) > 0
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .center, spacing: 6) {
|
||||
@@ -19,6 +20,7 @@ struct CILinkView: View {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.modifier(PrivacyBlur(blurred: $blurred))
|
||||
}
|
||||
VStack(alignment: .leading, spacing: 6) {
|
||||
Text(linkPreview.title)
|
||||
|
||||
@@ -27,7 +27,7 @@ struct CIRcvDecryptionError: View {
|
||||
case syncNotSupportedContactAlert
|
||||
case syncNotSupportedMemberAlert
|
||||
case decryptionErrorAlert
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey)
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey?)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@@ -62,7 +62,7 @@ struct CIRcvDecryptionError: View {
|
||||
case .syncNotSupportedContactAlert: return Alert(title: Text("Fix not supported by contact"), message: message())
|
||||
case .syncNotSupportedMemberAlert: return Alert(title: Text("Fix not supported by group member"), message: message())
|
||||
case .decryptionErrorAlert: return Alert(title: Text("Decryption error"), message: message())
|
||||
case let .error(title, error): return Alert(title: Text(title), message: Text(error))
|
||||
case let .error(title, error): return mkAlert(title: title, message: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,45 +20,44 @@ struct CIVideoView: View {
|
||||
@State private var videoPlaying: Bool = false
|
||||
private let maxWidth: CGFloat
|
||||
private var videoWidth: CGFloat?
|
||||
private let smallView: Bool
|
||||
@State private var player: AVPlayer?
|
||||
@State private var fullPlayer: AVPlayer?
|
||||
@State private var url: URL?
|
||||
@State private var urlDecrypted: URL?
|
||||
@State private var decryptionInProgress: Bool = false
|
||||
@State private var showFullScreenPlayer = false
|
||||
@Binding private var showFullScreenPlayer: Bool
|
||||
@State private var timeObserver: Any? = nil
|
||||
@State private var fullScreenTimeObserver: Any? = nil
|
||||
@State private var publisher: AnyCancellable? = nil
|
||||
private var sizeMultiplier: CGFloat { smallView ? 0.38 : 1 }
|
||||
@State private var blurred: Bool = UserDefaults.standard.integer(forKey: DEFAULT_PRIVACY_MEDIA_BLUR_RADIUS) > 0
|
||||
|
||||
init(chatItem: ChatItem, preview: UIImage?, duration: Int, maxWidth: CGFloat, videoWidth: CGFloat?) {
|
||||
init(chatItem: ChatItem, preview: UIImage?, duration: Int, maxWidth: CGFloat, videoWidth: CGFloat?, smallView: Bool = false, showFullscreenPlayer: Binding<Bool>) {
|
||||
self.chatItem = chatItem
|
||||
self.preview = preview
|
||||
self._duration = State(initialValue: duration)
|
||||
self.maxWidth = maxWidth
|
||||
self.videoWidth = videoWidth
|
||||
if let url = getLoadedVideo(chatItem.file) {
|
||||
let decrypted = chatItem.file?.fileSource?.cryptoArgs == nil ? url : chatItem.file?.fileSource?.decryptedGet()
|
||||
self._urlDecrypted = State(initialValue: decrypted)
|
||||
if let decrypted = decrypted {
|
||||
self._player = State(initialValue: VideoPlayerView.getOrCreatePlayer(decrypted, false))
|
||||
self._fullPlayer = State(initialValue: AVPlayer(url: decrypted))
|
||||
}
|
||||
self._url = State(initialValue: url)
|
||||
}
|
||||
self.smallView = smallView
|
||||
self._showFullScreenPlayer = showFullscreenPlayer
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
let file = chatItem.file
|
||||
ZStack {
|
||||
ZStack(alignment: smallView ? .topLeading : .center) {
|
||||
ZStack(alignment: .topLeading) {
|
||||
if let file = file, let preview = preview, let player = player, let decrypted = urlDecrypted {
|
||||
if let file = file, let preview = preview, let decrypted = urlDecrypted, smallView {
|
||||
smallVideoView(decrypted, file, preview)
|
||||
} else if let file = file, let preview = preview, let player = player, let decrypted = urlDecrypted {
|
||||
videoView(player, decrypted, file, preview, duration)
|
||||
} else if let file = file, let defaultPreview = preview, file.loaded && urlDecrypted == nil, smallView {
|
||||
smallVideoViewEncrypted(file, defaultPreview)
|
||||
} else if let file = file, let defaultPreview = preview, file.loaded && urlDecrypted == nil {
|
||||
videoViewEncrypted(file, defaultPreview, duration)
|
||||
} else if let preview {
|
||||
imageView(preview)
|
||||
.onTapGesture {
|
||||
if let file = file {
|
||||
} else if let preview, let file {
|
||||
Group { if smallView { smallViewImageView(preview, file) } else { imageView(preview) } }
|
||||
.onTapGesture {
|
||||
switch file.fileStatus {
|
||||
case .rcvInvitation, .rcvAborted:
|
||||
receiveFileIfValidSize(file: file, receiveFile: receiveFile)
|
||||
@@ -82,21 +81,64 @@ struct CIVideoView: View {
|
||||
default: ()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
durationProgress()
|
||||
if !smallView {
|
||||
durationProgress()
|
||||
}
|
||||
}
|
||||
if let file = file, showDownloadButton(file.fileStatus) {
|
||||
Button {
|
||||
receiveFileIfValidSize(file: file, receiveFile: receiveFile)
|
||||
} label: {
|
||||
if !blurred, let file, showDownloadButton(file.fileStatus) {
|
||||
if !smallView {
|
||||
Button {
|
||||
receiveFileIfValidSize(file: file, receiveFile: receiveFile)
|
||||
} label: {
|
||||
playPauseIcon("play.fill")
|
||||
}
|
||||
} else if !file.showStatusIconInSmallView {
|
||||
playPauseIcon("play.fill")
|
||||
.onTapGesture {
|
||||
receiveFileIfValidSize(file: file, receiveFile: receiveFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.fullScreenCover(isPresented: $showFullScreenPlayer) {
|
||||
if let decrypted = urlDecrypted {
|
||||
fullScreenPlayer(decrypted)
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
setupPlayer(chatItem.file)
|
||||
}
|
||||
.onChange(of: chatItem.file) { file in
|
||||
// ChatItem can be changed in small view on chat list screen
|
||||
setupPlayer(file)
|
||||
}
|
||||
.onDisappear {
|
||||
showFullScreenPlayer = false
|
||||
}
|
||||
}
|
||||
|
||||
private func showDownloadButton(_ fileStatus: CIFileStatus) -> Bool {
|
||||
private func setupPlayer(_ file: CIFile?) {
|
||||
let newUrl = getLoadedVideo(file)
|
||||
if newUrl == url {
|
||||
return
|
||||
}
|
||||
url = nil
|
||||
urlDecrypted = nil
|
||||
player = nil
|
||||
fullPlayer = nil
|
||||
if let newUrl {
|
||||
let decrypted = file?.fileSource?.cryptoArgs == nil ? newUrl : file?.fileSource?.decryptedGet()
|
||||
urlDecrypted = decrypted
|
||||
if let decrypted = decrypted {
|
||||
player = VideoPlayerView.getOrCreatePlayer(decrypted, false)
|
||||
fullPlayer = AVPlayer(url: decrypted)
|
||||
}
|
||||
url = newUrl
|
||||
}
|
||||
}
|
||||
|
||||
private func showDownloadButton(_ fileStatus: CIFileStatus?) -> Bool {
|
||||
switch fileStatus {
|
||||
case .rcvInvitation: true
|
||||
case .rcvAborted: true
|
||||
@@ -109,11 +151,6 @@ struct CIVideoView: View {
|
||||
ZStack(alignment: .center) {
|
||||
let canBePlayed = !chatItem.chatDir.sent || file.fileStatus == CIFileStatus.sndComplete || (file.fileStatus == .sndStored && file.fileProtocol == .local)
|
||||
imageView(defaultPreview)
|
||||
.fullScreenCover(isPresented: $showFullScreenPlayer) {
|
||||
if let decrypted = urlDecrypted {
|
||||
fullScreenPlayer(decrypted)
|
||||
}
|
||||
}
|
||||
.onTapGesture {
|
||||
decrypt(file: file) {
|
||||
showFullScreenPlayer = urlDecrypted != nil
|
||||
@@ -122,20 +159,22 @@ struct CIVideoView: View {
|
||||
.onChange(of: m.activeCallViewIsCollapsed) { _ in
|
||||
showFullScreenPlayer = false
|
||||
}
|
||||
if !decryptionInProgress {
|
||||
Button {
|
||||
decrypt(file: file) {
|
||||
if urlDecrypted != nil {
|
||||
videoPlaying = true
|
||||
player?.play()
|
||||
if !blurred {
|
||||
if !decryptionInProgress {
|
||||
Button {
|
||||
decrypt(file: file) {
|
||||
if urlDecrypted != nil {
|
||||
videoPlaying = true
|
||||
player?.play()
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
playPauseIcon(canBePlayed ? "play.fill" : "play.slash")
|
||||
}
|
||||
} label: {
|
||||
playPauseIcon(canBePlayed ? "play.fill" : "play.slash")
|
||||
.disabled(!canBePlayed)
|
||||
} else {
|
||||
videoDecryptionProgress()
|
||||
}
|
||||
.disabled(!canBePlayed)
|
||||
} else {
|
||||
videoDecryptionProgress()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,9 +193,7 @@ struct CIVideoView: View {
|
||||
videoPlaying = false
|
||||
}
|
||||
}
|
||||
.fullScreenCover(isPresented: $showFullScreenPlayer) {
|
||||
fullScreenPlayer(url)
|
||||
}
|
||||
.modifier(PrivacyBlur(enabled: !videoPlaying, blurred: $blurred))
|
||||
.onTapGesture {
|
||||
switch player.timeControlStatus {
|
||||
case .playing:
|
||||
@@ -172,7 +209,7 @@ struct CIVideoView: View {
|
||||
.onChange(of: m.activeCallViewIsCollapsed) { _ in
|
||||
showFullScreenPlayer = false
|
||||
}
|
||||
if !videoPlaying {
|
||||
if !videoPlaying && !blurred {
|
||||
Button {
|
||||
m.stopPreviousRecPlay = url
|
||||
player.play()
|
||||
@@ -194,14 +231,53 @@ struct CIVideoView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func smallVideoViewEncrypted(_ file: CIFile, _ preview: UIImage) -> some View {
|
||||
return ZStack(alignment: .topLeading) {
|
||||
let canBePlayed = !chatItem.chatDir.sent || file.fileStatus == CIFileStatus.sndComplete || (file.fileStatus == .sndStored && file.fileProtocol == .local)
|
||||
smallViewImageView(preview, file)
|
||||
.onTapGesture {
|
||||
decrypt(file: file) {
|
||||
showFullScreenPlayer = urlDecrypted != nil
|
||||
}
|
||||
}
|
||||
.onChange(of: m.activeCallViewIsCollapsed) { _ in
|
||||
showFullScreenPlayer = false
|
||||
}
|
||||
if file.showStatusIconInSmallView {
|
||||
// Show nothing
|
||||
} else if !decryptionInProgress {
|
||||
playPauseIcon(canBePlayed ? "play.fill" : "play.slash")
|
||||
} else {
|
||||
videoDecryptionProgress()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func smallVideoView(_ url: URL, _ file: CIFile, _ preview: UIImage) -> some View {
|
||||
return ZStack(alignment: .topLeading) {
|
||||
smallViewImageView(preview, file)
|
||||
.onTapGesture {
|
||||
showFullScreenPlayer = true
|
||||
}
|
||||
.onChange(of: m.activeCallViewIsCollapsed) { _ in
|
||||
showFullScreenPlayer = false
|
||||
}
|
||||
|
||||
if !file.showStatusIconInSmallView {
|
||||
playPauseIcon("play.fill")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func playPauseIcon(_ image: String, _ color: Color = .white) -> some View {
|
||||
Image(systemName: image)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 12, height: 12)
|
||||
.frame(width: smallView ? 12 * sizeMultiplier * 1.6 : 12, height: smallView ? 12 * sizeMultiplier * 1.6 : 12)
|
||||
.foregroundColor(color)
|
||||
.padding(.leading, 4)
|
||||
.frame(width: 40, height: 40)
|
||||
.padding(.leading, smallView ? 0 : 4)
|
||||
.frame(width: 40 * sizeMultiplier, height: 40 * sizeMultiplier)
|
||||
.background(Color.black.opacity(0.35))
|
||||
.clipShape(Circle())
|
||||
}
|
||||
@@ -209,9 +285,9 @@ struct CIVideoView: View {
|
||||
private func videoDecryptionProgress(_ color: Color = .white) -> some View {
|
||||
ProgressView()
|
||||
.progressViewStyle(.circular)
|
||||
.frame(width: 12, height: 12)
|
||||
.frame(width: smallView ? 12 * sizeMultiplier : 12, height: smallView ? 12 * sizeMultiplier : 12)
|
||||
.tint(color)
|
||||
.frame(width: 40, height: 40)
|
||||
.frame(width: smallView ? 40 * sizeMultiplier * 0.9 : 40, height: smallView ? 40 * sizeMultiplier * 0.9 : 40)
|
||||
.background(Color.black.opacity(0.35))
|
||||
.clipShape(Circle())
|
||||
}
|
||||
@@ -247,7 +323,23 @@ struct CIVideoView: View {
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: w)
|
||||
fileStatusIcon()
|
||||
.modifier(PrivacyBlur(blurred: $blurred))
|
||||
if !blurred || !showDownloadButton(chatItem.file?.fileStatus) {
|
||||
fileStatusIcon()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func smallViewImageView(_ img: UIImage, _ file: CIFile) -> some View {
|
||||
ZStack(alignment: .center) {
|
||||
Image(uiImage: img)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: maxWidth, height: maxWidth)
|
||||
if file.showStatusIconInSmallView {
|
||||
fileStatusIcon()
|
||||
.allowsHitTesting(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +414,7 @@ struct CIVideoView: View {
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: size, height: size)
|
||||
.foregroundColor(.white)
|
||||
.padding(padding)
|
||||
.padding(smallView ? 0 : padding)
|
||||
}
|
||||
|
||||
private func progressView() -> some View {
|
||||
@@ -330,7 +422,7 @@ struct CIVideoView: View {
|
||||
.progressViewStyle(.circular)
|
||||
.frame(width: 16, height: 16)
|
||||
.tint(.white)
|
||||
.padding(11)
|
||||
.padding(smallView ? 0 : 11)
|
||||
}
|
||||
|
||||
private func progressCircle(_ progress: Int64, _ total: Int64) -> some View {
|
||||
@@ -342,7 +434,7 @@ struct CIVideoView: View {
|
||||
)
|
||||
.rotationEffect(.degrees(-90))
|
||||
.frame(width: 16, height: 16)
|
||||
.padding([.trailing, .top], 11)
|
||||
.padding([.trailing, .top], smallView ? 0 : 11)
|
||||
}
|
||||
|
||||
// TODO encrypt: where file size is checked?
|
||||
@@ -382,7 +474,8 @@ struct CIVideoView: View {
|
||||
)
|
||||
.onAppear {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now()) {
|
||||
m.stopPreviousRecPlay = url
|
||||
// Prevent feedback loop - setting `ChatModel`s property causes `onAppear` to be called on iOS17+
|
||||
if m.stopPreviousRecPlay != url { m.stopPreviousRecPlay = url }
|
||||
if let player = fullPlayer {
|
||||
player.play()
|
||||
var played = false
|
||||
@@ -419,10 +512,12 @@ struct CIVideoView: View {
|
||||
urlDecrypted = await file.fileSource?.decryptedGetOrCreate(&ChatModel.shared.filesToDelete)
|
||||
await MainActor.run {
|
||||
if let decrypted = urlDecrypted {
|
||||
player = VideoPlayerView.getOrCreatePlayer(decrypted, false)
|
||||
if !smallView {
|
||||
player = VideoPlayerView.getOrCreatePlayer(decrypted, false)
|
||||
}
|
||||
fullPlayer = AVPlayer(url: decrypted)
|
||||
}
|
||||
decryptionInProgress = true
|
||||
decryptionInProgress = false
|
||||
completed?()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,15 +15,26 @@ struct CIVoiceView: View {
|
||||
var chatItem: ChatItem
|
||||
let recordingFile: CIFile?
|
||||
let duration: Int
|
||||
@Binding var audioPlayer: AudioPlayer?
|
||||
@Binding var playbackState: VoiceMessagePlaybackState
|
||||
@Binding var playbackTime: TimeInterval?
|
||||
@State var audioPlayer: AudioPlayer? = nil
|
||||
@State var playbackState: VoiceMessagePlaybackState = .noPlayback
|
||||
@State var playbackTime: TimeInterval? = nil
|
||||
|
||||
@Binding var allowMenu: Bool
|
||||
var smallViewSize: CGFloat?
|
||||
@State private var seek: (TimeInterval) -> Void = { _ in }
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
if chatItem.chatDir.sent {
|
||||
if smallViewSize != nil {
|
||||
HStack(spacing: 10) {
|
||||
player()
|
||||
playerTime()
|
||||
.allowsHitTesting(false)
|
||||
if .playing == playbackState || (playbackTime ?? 0) > 0 || !allowMenu {
|
||||
playbackSlider()
|
||||
}
|
||||
}
|
||||
} else if chatItem.chatDir.sent {
|
||||
VStack (alignment: .trailing, spacing: 6) {
|
||||
HStack {
|
||||
if .playing == playbackState || (playbackTime ?? 0) > 0 || !allowMenu {
|
||||
@@ -54,7 +65,13 @@ struct CIVoiceView: View {
|
||||
}
|
||||
|
||||
private func player() -> some View {
|
||||
VoiceMessagePlayer(
|
||||
let sizeMultiplier: CGFloat = if let sz = smallViewSize {
|
||||
voiceMessageSizeBasedOnSquareSize(sz) / 56
|
||||
} else {
|
||||
1
|
||||
}
|
||||
return VoiceMessagePlayer(
|
||||
chat: chat,
|
||||
chatItem: chatItem,
|
||||
recordingFile: recordingFile,
|
||||
recordingTime: TimeInterval(duration),
|
||||
@@ -63,7 +80,8 @@ struct CIVoiceView: View {
|
||||
audioPlayer: $audioPlayer,
|
||||
playbackState: $playbackState,
|
||||
playbackTime: $playbackTime,
|
||||
allowMenu: $allowMenu
|
||||
allowMenu: $allowMenu,
|
||||
sizeMultiplier: sizeMultiplier
|
||||
)
|
||||
}
|
||||
|
||||
@@ -119,6 +137,7 @@ struct VoiceMessagePlayerTime: View {
|
||||
}
|
||||
|
||||
struct VoiceMessagePlayer: View {
|
||||
@ObservedObject var chat: Chat
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
var chatItem: ChatItem
|
||||
@@ -130,7 +149,9 @@ struct VoiceMessagePlayer: View {
|
||||
@Binding var audioPlayer: AudioPlayer?
|
||||
@Binding var playbackState: VoiceMessagePlaybackState
|
||||
@Binding var playbackTime: TimeInterval?
|
||||
|
||||
@Binding var allowMenu: Bool
|
||||
var sizeMultiplier: CGFloat
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
@@ -190,49 +211,113 @@ struct VoiceMessagePlayer: View {
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
if audioPlayer == nil {
|
||||
let small = sizeMultiplier != 1
|
||||
audioPlayer = small ? VoiceItemState.smallView[VoiceItemState.id(chat, chatItem)]?.audioPlayer : VoiceItemState.chatView[VoiceItemState.id(chat, chatItem)]?.audioPlayer
|
||||
playbackState = (small ? VoiceItemState.smallView[VoiceItemState.id(chat, chatItem)]?.playbackState : VoiceItemState.chatView[VoiceItemState.id(chat, chatItem)]?.playbackState) ?? .noPlayback
|
||||
playbackTime = small ? VoiceItemState.smallView[VoiceItemState.id(chat, chatItem)]?.playbackTime : VoiceItemState.chatView[VoiceItemState.id(chat, chatItem)]?.playbackTime
|
||||
}
|
||||
seek = { to in audioPlayer?.seek(to) }
|
||||
audioPlayer?.onTimer = { playbackTime = $0 }
|
||||
let audioPath: URL? = if let recordingSource = getLoadedFileSource(recordingFile) {
|
||||
getAppFilePath(recordingSource.filePath)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
let chatId = chatModel.chatId
|
||||
let userId = chatModel.currentUser?.userId
|
||||
audioPlayer?.onTimer = {
|
||||
playbackTime = $0
|
||||
notifyStateChange()
|
||||
// Manual check here is needed because when this view is not visible, SwiftUI don't react on stopPreviousRecPlay, chatId and current user changes and audio keeps playing when it should stop
|
||||
if (audioPath != nil && chatModel.stopPreviousRecPlay != audioPath) || chatModel.chatId != chatId || chatModel.currentUser?.userId != userId {
|
||||
stopPlayback()
|
||||
}
|
||||
}
|
||||
audioPlayer?.onFinishPlayback = {
|
||||
playbackState = .noPlayback
|
||||
playbackTime = TimeInterval(0)
|
||||
notifyStateChange()
|
||||
}
|
||||
// One voice message was paused, then scrolled far from it, started to play another one, drop to stopped state
|
||||
if let audioPath, chatModel.stopPreviousRecPlay != audioPath {
|
||||
stopPlayback()
|
||||
}
|
||||
}
|
||||
.onChange(of: chatModel.stopPreviousRecPlay) { it in
|
||||
if let recordingFileName = getLoadedFileSource(recordingFile)?.filePath,
|
||||
chatModel.stopPreviousRecPlay != getAppFilePath(recordingFileName) {
|
||||
audioPlayer?.stop()
|
||||
playbackState = .noPlayback
|
||||
playbackTime = TimeInterval(0)
|
||||
stopPlayback()
|
||||
}
|
||||
}
|
||||
.onChange(of: playbackState) { state in
|
||||
allowMenu = state == .paused || state == .noPlayback
|
||||
// Notify activeContentPreview in ChatPreviewView that playback is finished
|
||||
if state == .noPlayback, let recordingFileName = getLoadedFileSource(recordingFile)?.filePath,
|
||||
chatModel.stopPreviousRecPlay == getAppFilePath(recordingFileName) {
|
||||
chatModel.stopPreviousRecPlay = nil
|
||||
}
|
||||
}
|
||||
.onChange(of: chatModel.chatId) { _ in
|
||||
stopPlayback()
|
||||
}
|
||||
.onDisappear {
|
||||
if sizeMultiplier == 1 && chatModel.chatId == nil {
|
||||
stopPlayback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func playbackButton() -> some View {
|
||||
switch playbackState {
|
||||
case .noPlayback:
|
||||
Button {
|
||||
if let recordingSource = getLoadedFileSource(recordingFile) {
|
||||
startPlayback(recordingSource)
|
||||
}
|
||||
} label: {
|
||||
if sizeMultiplier != 1 {
|
||||
switch playbackState {
|
||||
case .noPlayback:
|
||||
playPauseIcon("play.fill", theme.colors.primary)
|
||||
}
|
||||
case .playing:
|
||||
Button {
|
||||
audioPlayer?.pause()
|
||||
playbackState = .paused
|
||||
} label: {
|
||||
.onTapGesture {
|
||||
if let recordingSource = getLoadedFileSource(recordingFile) {
|
||||
startPlayback(recordingSource)
|
||||
}
|
||||
}
|
||||
case .playing:
|
||||
playPauseIcon("pause.fill", theme.colors.primary)
|
||||
}
|
||||
case .paused:
|
||||
Button {
|
||||
audioPlayer?.play()
|
||||
playbackState = .playing
|
||||
} label: {
|
||||
.onTapGesture {
|
||||
audioPlayer?.pause()
|
||||
playbackState = .paused
|
||||
notifyStateChange()
|
||||
}
|
||||
case .paused:
|
||||
playPauseIcon("play.fill", theme.colors.primary)
|
||||
.onTapGesture {
|
||||
audioPlayer?.play()
|
||||
playbackState = .playing
|
||||
notifyStateChange()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch playbackState {
|
||||
case .noPlayback:
|
||||
Button {
|
||||
if let recordingSource = getLoadedFileSource(recordingFile) {
|
||||
startPlayback(recordingSource)
|
||||
}
|
||||
} label: {
|
||||
playPauseIcon("play.fill", theme.colors.primary)
|
||||
}
|
||||
case .playing:
|
||||
Button {
|
||||
audioPlayer?.pause()
|
||||
playbackState = .paused
|
||||
notifyStateChange()
|
||||
} label: {
|
||||
playPauseIcon("pause.fill", theme.colors.primary)
|
||||
}
|
||||
case .paused:
|
||||
Button {
|
||||
audioPlayer?.play()
|
||||
playbackState = .playing
|
||||
notifyStateChange()
|
||||
} label: {
|
||||
playPauseIcon("play.fill", theme.colors.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -242,28 +327,49 @@ struct VoiceMessagePlayer: View {
|
||||
Image(systemName: image)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 20, height: 20)
|
||||
.frame(width: 20 * sizeMultiplier, height: 20 * sizeMultiplier)
|
||||
.foregroundColor(color)
|
||||
.padding(.leading, image == "play.fill" ? 4 : 0)
|
||||
.frame(width: 56, height: 56)
|
||||
.frame(width: 56 * sizeMultiplier, height: 56 * sizeMultiplier)
|
||||
.background(showBackground ? chatItemFrameColor(chatItem, theme) : .clear)
|
||||
.clipShape(Circle())
|
||||
if recordingTime > 0 {
|
||||
ProgressCircle(length: recordingTime, progress: $playbackTime)
|
||||
.frame(width: 53, height: 53) // this + ProgressCircle lineWidth = background circle diameter
|
||||
.frame(width: 53 * sizeMultiplier, height: 53 * sizeMultiplier) // this + ProgressCircle lineWidth = background circle diameter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func downloadButton(_ recordingFile: CIFile, _ icon: String) -> some View {
|
||||
Button {
|
||||
Task {
|
||||
if let user = chatModel.currentUser {
|
||||
await receiveFile(user: user, fileId: recordingFile.fileId)
|
||||
Group {
|
||||
if sizeMultiplier != 1 {
|
||||
playPauseIcon(icon, theme.colors.primary)
|
||||
.onTapGesture {
|
||||
Task {
|
||||
if let user = chatModel.currentUser {
|
||||
await receiveFile(user: user, fileId: recordingFile.fileId)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Button {
|
||||
Task {
|
||||
if let user = chatModel.currentUser {
|
||||
await receiveFile(user: user, fileId: recordingFile.fileId)
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
playPauseIcon(icon, theme.colors.primary)
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
playPauseIcon(icon, theme.colors.primary)
|
||||
}
|
||||
}
|
||||
|
||||
func notifyStateChange() {
|
||||
if sizeMultiplier != 1 {
|
||||
VoiceItemState.smallView[VoiceItemState.id(chat, chatItem)] = VoiceItemState(audioPlayer: audioPlayer, playbackState: playbackState, playbackTime: playbackTime)
|
||||
} else {
|
||||
VoiceItemState.chatView[VoiceItemState.id(chat, chatItem)] = VoiceItemState(audioPlayer: audioPlayer, playbackState: playbackState, playbackTime: playbackTime)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,33 +394,96 @@ struct VoiceMessagePlayer: View {
|
||||
Image(systemName: image)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: size, height: size)
|
||||
.frame(width: size * sizeMultiplier, height: size * sizeMultiplier)
|
||||
.foregroundColor(Color(uiColor: .tertiaryLabel))
|
||||
.frame(width: 56, height: 56)
|
||||
.frame(width: 56 * sizeMultiplier, height: 56 * sizeMultiplier)
|
||||
.background(showBackground ? chatItemFrameColor(chatItem, theme) : .clear)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
|
||||
private func loadingIcon() -> some View {
|
||||
ProgressView()
|
||||
.frame(width: 30, height: 30)
|
||||
.frame(width: 56, height: 56)
|
||||
.frame(width: 30 * sizeMultiplier, height: 30 * sizeMultiplier)
|
||||
.frame(width: 56 * sizeMultiplier, height: 56 * sizeMultiplier)
|
||||
.background(showBackground ? chatItemFrameColor(chatItem, theme) : .clear)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
|
||||
private func startPlayback(_ recordingSource: CryptoFile) {
|
||||
chatModel.stopPreviousRecPlay = getAppFilePath(recordingSource.filePath)
|
||||
let audioPath = getAppFilePath(recordingSource.filePath)
|
||||
let chatId = chatModel.chatId
|
||||
let userId = chatModel.currentUser?.userId
|
||||
chatModel.stopPreviousRecPlay = audioPath
|
||||
audioPlayer = AudioPlayer(
|
||||
onTimer: { playbackTime = $0 },
|
||||
onTimer: {
|
||||
playbackTime = $0
|
||||
notifyStateChange()
|
||||
// Manual check here is needed because when this view is not visible, SwiftUI don't react on stopPreviousRecPlay, chatId and current user changes and audio keeps playing when it should stop
|
||||
if chatModel.stopPreviousRecPlay != audioPath || chatModel.chatId != chatId || chatModel.currentUser?.userId != userId {
|
||||
stopPlayback()
|
||||
}
|
||||
},
|
||||
onFinishPlayback: {
|
||||
playbackState = .noPlayback
|
||||
playbackTime = TimeInterval(0)
|
||||
notifyStateChange()
|
||||
}
|
||||
)
|
||||
audioPlayer?.start(fileSource: recordingSource, at: playbackTime)
|
||||
playbackState = .playing
|
||||
notifyStateChange()
|
||||
}
|
||||
|
||||
private func stopPlayback() {
|
||||
audioPlayer?.stop()
|
||||
playbackState = .noPlayback
|
||||
playbackTime = TimeInterval(0)
|
||||
notifyStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
func voiceMessageSizeBasedOnSquareSize(_ squareSize: CGFloat) -> CGFloat {
|
||||
let squareToCircleRatio = 0.935
|
||||
return squareSize + squareSize * (1 - squareToCircleRatio)
|
||||
}
|
||||
|
||||
class VoiceItemState {
|
||||
var audioPlayer: AudioPlayer?
|
||||
var playbackState: VoiceMessagePlaybackState
|
||||
var playbackTime: TimeInterval?
|
||||
|
||||
init(audioPlayer: AudioPlayer? = nil, playbackState: VoiceMessagePlaybackState, playbackTime: TimeInterval? = nil) {
|
||||
self.audioPlayer = audioPlayer
|
||||
self.playbackState = playbackState
|
||||
self.playbackTime = playbackTime
|
||||
}
|
||||
|
||||
static func id(_ chat: Chat, _ chatItem: ChatItem) -> String {
|
||||
"\(chat.id) \(chatItem.id)"
|
||||
}
|
||||
|
||||
static func id(_ chatInfo: ChatInfo, _ chatItem: ChatItem) -> String {
|
||||
"\(chatInfo.id) \(chatItem.id)"
|
||||
}
|
||||
|
||||
static func stopVoiceInSmallView(_ chatInfo: ChatInfo, _ chatItem: ChatItem) {
|
||||
let id = id(chatInfo, chatItem)
|
||||
if let item = smallView[id] {
|
||||
item.audioPlayer?.stop()
|
||||
ChatModel.shared.stopPreviousRecPlay = nil
|
||||
}
|
||||
}
|
||||
|
||||
static func stopVoiceInChatView(_ chatInfo: ChatInfo, _ chatItem: ChatItem) {
|
||||
let id = id(chatInfo, chatItem)
|
||||
if let item = chatView[id] {
|
||||
item.audioPlayer?.stop()
|
||||
ChatModel.shared.stopPreviousRecPlay = nil
|
||||
}
|
||||
}
|
||||
|
||||
static var smallView: [String: VoiceItemState] = [:]
|
||||
static var chatView: [String: VoiceItemState] = [:]
|
||||
}
|
||||
|
||||
struct CIVoiceView_Previews: PreviewProvider {
|
||||
@@ -339,15 +508,12 @@ struct CIVoiceView_Previews: PreviewProvider {
|
||||
chatItem: ChatItem.getVoiceMsgContentSample(),
|
||||
recordingFile: CIFile.getSample(fileName: "voice.m4a", fileSize: 65536, fileStatus: .rcvComplete),
|
||||
duration: 30,
|
||||
audioPlayer: .constant(nil),
|
||||
playbackState: .constant(.playing),
|
||||
playbackTime: .constant(TimeInterval(20)),
|
||||
allowMenu: Binding.constant(true)
|
||||
)
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: sentVoiceMessage, revealed: Binding.constant(false), allowMenu: .constant(true), playbackState: .constant(.noPlayback), playbackTime: .constant(nil))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(), revealed: Binding.constant(false), allowMenu: .constant(true), playbackState: .constant(.noPlayback), playbackTime: .constant(nil))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(fileStatus: .rcvTransfer(rcvProgress: 7, rcvTotal: 10)), revealed: Binding.constant(false), allowMenu: .constant(true), playbackState: .constant(.noPlayback), playbackTime: .constant(nil))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: voiceMessageWtFile, revealed: Binding.constant(false), allowMenu: .constant(true), playbackState: .constant(.noPlayback), playbackTime: .constant(nil))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: sentVoiceMessage, revealed: Binding.constant(false), allowMenu: .constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(), revealed: Binding.constant(false), allowMenu: .constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(fileStatus: .rcvTransfer(rcvProgress: 7, rcvTotal: 10)), revealed: Binding.constant(false), allowMenu: .constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: voiceMessageWtFile, revealed: Binding.constant(false), allowMenu: .constant(true))
|
||||
}
|
||||
.previewLayout(.fixed(width: 360, height: 360))
|
||||
}
|
||||
|
||||
@@ -13,21 +13,23 @@ import SimpleXChat
|
||||
|
||||
struct FramedCIVoiceView: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@ObservedObject var chat: Chat
|
||||
var chatItem: ChatItem
|
||||
let recordingFile: CIFile?
|
||||
let duration: Int
|
||||
|
||||
|
||||
@State var audioPlayer: AudioPlayer? = nil
|
||||
@State var playbackState: VoiceMessagePlaybackState = .noPlayback
|
||||
@State var playbackTime: TimeInterval? = nil
|
||||
|
||||
@Binding var allowMenu: Bool
|
||||
|
||||
@Binding var audioPlayer: AudioPlayer?
|
||||
@Binding var playbackState: VoiceMessagePlaybackState
|
||||
@Binding var playbackTime: TimeInterval?
|
||||
|
||||
|
||||
@State private var seek: (TimeInterval) -> Void = { _ in }
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
VoiceMessagePlayer(
|
||||
chat: chat,
|
||||
chatItem: chatItem,
|
||||
recordingFile: recordingFile,
|
||||
recordingTime: TimeInterval(duration),
|
||||
@@ -36,7 +38,8 @@ struct FramedCIVoiceView: View {
|
||||
audioPlayer: $audioPlayer,
|
||||
playbackState: $playbackState,
|
||||
playbackTime: $playbackTime,
|
||||
allowMenu: $allowMenu
|
||||
allowMenu: $allowMenu,
|
||||
sizeMultiplier: 1
|
||||
)
|
||||
VoiceMessagePlayerTime(
|
||||
recordingTime: TimeInterval(duration),
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -22,7 +22,7 @@ struct ChatItemForwardingView: View {
|
||||
@FocusState private var searchFocused
|
||||
@State private var alert: SomeAlert?
|
||||
@State private var hasSimplexLink_: Bool?
|
||||
private let chatsToForwardTo = filterChatsToForwardTo()
|
||||
private let chatsToForwardTo = filterChatsToForwardTo(chats: ChatModel.shared.chats)
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
@@ -67,22 +67,6 @@ struct ChatItemForwardingView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func foundChat(_ chat: Chat, _ searchStr: String) -> Bool {
|
||||
let cInfo = chat.chatInfo
|
||||
return switch cInfo {
|
||||
case let .direct(contact):
|
||||
viewNameContains(cInfo, searchStr) ||
|
||||
contact.profile.displayName.localizedLowercase.contains(searchStr) ||
|
||||
contact.fullName.localizedLowercase.contains(searchStr)
|
||||
default:
|
||||
viewNameContains(cInfo, searchStr)
|
||||
}
|
||||
|
||||
func viewNameContains(_ cInfo: ChatInfo, _ s: String) -> Bool {
|
||||
cInfo.chatViewName.localizedLowercase.contains(s)
|
||||
}
|
||||
}
|
||||
|
||||
private func prohibitedByPref(_ chat: Chat) -> Bool {
|
||||
// preference checks should match checks in compose view
|
||||
let simplexLinkProhibited = hasSimplexLink && !chat.groupFeatureEnabled(.simplexLinks)
|
||||
@@ -162,27 +146,6 @@ struct ChatItemForwardingView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func filterChatsToForwardTo() -> [Chat] {
|
||||
var filteredChats = ChatModel.shared.chats.filter { c in
|
||||
c.chatInfo.chatType != .local && canForwardToChat(c)
|
||||
}
|
||||
if let privateNotes = ChatModel.shared.chats.first(where: { $0.chatInfo.chatType == .local }) {
|
||||
filteredChats.insert(privateNotes, at: 0)
|
||||
}
|
||||
return filteredChats
|
||||
}
|
||||
|
||||
private func canForwardToChat(_ chat: Chat) -> Bool {
|
||||
switch chat.chatInfo {
|
||||
case let .direct(contact): contact.sendMsgEnabled && !contact.nextSendGrpInv
|
||||
case let .group(groupInfo): groupInfo.sendMsgEnabled
|
||||
case let .local(noteFolder): noteFolder.sendMsgEnabled
|
||||
case .contactRequest: false
|
||||
case .contactConnection: false
|
||||
case .invalidJSON: false
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ChatItemForwardingView(
|
||||
ci: ChatItem.getSample(1, .directSnd, .now, "hello"),
|
||||
@@ -190,3 +153,4 @@ private func canForwardToChat(_ chat: Chat) -> Bool {
|
||||
composeState: Binding.constant(ComposeState(message: "hello"))
|
||||
).environmentObject(CurrentColors.toAppTheme())
|
||||
}
|
||||
|
||||
|
||||
@@ -16,28 +16,20 @@ struct ChatItemView: View {
|
||||
var maxWidth: CGFloat = .infinity
|
||||
@Binding var revealed: Bool
|
||||
@Binding var allowMenu: Bool
|
||||
@Binding var audioPlayer: AudioPlayer?
|
||||
@Binding var playbackState: VoiceMessagePlaybackState
|
||||
@Binding var playbackTime: TimeInterval?
|
||||
|
||||
init(
|
||||
chat: Chat,
|
||||
chatItem: ChatItem,
|
||||
showMember: Bool = false,
|
||||
maxWidth: CGFloat = .infinity,
|
||||
revealed: Binding<Bool>,
|
||||
allowMenu: Binding<Bool> = .constant(false),
|
||||
audioPlayer: Binding<AudioPlayer?> = .constant(nil),
|
||||
playbackState: Binding<VoiceMessagePlaybackState> = .constant(.noPlayback),
|
||||
playbackTime: Binding<TimeInterval?> = .constant(nil)
|
||||
allowMenu: Binding<Bool> = .constant(false)
|
||||
) {
|
||||
self.chat = chat
|
||||
self.chatItem = chatItem
|
||||
self.maxWidth = maxWidth
|
||||
_revealed = revealed
|
||||
_allowMenu = allowMenu
|
||||
_audioPlayer = audioPlayer
|
||||
_playbackState = playbackState
|
||||
_playbackTime = playbackTime
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
@@ -48,7 +40,7 @@ struct ChatItemView: View {
|
||||
if let mc = ci.content.msgContent, mc.isText && isShortEmoji(ci.content.text) {
|
||||
EmojiItemView(chat: chat, chatItem: ci)
|
||||
} else if ci.content.text.isEmpty, case let .voice(_, duration) = ci.content.msgContent {
|
||||
CIVoiceView(chat: chat, chatItem: ci, recordingFile: ci.file, duration: duration, audioPlayer: $audioPlayer, playbackState: $playbackState, playbackTime: $playbackTime, allowMenu: $allowMenu)
|
||||
CIVoiceView(chat: chat, chatItem: ci, recordingFile: ci.file, duration: duration, allowMenu: $allowMenu)
|
||||
} else if ci.content.msgContent == nil {
|
||||
ChatItemContentView(chat: chat, chatItem: chatItem, revealed: $revealed, msgContentView: { Text(ci.text) }) // msgContent is unreachable branch in this case
|
||||
} else {
|
||||
@@ -84,10 +76,7 @@ struct ChatItemView: View {
|
||||
maxWidth: maxWidth,
|
||||
imgWidth: adjustedMaxWidth,
|
||||
videoWidth: adjustedMaxWidth,
|
||||
allowMenu: $allowMenu,
|
||||
audioPlayer: $audioPlayer,
|
||||
playbackState: $playbackState,
|
||||
playbackTime: $playbackTime
|
||||
allowMenu: $allowMenu
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ struct ChatView: View {
|
||||
}
|
||||
.onChange(of: chatModel.chatId) { cId in
|
||||
showChatInfoSheet = false
|
||||
stopAudioPlayer()
|
||||
if let cId {
|
||||
if let c = chatModel.getChat(cId) {
|
||||
chat = c
|
||||
@@ -117,6 +118,7 @@ struct ChatView: View {
|
||||
.environmentObject(scrollModel)
|
||||
.onDisappear {
|
||||
VideoPlayerView.players.removeAll()
|
||||
stopAudioPlayer()
|
||||
if chatModel.chatId == cInfo.id && !presentationMode.wrappedValue.isPresented {
|
||||
chatModel.chatId = nil
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
|
||||
@@ -378,7 +380,7 @@ struct ChatView: View {
|
||||
|
||||
@ViewBuilder private func connectingText() -> some View {
|
||||
if case let .direct(contact) = chat.chatInfo,
|
||||
!contact.ready,
|
||||
!contact.sndReady,
|
||||
contact.active,
|
||||
!contact.nextSendGrpInv {
|
||||
Text("connecting…")
|
||||
@@ -589,6 +591,11 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
|
||||
func stopAudioPlayer() {
|
||||
VoiceItemState.chatView.values.forEach { $0.audioPlayer?.stop() }
|
||||
VoiceItemState.chatView = [:]
|
||||
}
|
||||
|
||||
@ViewBuilder private func chatItemView(_ ci: ChatItem, _ maxWidth: CGFloat) -> some View {
|
||||
ChatItemWithMenu(
|
||||
chat: chat,
|
||||
@@ -620,10 +627,6 @@ struct ChatView: View {
|
||||
|
||||
@State private var allowMenu: Bool = true
|
||||
|
||||
@State private var audioPlayer: AudioPlayer?
|
||||
@State private var playbackState: VoiceMessagePlaybackState = .noPlayback
|
||||
@State private var playbackTime: TimeInterval?
|
||||
|
||||
var revealed: Bool { chatItem == revealedChatItem }
|
||||
|
||||
var body: some View {
|
||||
@@ -643,23 +646,38 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
markRead(
|
||||
chatItems: range.flatMap { m.reversedChatItems[$0] }
|
||||
?? [chatItem]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private func markRead(chatItems: Array<ChatItem>.SubSequence) {
|
||||
let unreadItems = chatItems.filter { $0.isRcvNew }
|
||||
if unreadItems.isEmpty { return }
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) {
|
||||
if m.chatId == chat.chatInfo.id {
|
||||
Task {
|
||||
for unreadItem in unreadItems {
|
||||
await apiMarkChatItemRead(chat.chatInfo, unreadItem)
|
||||
if let range {
|
||||
if let items = unreadItems(range) {
|
||||
waitToMarkRead {
|
||||
for ci in items {
|
||||
await apiMarkChatItemRead(chat.chatInfo, ci)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if chatItem.isRcvNew {
|
||||
waitToMarkRead {
|
||||
await apiMarkChatItemRead(chat.chatInfo, chatItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func unreadItems(_ range: ClosedRange<Int>) -> [ChatItem]? {
|
||||
let items = range.compactMap { i in
|
||||
if i >= 0 && i < m.reversedChatItems.count {
|
||||
let ci = m.reversedChatItems[i]
|
||||
return if ci.isRcvNew { ci } else { nil }
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return if items.isEmpty { nil } else { items }
|
||||
}
|
||||
|
||||
private func waitToMarkRead(_ op: @Sendable @escaping () async -> Void) {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) {
|
||||
if m.chatId == chat.chatInfo.id {
|
||||
Task(operation: op)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -742,10 +760,7 @@ struct ChatView: View {
|
||||
chatItem: ci,
|
||||
maxWidth: maxWidth,
|
||||
revealed: .constant(revealed),
|
||||
allowMenu: $allowMenu,
|
||||
audioPlayer: $audioPlayer,
|
||||
playbackState: $playbackState,
|
||||
playbackTime: $playbackTime
|
||||
allowMenu: $allowMenu
|
||||
)
|
||||
.modifier(ChatItemClipped(ci))
|
||||
.contextMenu { menu(ci, range, live: composeState.liveMessage != nil) }
|
||||
@@ -772,14 +787,6 @@ struct ChatView: View {
|
||||
}
|
||||
.frame(maxWidth: maxWidth, maxHeight: .infinity, alignment: alignment)
|
||||
.frame(minWidth: 0, maxWidth: .infinity, alignment: alignment)
|
||||
.onDisappear {
|
||||
if ci.content.msgContent?.isVoice == true {
|
||||
allowMenu = true
|
||||
audioPlayer?.stop()
|
||||
playbackState = .noPlayback
|
||||
playbackTime = TimeInterval(0)
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showChatItemInfoSheet, onDismiss: {
|
||||
chatItemInfo = nil
|
||||
}) {
|
||||
|
||||
@@ -10,35 +10,6 @@ import SwiftUI
|
||||
import LinkPresentation
|
||||
import SimpleXChat
|
||||
|
||||
func getLinkPreview(url: URL, cb: @escaping (LinkPreview?) -> Void) {
|
||||
logger.debug("getLinkMetadata: fetching URL preview")
|
||||
LPMetadataProvider().startFetchingMetadata(for: url){ metadata, error in
|
||||
if let e = error {
|
||||
logger.error("Error retrieving link metadata: \(e.localizedDescription)")
|
||||
}
|
||||
if let metadata = metadata,
|
||||
let imageProvider = metadata.imageProvider,
|
||||
imageProvider.canLoadObject(ofClass: UIImage.self) {
|
||||
imageProvider.loadObject(ofClass: UIImage.self){ object, error in
|
||||
var linkPreview: LinkPreview? = nil
|
||||
if let error = error {
|
||||
logger.error("Couldn't load image preview from link metadata with error: \(error.localizedDescription)")
|
||||
} else {
|
||||
if let image = object as? UIImage,
|
||||
let resized = resizeImageToStrSize(image, maxDataSize: 14000),
|
||||
let title = metadata.title,
|
||||
let uri = metadata.originalURL {
|
||||
linkPreview = LinkPreview(uri: uri, title: title, image: resized)
|
||||
}
|
||||
}
|
||||
cb(linkPreview)
|
||||
}
|
||||
} else {
|
||||
cb(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ComposeLinkView: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
let linkPreview: LinkPreview?
|
||||
|
||||
@@ -67,7 +67,6 @@ struct SendMessageView: View {
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
}
|
||||
|
||||
if progressByTimeout {
|
||||
ProgressView()
|
||||
.scaleEffect(1.4)
|
||||
@@ -87,7 +86,7 @@ struct SendMessageView: View {
|
||||
.padding(.vertical, 1)
|
||||
.background(theme.colors.background)
|
||||
.clipShape(composeShape)
|
||||
.overlay(composeShape.strokeBorder(.secondary, lineWidth: 0.3, antialiased: true))
|
||||
.overlay(composeShape.strokeBorder(.secondary, lineWidth: 0.5).opacity(0.7))
|
||||
}
|
||||
.onChange(of: composeState.message, perform: { text in updateFont(text) })
|
||||
.onChange(of: composeState.inProgress) { inProgress in
|
||||
|
||||
@@ -35,7 +35,7 @@ struct AddGroupMembersViewCommon: View {
|
||||
|
||||
private enum AddGroupMembersAlert: Identifiable {
|
||||
case prohibitedToInviteIncognito
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey = "")
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey?)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@@ -122,7 +122,7 @@ struct AddGroupMembersViewCommon: View {
|
||||
message: Text("You're trying to invite contact with whom you've shared an incognito profile to the group in which you're using your main profile")
|
||||
)
|
||||
case let .error(title, error):
|
||||
return Alert(title: Text(title), message: Text(error))
|
||||
return mkAlert(title: title, message: error)
|
||||
}
|
||||
}
|
||||
.onChange(of: selectedContacts) { _ in
|
||||
|
||||
@@ -40,7 +40,7 @@ struct GroupChatInfoView: View {
|
||||
case blockForAllAlert(mem: GroupMember)
|
||||
case unblockForAllAlert(mem: GroupMember)
|
||||
case removeMemberAlert(mem: GroupMember)
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey)
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey?)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@@ -158,7 +158,7 @@ struct GroupChatInfoView: View {
|
||||
case let .blockForAllAlert(mem): return blockForAllAlert(groupInfo, mem)
|
||||
case let .unblockForAllAlert(mem): return unblockForAllAlert(groupInfo, mem)
|
||||
case let .removeMemberAlert(mem): return removeMemberAlert(mem)
|
||||
case let .error(title, error): return Alert(title: Text(title), message: Text(error))
|
||||
case let .error(title, error): return mkAlert(title: title, message: error)
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
|
||||
@@ -22,7 +22,7 @@ struct GroupLinkView: View {
|
||||
|
||||
private enum GroupLinkAlert: Identifiable {
|
||||
case deleteLink
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey = "")
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey?)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@@ -113,7 +113,7 @@ struct GroupLinkView: View {
|
||||
}, secondaryButton: .cancel()
|
||||
)
|
||||
case let .error(title, error):
|
||||
return Alert(title: Text(title), message: Text(error))
|
||||
return mkAlert(title: title, message: error)
|
||||
}
|
||||
}
|
||||
.onChange(of: groupLinkMemberRole) { _ in
|
||||
|
||||
@@ -37,7 +37,7 @@ struct GroupMemberInfoView: View {
|
||||
case syncConnectionForceAlert
|
||||
case planAndConnectAlert(alert: PlanAndConnectAlert)
|
||||
case queueInfo(info: String)
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey)
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey?)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@@ -237,7 +237,7 @@ struct GroupMemberInfoView: View {
|
||||
case .syncConnectionForceAlert: return syncConnectionForceAlert({ syncMemberConnection(force: true) })
|
||||
case let .planAndConnectAlert(alert): return planAndConnectAlert(alert, dismiss: true)
|
||||
case let .queueInfo(info): return queueInfoAlert(info)
|
||||
case let .error(title, error): return Alert(title: Text(title), message: Text(error))
|
||||
case let .error(title, error): return mkAlert(title: title, message: error)
|
||||
}
|
||||
}
|
||||
.actionSheet(item: $sheet) { s in planAndConnectActionSheet(s, dismiss: true) }
|
||||
|
||||
@@ -129,8 +129,9 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
from: nil,
|
||||
for: nil
|
||||
)
|
||||
NotificationCenter.default.post(name: .chatViewWillBeginScrolling, object: nil)
|
||||
}
|
||||
|
||||
|
||||
/// Scrolls up
|
||||
func scrollToNextPage() {
|
||||
tableView.setContentOffset(
|
||||
|
||||
@@ -9,25 +9,34 @@
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
private let rowHeights: [DynamicTypeSize: CGFloat] = [
|
||||
.xSmall: 68,
|
||||
.small: 72,
|
||||
.medium: 76,
|
||||
.large: 80,
|
||||
.xLarge: 88,
|
||||
.xxLarge: 94,
|
||||
.xxxLarge: 104,
|
||||
.accessibility1: 90,
|
||||
.accessibility2: 100,
|
||||
.accessibility3: 120,
|
||||
.accessibility4: 130,
|
||||
.accessibility5: 140
|
||||
let dynamicSizes: [
|
||||
DynamicTypeSize: (
|
||||
rowHeight: CGFloat,
|
||||
profileImageSize: CGFloat,
|
||||
mediaSize: CGFloat,
|
||||
chatInfoSize: CGFloat,
|
||||
unreadCorner: CGFloat,
|
||||
unreadPadding: CGFloat
|
||||
)
|
||||
] = [
|
||||
.xSmall: (68, 55, 33, 18, 9, 3),
|
||||
.small: (72, 57, 34, 18, 9, 3),
|
||||
.medium: (76, 60, 36, 18, 10, 4),
|
||||
.large: (80, 63, 38, 20, 10, 4),
|
||||
.xLarge: (88, 67, 41, 20, 10, 4),
|
||||
.xxLarge: (94, 71, 44, 22, 11, 4),
|
||||
.xxxLarge: (104, 75, 48, 24, 12, 5),
|
||||
.accessibility1: (104, 75, 48, 24, 12, 5),
|
||||
.accessibility2: (114, 75, 48, 24, 12, 5),
|
||||
.accessibility3: (124, 75, 48, 24, 12, 5),
|
||||
.accessibility4: (134, 75, 48, 24, 12, 5),
|
||||
.accessibility5: (144, 75, 48, 24, 12, 5)
|
||||
]
|
||||
|
||||
struct ChatListNavLink: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.dynamicTypeSize) private var dynamicTypeSize
|
||||
@Environment(\.dynamicTypeSize) private var userFont: DynamicTypeSize
|
||||
@ObservedObject var chat: Chat
|
||||
@State private var showContactRequestDialog = false
|
||||
@State private var showJoinGroupDialog = false
|
||||
@@ -38,6 +47,8 @@ struct ChatListNavLink: View {
|
||||
@State private var inProgress = false
|
||||
@State private var progressByTimeout = false
|
||||
|
||||
var dynamicRowHeight: CGFloat { dynamicSizes[userFont]?.rowHeight ?? 80 }
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
switch chat.chatInfo {
|
||||
@@ -70,7 +81,7 @@ struct ChatListNavLink: View {
|
||||
Group {
|
||||
if contact.activeConn == nil && contact.profile.contactLink != nil {
|
||||
ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false))
|
||||
.frame(height: rowHeights[dynamicTypeSize])
|
||||
.frame(height: dynamicRowHeight)
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
||||
Button {
|
||||
showDeleteContactActionSheet = true
|
||||
@@ -100,7 +111,7 @@ struct ChatListNavLink: View {
|
||||
clearChatButton()
|
||||
}
|
||||
Button {
|
||||
if contact.ready || !contact.active {
|
||||
if contact.sndReady || !contact.active {
|
||||
showDeleteContactActionSheet = true
|
||||
} else {
|
||||
AlertManager.shared.showAlert(deletePendingContactAlert(chat, contact))
|
||||
@@ -110,11 +121,11 @@ struct ChatListNavLink: View {
|
||||
}
|
||||
.tint(.red)
|
||||
}
|
||||
.frame(height: rowHeights[dynamicTypeSize])
|
||||
.frame(height: dynamicRowHeight)
|
||||
}
|
||||
}
|
||||
.actionSheet(isPresented: $showDeleteContactActionSheet) {
|
||||
if contact.ready && contact.active {
|
||||
if contact.sndReady && contact.active {
|
||||
return ActionSheet(
|
||||
title: Text("Delete contact?\nThis cannot be undone!"),
|
||||
buttons: [
|
||||
@@ -139,7 +150,7 @@ struct ChatListNavLink: View {
|
||||
switch (groupInfo.membership.memberStatus) {
|
||||
case .memInvited:
|
||||
ChatPreviewView(chat: chat, progressByTimeout: $progressByTimeout)
|
||||
.frame(height: rowHeights[dynamicTypeSize])
|
||||
.frame(height: dynamicRowHeight)
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
||||
joinGroupButton()
|
||||
if groupInfo.canDelete {
|
||||
@@ -159,7 +170,7 @@ struct ChatListNavLink: View {
|
||||
.disabled(inProgress)
|
||||
case .memAccepted:
|
||||
ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false))
|
||||
.frame(height: rowHeights[dynamicTypeSize])
|
||||
.frame(height: dynamicRowHeight)
|
||||
.onTapGesture {
|
||||
AlertManager.shared.showAlert(groupInvitationAcceptedAlert())
|
||||
}
|
||||
@@ -178,7 +189,7 @@ struct ChatListNavLink: View {
|
||||
label: { ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false)) },
|
||||
disabled: !groupInfo.ready
|
||||
)
|
||||
.frame(height: rowHeights[dynamicTypeSize])
|
||||
.frame(height: dynamicRowHeight)
|
||||
.swipeActions(edge: .leading, allowsFullSwipe: true) {
|
||||
markReadButton()
|
||||
toggleFavoriteButton()
|
||||
@@ -205,7 +216,7 @@ struct ChatListNavLink: View {
|
||||
label: { ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false)) },
|
||||
disabled: !noteFolder.ready
|
||||
)
|
||||
.frame(height: rowHeights[dynamicTypeSize])
|
||||
.frame(height: dynamicRowHeight)
|
||||
.swipeActions(edge: .leading, allowsFullSwipe: true) {
|
||||
markReadButton()
|
||||
}
|
||||
@@ -321,7 +332,7 @@ struct ChatListNavLink: View {
|
||||
}
|
||||
.tint(.red)
|
||||
}
|
||||
.frame(height: rowHeights[dynamicTypeSize])
|
||||
.frame(height: dynamicRowHeight)
|
||||
.onTapGesture { showContactRequestDialog = true }
|
||||
.confirmationDialog("Accept connection request?", isPresented: $showContactRequestDialog, titleVisibility: .visible) {
|
||||
Button("Accept") { Task { await acceptContactRequest(incognito: false, contactRequest: contactRequest) } }
|
||||
@@ -349,7 +360,7 @@ struct ChatListNavLink: View {
|
||||
}
|
||||
.tint(theme.colors.primary)
|
||||
}
|
||||
.frame(height: rowHeights[dynamicTypeSize])
|
||||
.frame(height: dynamicRowHeight)
|
||||
.appSheet(isPresented: $showContactConnectionInfo) {
|
||||
Group {
|
||||
if case let .contactConnection(contactConnection) = chat.chatInfo {
|
||||
@@ -469,7 +480,7 @@ struct ChatListNavLink: View {
|
||||
Text("invalid chat data")
|
||||
.foregroundColor(.red)
|
||||
.padding(4)
|
||||
.frame(height: rowHeights[dynamicTypeSize])
|
||||
.frame(height: dynamicRowHeight)
|
||||
.onTapGesture { showInvalidJSON = true }
|
||||
.appSheet(isPresented: $showInvalidJSON) {
|
||||
invalidJSONView(json)
|
||||
|
||||
@@ -21,6 +21,7 @@ struct ChatListView: View {
|
||||
@State private var newChatMenuOption: NewChatMenuOption? = nil
|
||||
@State private var userPickerVisible = false
|
||||
@State private var showConnectDesktop = false
|
||||
|
||||
@AppStorage(DEFAULT_SHOW_UNREAD_AND_FAVORITES) private var showUnreadAndFavorites = false
|
||||
|
||||
var body: some View {
|
||||
@@ -162,6 +163,10 @@ struct ChatListView: View {
|
||||
chatModel.chatToTop = nil
|
||||
chatModel.popChat(chatId)
|
||||
}
|
||||
stopAudioPlayer()
|
||||
}
|
||||
.onChange(of: chatModel.currentUser?.userId) { _ in
|
||||
stopAudioPlayer()
|
||||
}
|
||||
if cs.isEmpty && !chatModel.chats.isEmpty {
|
||||
Text("No filtered chats").foregroundColor(theme.colors.secondary)
|
||||
@@ -217,6 +222,11 @@ struct ChatListView: View {
|
||||
}
|
||||
}
|
||||
|
||||
func stopAudioPlayer() {
|
||||
VoiceItemState.smallView.values.forEach { $0.audioPlayer?.stop() }
|
||||
VoiceItemState.smallView = [:]
|
||||
}
|
||||
|
||||
private func filteredChats() -> [Chat] {
|
||||
if let linkChatId = searchChatFilteredBySimplexLink {
|
||||
return chatModel.chats.filter { $0.id == linkChatId }
|
||||
@@ -266,9 +276,9 @@ struct ChatListView: View {
|
||||
}
|
||||
|
||||
struct SubsStatusIndicator: View {
|
||||
@State private var serversSummary: PresentedServersSummary?
|
||||
@State private var subs: SMPServerSubs = SMPServerSubs.newSMPServerSubs
|
||||
@State private var hasSess: Bool = false
|
||||
@State private var timer: Timer? = nil
|
||||
@State private var timerCounter = 0
|
||||
@State private var showServersSummary = false
|
||||
|
||||
@AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false
|
||||
@@ -277,12 +287,10 @@ struct SubsStatusIndicator: View {
|
||||
Button {
|
||||
showServersSummary = true
|
||||
} label: {
|
||||
let subs = serversSummary?.allUsersSMP.smpTotals.subs ?? SMPServerSubs.newSMPServerSubs
|
||||
let sess = serversSummary?.allUsersSMP.smpTotals.sessions ?? ServerSessions.newServerSessions
|
||||
HStack(spacing: 4) {
|
||||
SubscriptionStatusIndicatorView(subs: subs, sess: sess)
|
||||
SubscriptionStatusIndicatorView(subs: subs, hasSess: hasSess)
|
||||
if showSubscriptionPercentage {
|
||||
SubscriptionStatusPercentageView(subs: subs, sess: sess)
|
||||
SubscriptionStatusPercentageView(subs: subs, hasSess: hasSess)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,14 +301,14 @@ struct SubsStatusIndicator: View {
|
||||
stopTimer()
|
||||
}
|
||||
.sheet(isPresented: $showServersSummary) {
|
||||
ServersSummaryView(serversSummary: $serversSummary)
|
||||
ServersSummaryView()
|
||||
}
|
||||
}
|
||||
|
||||
private func startTimer() {
|
||||
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
|
||||
if AppChatState.shared.value == .active {
|
||||
getServersSummary()
|
||||
getSubsTotal()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,11 +318,11 @@ struct SubsStatusIndicator: View {
|
||||
timer = nil
|
||||
}
|
||||
|
||||
private func getServersSummary() {
|
||||
private func getSubsTotal() {
|
||||
do {
|
||||
serversSummary = try getAgentServersSummary()
|
||||
(subs, hasSess) = try getAgentSubsTotal()
|
||||
} catch let error {
|
||||
logger.error("getAgentServersSummary error: \(responseError(error))")
|
||||
logger.error("getSubsTotal error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,18 +12,24 @@ import SimpleXChat
|
||||
struct ChatPreviewView: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.dynamicTypeSize) private var userFont: DynamicTypeSize
|
||||
@ObservedObject var chat: Chat
|
||||
@Binding var progressByTimeout: Bool
|
||||
@State var deleting: Bool = false
|
||||
var darkGreen = Color(red: 0, green: 0.5, blue: 0)
|
||||
@State private var activeContentPreview: ActiveContentPreview? = nil
|
||||
@State private var showFullscreenGallery: Bool = false
|
||||
|
||||
@AppStorage(DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS) private var showChatPreviews = true
|
||||
|
||||
var dynamicMediaSize: CGFloat { dynamicSizes[userFont]?.mediaSize ?? 36 }
|
||||
var dynamicChatInfoSize: CGFloat { dynamicSizes[userFont]?.chatInfoSize ?? 18 }
|
||||
|
||||
var body: some View {
|
||||
let cItem = chat.chatItems.last
|
||||
return HStack(spacing: 8) {
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
ChatInfoImage(chat: chat, size: 63)
|
||||
ChatInfoImage(chat: chat, size: dynamicSizes[userFont]?.profileImageSize ?? 63)
|
||||
chatPreviewImageOverlayIcon()
|
||||
.padding([.bottom, .trailing], 1)
|
||||
}
|
||||
@@ -43,11 +49,38 @@ struct ChatPreviewView: View {
|
||||
.padding(.horizontal, 8)
|
||||
|
||||
ZStack(alignment: .topTrailing) {
|
||||
chatMessagePreview(cItem)
|
||||
let chat = activeContentPreview?.chat ?? chat
|
||||
let ci = activeContentPreview?.ci ?? chat.chatItems.last
|
||||
let mc = ci?.content.msgContent
|
||||
HStack(alignment: .top) {
|
||||
let deleted = ci?.isDeletedContent == true || ci?.meta.itemDeleted != nil
|
||||
let showContentPreview = (showChatPreviews && chatModel.draftChatId != chat.id && !deleted) || activeContentPreview != nil
|
||||
if let ci, showContentPreview {
|
||||
chatItemContentPreview(chat, ci)
|
||||
}
|
||||
let mcIsVoice = switch mc { case .voice: true; default: false }
|
||||
if !mcIsVoice || !showContentPreview || mc?.text != "" || chatModel.draftChatId == chat.id {
|
||||
let hasFilePreview = if case .file = mc { true } else { false }
|
||||
chatMessagePreview(cItem, hasFilePreview)
|
||||
} else {
|
||||
Spacer()
|
||||
chatInfoIcon(chat).frame(minWidth: 37, alignment: .trailing)
|
||||
}
|
||||
}
|
||||
.onChange(of: chatModel.stopPreviousRecPlay?.path) { _ in
|
||||
checkActiveContentPreview(chat, ci, mc)
|
||||
}
|
||||
.onChange(of: activeContentPreview) { _ in
|
||||
checkActiveContentPreview(chat, ci, mc)
|
||||
}
|
||||
.onChange(of: showFullscreenGallery) { _ in
|
||||
checkActiveContentPreview(chat, ci, mc)
|
||||
}
|
||||
chatStatusImage()
|
||||
.padding(.top, 26)
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.trailing, 8)
|
||||
|
||||
Spacer()
|
||||
@@ -57,6 +90,33 @@ struct ChatPreviewView: View {
|
||||
.padding(.bottom, -8)
|
||||
.onChange(of: chatModel.deletedChats.contains(chat.chatInfo.id)) { contains in
|
||||
deleting = contains
|
||||
// Stop voice when deleting the chat
|
||||
if contains, let ci = activeContentPreview?.ci {
|
||||
VoiceItemState.stopVoiceInSmallView(chat.chatInfo, ci)
|
||||
}
|
||||
}
|
||||
|
||||
func checkActiveContentPreview(_ chat: Chat, _ ci: ChatItem?, _ mc: MsgContent?) {
|
||||
let playing = chatModel.stopPreviousRecPlay
|
||||
if case .voice = activeContentPreview?.mc, playing == nil {
|
||||
activeContentPreview = nil
|
||||
} else if activeContentPreview == nil {
|
||||
if case .image = mc, let ci, let mc, showFullscreenGallery {
|
||||
activeContentPreview = ActiveContentPreview(chat: chat, ci: ci, mc: mc)
|
||||
}
|
||||
if case .video = mc, let ci, let mc, showFullscreenGallery {
|
||||
activeContentPreview = ActiveContentPreview(chat: chat, ci: ci, mc: mc)
|
||||
}
|
||||
if case .voice = mc, let ci, let mc, let fileSource = ci.file?.fileSource, playing?.path.hasSuffix(fileSource.filePath) == true {
|
||||
activeContentPreview = ActiveContentPreview(chat: chat, ci: ci, mc: mc)
|
||||
}
|
||||
} else if case .voice = activeContentPreview?.mc {
|
||||
if let playing, let fileSource = ci?.file?.fileSource, !playing.path.hasSuffix(fileSource.filePath) {
|
||||
activeContentPreview = nil
|
||||
}
|
||||
} else if !showFullscreenGallery {
|
||||
activeContentPreview = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,39 +173,50 @@ struct ChatPreviewView: View {
|
||||
.kerning(-2)
|
||||
}
|
||||
|
||||
private func chatPreviewLayout(_ text: Text, draft: Bool = false) -> some View {
|
||||
private func chatPreviewLayout(_ text: Text?, draft: Bool = false, _ hasFilePreview: Bool = false) -> some View {
|
||||
ZStack(alignment: .topTrailing) {
|
||||
let t = text
|
||||
.lineLimit(2)
|
||||
.lineLimit(userFont <= .xxxLarge ? 2 : 1)
|
||||
.multilineTextAlignment(.leading)
|
||||
.frame(maxWidth: .infinity, alignment: .topLeading)
|
||||
.padding(.leading, 8)
|
||||
.padding(.trailing, 36)
|
||||
.padding(.leading, hasFilePreview ? 0 : 8)
|
||||
.padding(.trailing, hasFilePreview ? 38 : 36)
|
||||
.offset(x: hasFilePreview ? -2 : 0)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
if !showChatPreviews && !draft {
|
||||
t.privacySensitive(true).redacted(reason: .privacy)
|
||||
} else {
|
||||
t
|
||||
}
|
||||
let s = chat.chatStats
|
||||
if s.unreadCount > 0 || s.unreadChat {
|
||||
unreadCountText(s.unreadCount)
|
||||
.font(.caption)
|
||||
.foregroundColor(.white)
|
||||
.padding(.horizontal, 4)
|
||||
.frame(minWidth: 18, minHeight: 18)
|
||||
.background(chat.chatInfo.ntfsEnabled || chat.chatInfo.chatType == .local ? theme.colors.primary : theme.colors.secondary)
|
||||
.cornerRadius(10)
|
||||
} else if !chat.chatInfo.ntfsEnabled && chat.chatInfo.chatType != .local {
|
||||
Image(systemName: "speaker.slash.fill")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
} else if chat.chatInfo.chatSettings?.favorite ?? false {
|
||||
Image(systemName: "star.fill")
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 18, height: 18)
|
||||
.padding(.trailing, 1)
|
||||
.foregroundColor(.secondary.opacity(0.65))
|
||||
}
|
||||
chatInfoIcon(chat).frame(minWidth: 37, alignment: .trailing)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func chatInfoIcon(_ chat: Chat) -> some View {
|
||||
let s = chat.chatStats
|
||||
if s.unreadCount > 0 || s.unreadChat {
|
||||
unreadCountText(s.unreadCount)
|
||||
.font(userFont <= .xxxLarge ? .caption : .caption2)
|
||||
.foregroundColor(.white)
|
||||
.padding(.horizontal, dynamicSizes[userFont]?.unreadPadding ?? 4)
|
||||
.frame(minWidth: dynamicChatInfoSize, minHeight: dynamicChatInfoSize)
|
||||
.background(chat.chatInfo.ntfsEnabled || chat.chatInfo.chatType == .local ? theme.colors.primary : theme.colors.secondary)
|
||||
.cornerRadius(dynamicSizes[userFont]?.unreadCorner ?? 10)
|
||||
} else if !chat.chatInfo.ntfsEnabled && chat.chatInfo.chatType != .local {
|
||||
Image(systemName: "speaker.slash.fill")
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: dynamicChatInfoSize, height: dynamicChatInfoSize)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
} else if chat.chatInfo.chatSettings?.favorite ?? false {
|
||||
Image(systemName: "star.fill")
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: dynamicChatInfoSize, height: dynamicChatInfoSize)
|
||||
.padding(.trailing, 1)
|
||||
.foregroundColor(theme.colors.secondary.opacity(0.65))
|
||||
} else {
|
||||
Color.clear.frame(width: 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +243,7 @@ struct ChatPreviewView: View {
|
||||
func chatItemPreview(_ cItem: ChatItem) -> Text {
|
||||
let itemText = cItem.meta.itemDeleted == nil ? cItem.text : markedDeletedText()
|
||||
let itemFormattedText = cItem.meta.itemDeleted == nil ? cItem.formattedText : nil
|
||||
return messageText(itemText, itemFormattedText, cItem.memberDisplayName, icon: attachment(), preview: true, showSecrets: false, secondaryColor: theme.colors.secondary)
|
||||
return messageText(itemText, itemFormattedText, cItem.memberDisplayName, icon: nil, preview: true, showSecrets: false, secondaryColor: theme.colors.secondary)
|
||||
|
||||
// same texts are in markedDeletedText in MarkedDeletedItemView, but it returns LocalizedStringKey;
|
||||
// can be refactored into a single function if functions calling these are changed to return same type
|
||||
@@ -196,18 +267,18 @@ struct ChatPreviewView: View {
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func chatMessagePreview(_ cItem: ChatItem?) -> some View {
|
||||
@ViewBuilder private func chatMessagePreview(_ cItem: ChatItem?, _ hasFilePreview: Bool = false) -> some View {
|
||||
if chatModel.draftChatId == chat.id, let draft = chatModel.draft {
|
||||
chatPreviewLayout(messageDraft(draft), draft: true)
|
||||
chatPreviewLayout(messageDraft(draft), draft: true, hasFilePreview)
|
||||
} else if let cItem = cItem {
|
||||
chatPreviewLayout(itemStatusMark(cItem) + chatItemPreview(cItem))
|
||||
chatPreviewLayout(itemStatusMark(cItem) + chatItemPreview(cItem), hasFilePreview)
|
||||
} else {
|
||||
switch (chat.chatInfo) {
|
||||
case let .direct(contact):
|
||||
if contact.activeConn == nil && contact.profile.contactLink != nil {
|
||||
chatPreviewInfoText("Tap to Connect")
|
||||
.foregroundColor(theme.colors.primary)
|
||||
} else if !contact.ready && contact.activeConn != nil {
|
||||
} else if !contact.sndReady && contact.activeConn != nil {
|
||||
if contact.nextSendGrpInv {
|
||||
chatPreviewInfoText("send direct message")
|
||||
} else if contact.active {
|
||||
@@ -225,6 +296,54 @@ struct ChatPreviewView: View {
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func chatItemContentPreview(_ chat: Chat, _ ci: ChatItem) -> some View {
|
||||
let mc = ci.content.msgContent
|
||||
switch mc {
|
||||
case let .link(_, preview):
|
||||
smallContentPreview(size: dynamicMediaSize) {
|
||||
ZStack(alignment: .topTrailing) {
|
||||
Image(uiImage: UIImage(base64Encoded: preview.image) ?? UIImage(systemName: "arrow.up.right")!)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: dynamicMediaSize, height: dynamicMediaSize)
|
||||
ZStack {
|
||||
Image(systemName: "arrow.up.right")
|
||||
.resizable()
|
||||
.foregroundColor(Color.white)
|
||||
.font(.system(size: 15, weight: .black))
|
||||
.frame(width: 8, height: 8)
|
||||
}
|
||||
.frame(width: 16, height: 16)
|
||||
.background(Color.black.opacity(0.25))
|
||||
.cornerRadius(8)
|
||||
}
|
||||
.onTapGesture {
|
||||
UIApplication.shared.open(preview.uri)
|
||||
}
|
||||
}
|
||||
case let .image(_, image):
|
||||
smallContentPreview(size: dynamicMediaSize) {
|
||||
CIImageView(chatItem: ci, preview: UIImage(base64Encoded: image), maxWidth: dynamicMediaSize, smallView: true, showFullScreenImage: $showFullscreenGallery)
|
||||
.environmentObject(ReverseListScrollModel<ChatItem>())
|
||||
}
|
||||
case let .video(_,image, duration):
|
||||
smallContentPreview(size: dynamicMediaSize) {
|
||||
CIVideoView(chatItem: ci, preview: UIImage(base64Encoded: image), duration: duration, maxWidth: dynamicMediaSize, videoWidth: nil, smallView: true, showFullscreenPlayer: $showFullscreenGallery)
|
||||
.environmentObject(ReverseListScrollModel<ChatItem>())
|
||||
}
|
||||
case let .voice(_, duration):
|
||||
smallContentPreviewVoice(size: dynamicMediaSize) {
|
||||
CIVoiceView(chat: chat, chatItem: ci, recordingFile: ci.file, duration: duration, allowMenu: Binding.constant(true), smallViewSize: dynamicMediaSize)
|
||||
}
|
||||
case .file:
|
||||
smallContentPreviewFile(size: dynamicMediaSize) {
|
||||
CIFileView(file: ci.file, edited: ci.meta.itemEdited, smallViewSize: dynamicMediaSize)
|
||||
}
|
||||
default: EmptyView()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder private func groupInvitationPreviewText(_ groupInfo: GroupInfo) -> some View {
|
||||
groupInfo.membership.memberIncognito
|
||||
? chatPreviewInfoText("join as \(groupInfo.membership.memberProfile.displayName)")
|
||||
@@ -294,10 +413,45 @@ struct ChatPreviewView: View {
|
||||
}
|
||||
}
|
||||
|
||||
func smallContentPreview(size: CGFloat, _ view: @escaping () -> some View) -> some View {
|
||||
view()
|
||||
.frame(width: size, height: size)
|
||||
.cornerRadius(8)
|
||||
.overlay(RoundedRectangle(cornerSize: CGSize(width: 8, height: 8))
|
||||
.strokeBorder(.secondary, lineWidth: 0.3, antialiased: true))
|
||||
.padding(.vertical, size / 6)
|
||||
.padding(.leading, 3)
|
||||
.offset(x: 6)
|
||||
}
|
||||
|
||||
func smallContentPreviewVoice(size: CGFloat, _ view: @escaping () -> some View) -> some View {
|
||||
view()
|
||||
.frame(height: voiceMessageSizeBasedOnSquareSize(size))
|
||||
.padding(.vertical, size / 6)
|
||||
.padding(.leading, 8)
|
||||
}
|
||||
|
||||
func smallContentPreviewFile(size: CGFloat, _ view: @escaping () -> some View) -> some View {
|
||||
view()
|
||||
.frame(width: size, height: size)
|
||||
.padding(.vertical, size / 7)
|
||||
.padding(.leading, 5)
|
||||
}
|
||||
|
||||
func unreadCountText(_ n: Int) -> Text {
|
||||
Text(n > 999 ? "\(n / 1000)k" : n > 0 ? "\(n)" : "")
|
||||
}
|
||||
|
||||
private struct ActiveContentPreview: Equatable {
|
||||
var chat: Chat
|
||||
var ci: ChatItem
|
||||
var mc: MsgContent
|
||||
|
||||
static func == (lhs: ActiveContentPreview, rhs: ActiveContentPreview) -> Bool {
|
||||
lhs.chat.id == rhs.chat.id && lhs.ci.id == rhs.ci.id && lhs.mc == rhs.mc
|
||||
}
|
||||
}
|
||||
|
||||
struct ChatPreviewView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group {
|
||||
|
||||
@@ -21,7 +21,7 @@ struct ContactConnectionInfo: View {
|
||||
|
||||
enum CCInfoAlert: Identifiable {
|
||||
case deleteInvitationAlert
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey)
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey?)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@@ -102,7 +102,7 @@ struct ContactConnectionInfo: View {
|
||||
} success: {
|
||||
dismiss()
|
||||
}
|
||||
case let .error(title, error): return Alert(title: Text(title), message: Text(error))
|
||||
case let .error(title, error): return mkAlert(title: title, message: error)
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
|
||||
@@ -12,12 +12,13 @@ import SimpleXChat
|
||||
struct ContactRequestView: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.dynamicTypeSize) private var userFont: DynamicTypeSize
|
||||
var contactRequest: UserContactRequest
|
||||
@ObservedObject var chat: Chat
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 8) {
|
||||
ChatInfoImage(chat: chat, size: 63)
|
||||
ChatInfoImage(chat: chat, size: dynamicSizes[userFont]?.profileImageSize ?? 63)
|
||||
.padding(.leading, 4)
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
HStack(alignment: .top) {
|
||||
|
||||
@@ -12,11 +12,12 @@ import SimpleXChat
|
||||
struct ServersSummaryView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Binding var serversSummary: PresentedServersSummary?
|
||||
@State private var serversSummary: PresentedServersSummary? = nil
|
||||
@State private var selectedUserCategory: PresentedUserCategory = .allUsers
|
||||
@State private var selectedServerType: PresentedServerType = .smp
|
||||
@State private var selectedSMPServer: String? = nil
|
||||
@State private var selectedXFTPServer: String? = nil
|
||||
@State private var timer: Timer? = nil
|
||||
@State private var alert: SomeAlert?
|
||||
|
||||
@AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false
|
||||
@@ -47,10 +48,36 @@ struct ServersSummaryView: View {
|
||||
if m.users.filter({ u in u.user.activeUser || !u.user.hidden }).count == 1 {
|
||||
selectedUserCategory = .currentUser
|
||||
}
|
||||
getServersSummary()
|
||||
startTimer()
|
||||
}
|
||||
.onDisappear {
|
||||
stopTimer()
|
||||
}
|
||||
.alert(item: $alert) { $0.alert }
|
||||
}
|
||||
|
||||
private func startTimer() {
|
||||
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
|
||||
if AppChatState.shared.value == .active {
|
||||
getServersSummary()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func getServersSummary() {
|
||||
do {
|
||||
serversSummary = try getAgentServersSummary()
|
||||
} catch let error {
|
||||
logger.error("getAgentServersSummary error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
|
||||
private func stopTimer() {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
}
|
||||
|
||||
private func shareButton() -> some View {
|
||||
Button {
|
||||
if let serversSummary = serversSummary {
|
||||
@@ -75,8 +102,8 @@ struct ServersSummaryView: View {
|
||||
Group {
|
||||
if m.users.filter({ u in u.user.activeUser || !u.user.hidden }).count > 1 {
|
||||
Picker("User selection", selection: $selectedUserCategory) {
|
||||
Text("All users").tag(PresentedUserCategory.allUsers)
|
||||
Text("Current user").tag(PresentedUserCategory.currentUser)
|
||||
Text("All profiles").tag(PresentedUserCategory.allUsers)
|
||||
Text("Current profile").tag(PresentedUserCategory.currentUser)
|
||||
}
|
||||
.pickerStyle(.segmented)
|
||||
}
|
||||
@@ -176,12 +203,13 @@ struct ServersSummaryView: View {
|
||||
Section {
|
||||
infoRow("Active connections", numOrDash(totals.subs.ssActive))
|
||||
infoRow("Total", numOrDash(totals.subs.total))
|
||||
Toggle("Show percentage", isOn: $showSubscriptionPercentage)
|
||||
} header: {
|
||||
HStack {
|
||||
Text("Message reception")
|
||||
SubscriptionStatusIndicatorView(subs: totals.subs, sess: totals.sessions)
|
||||
SubscriptionStatusIndicatorView(subs: totals.subs, hasSess: totals.sessions.hasSess)
|
||||
if showSubscriptionPercentage {
|
||||
SubscriptionStatusPercentageView(subs: totals.subs, sess: totals.sessions)
|
||||
SubscriptionStatusPercentageView(subs: totals.subs, hasSess: totals.sessions.hasSess)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,9 +287,9 @@ struct ServersSummaryView: View {
|
||||
if let subs = srvSumm.subs {
|
||||
Spacer()
|
||||
if showSubscriptionPercentage {
|
||||
SubscriptionStatusPercentageView(subs: subs, sess: srvSumm.sessionsOrNew)
|
||||
SubscriptionStatusPercentageView(subs: subs, hasSess: srvSumm.sessionsOrNew.hasSess)
|
||||
}
|
||||
SubscriptionStatusIndicatorView(subs: subs, sess: srvSumm.sessionsOrNew)
|
||||
SubscriptionStatusIndicatorView(subs: subs, hasSess: srvSumm.sessionsOrNew.hasSess)
|
||||
} else if let sess = srvSumm.sessions {
|
||||
Spacer()
|
||||
Image(systemName: "arrow.up.circle")
|
||||
@@ -355,6 +383,7 @@ struct ServersSummaryView: View {
|
||||
Task {
|
||||
do {
|
||||
try await resetAgentServersStats()
|
||||
getServersSummary()
|
||||
} catch let error {
|
||||
alert = SomeAlert(
|
||||
alert: mkAlert(
|
||||
@@ -379,11 +408,11 @@ struct ServersSummaryView: View {
|
||||
struct SubscriptionStatusIndicatorView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
var subs: SMPServerSubs
|
||||
var sess: ServerSessions
|
||||
var hasSess: Bool
|
||||
|
||||
var body: some View {
|
||||
let onionHosts = networkUseOnionHostsGroupDefault.get()
|
||||
let (color, variableValue, opacity, _) = subscriptionStatusColorAndPercentage(m.networkInfo.online, onionHosts, subs, sess)
|
||||
let (color, variableValue, opacity, _) = subscriptionStatusColorAndPercentage(m.networkInfo.online, onionHosts, subs, hasSess)
|
||||
if #available(iOS 16.0, *) {
|
||||
Image(systemName: "dot.radiowaves.up.forward", variableValue: variableValue)
|
||||
.foregroundColor(color)
|
||||
@@ -397,18 +426,18 @@ struct SubscriptionStatusIndicatorView: View {
|
||||
struct SubscriptionStatusPercentageView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
var subs: SMPServerSubs
|
||||
var sess: ServerSessions
|
||||
var hasSess: Bool
|
||||
|
||||
var body: some View {
|
||||
let onionHosts = networkUseOnionHostsGroupDefault.get()
|
||||
let (_, _, _, statusPercent) = subscriptionStatusColorAndPercentage(m.networkInfo.online, onionHosts, subs, sess)
|
||||
let (_, _, _, statusPercent) = subscriptionStatusColorAndPercentage(m.networkInfo.online, onionHosts, subs, hasSess)
|
||||
Text(verbatim: "\(Int(floor(statusPercent * 100)))%")
|
||||
.foregroundColor(.secondary)
|
||||
.font(.caption)
|
||||
}
|
||||
}
|
||||
|
||||
func subscriptionStatusColorAndPercentage(_ online: Bool, _ onionHosts: OnionHosts, _ subs: SMPServerSubs, _ sess: ServerSessions) -> (Color, Double, Double, Double) {
|
||||
func subscriptionStatusColorAndPercentage(_ online: Bool, _ onionHosts: OnionHosts, _ subs: SMPServerSubs, _ hasSess: Bool) -> (Color, Double, Double, Double) {
|
||||
func roundedToQuarter(_ n: Double) -> Double {
|
||||
n >= 1 ? 1
|
||||
: n <= 0 ? 0
|
||||
@@ -423,12 +452,12 @@ func subscriptionStatusColorAndPercentage(_ online: Bool, _ onionHosts: OnionHos
|
||||
? (
|
||||
subs.ssActive == 0
|
||||
? (
|
||||
sess.ssConnected == 0 ? noConnColorAndPercent : (activeColor, activeSubsRounded, subs.shareOfActive, subs.shareOfActive)
|
||||
hasSess ? (activeColor, activeSubsRounded, subs.shareOfActive, subs.shareOfActive) : noConnColorAndPercent
|
||||
)
|
||||
: ( // ssActive > 0
|
||||
sess.ssConnected == 0
|
||||
? (.orange, activeSubsRounded, subs.shareOfActive, subs.shareOfActive) // This would mean implementation error
|
||||
: (activeColor, activeSubsRounded, subs.shareOfActive, subs.shareOfActive)
|
||||
hasSess
|
||||
? (activeColor, activeSubsRounded, subs.shareOfActive, subs.shareOfActive)
|
||||
: (.orange, activeSubsRounded, subs.shareOfActive, subs.shareOfActive) // This would mean implementation error
|
||||
)
|
||||
)
|
||||
: noConnColorAndPercent
|
||||
@@ -481,9 +510,9 @@ struct SMPServerSummaryView: View {
|
||||
} header: {
|
||||
HStack {
|
||||
Text("Message reception")
|
||||
SubscriptionStatusIndicatorView(subs: subs, sess: summary.sessionsOrNew)
|
||||
SubscriptionStatusIndicatorView(subs: subs, hasSess: summary.sessionsOrNew.hasSess)
|
||||
if showSubscriptionPercentage {
|
||||
SubscriptionStatusPercentageView(subs: subs, sess: summary.sessionsOrNew)
|
||||
SubscriptionStatusPercentageView(subs: subs, hasSess: summary.sessionsOrNew.hasSess)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -588,7 +617,7 @@ struct DetailedSMPStatsView: View {
|
||||
infoRow(Text(verbatim: "NO_MSG errors"), numOrDash(stats._ackNoMsgErrs)).padding(.leading, 24)
|
||||
infoRow("other errors", numOrDash(stats._ackOtherErrs)).padding(.leading, 24)
|
||||
}
|
||||
Section {
|
||||
Section("Connections") {
|
||||
infoRow("Created", numOrDash(stats._connCreated))
|
||||
infoRow("Secured", numOrDash(stats._connCreated))
|
||||
infoRow("Completed", numOrDash(stats._connCompleted))
|
||||
@@ -597,8 +626,12 @@ struct DetailedSMPStatsView: View {
|
||||
infoRowTwoValues("Subscribed", "attempts", stats._connSubscribed, stats._connSubAttempts)
|
||||
infoRow("Subscriptions ignored", numOrDash(stats._connSubIgnored))
|
||||
infoRow("Subscription errors", numOrDash(stats._connSubErrs))
|
||||
}
|
||||
Section {
|
||||
infoRowTwoValues("Enabled", "attempts", stats._ntfKey, stats._ntfKeyAttempts)
|
||||
infoRowTwoValues("Disabled", "attempts", stats._ntfKeyDeleted, stats._ntfKeyDeleteAttempts)
|
||||
} header: {
|
||||
Text("Connections")
|
||||
Text("Connection notifications")
|
||||
} footer: {
|
||||
Text("Starting from \(localTimestamp(statsStartedAt)).")
|
||||
}
|
||||
@@ -711,7 +744,5 @@ struct DetailedXFTPStatsView: View {
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ServersSummaryView(
|
||||
serversSummary: Binding.constant(nil)
|
||||
)
|
||||
ServersSummaryView()
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ struct DatabaseErrorView: View {
|
||||
case let .migrationError(mtrError):
|
||||
titleText("Incompatible database version")
|
||||
fileNameText(dbFile)
|
||||
Text("Error: ") + Text(DatabaseErrorView.mtrErrorDescription(mtrError))
|
||||
Text("Error: ") + Text(mtrErrorDescription(mtrError))
|
||||
}
|
||||
case let .errorSQL(dbFile, migrationSQLError):
|
||||
titleText("Database error")
|
||||
@@ -105,15 +105,6 @@ struct DatabaseErrorView: View {
|
||||
Text("Migrations: \(ms.joined(separator: ", "))")
|
||||
}
|
||||
|
||||
static func mtrErrorDescription(_ err: MTRError) -> LocalizedStringKey {
|
||||
switch err {
|
||||
case let .noDown(dbMigrations):
|
||||
return "database version is newer than the app, but no down migration for: \(dbMigrations.joined(separator: ", "))"
|
||||
case let .different(appMigration, dbMigration):
|
||||
return "different migration in the app/database: \(appMigration) / \(dbMigration)"
|
||||
}
|
||||
}
|
||||
|
||||
private func databaseKeyField(onSubmit: @escaping () -> Void) -> some View {
|
||||
PassphraseField(key: $dbKey, placeholder: "Enter passphrase…", valid: validKey(dbKey), onSubmit: onSubmit)
|
||||
}
|
||||
|
||||
@@ -16,18 +16,10 @@ struct ChatInfoImage: View {
|
||||
var color = Color(uiColor: .tertiarySystemGroupedBackground)
|
||||
|
||||
var body: some View {
|
||||
var iconName: String
|
||||
switch chat.chatInfo {
|
||||
case .direct: iconName = "person.crop.circle.fill"
|
||||
case .group: iconName = "person.2.circle.fill"
|
||||
case .local: iconName = "folder.circle.fill"
|
||||
case .contactRequest: iconName = "person.crop.circle.fill"
|
||||
default: iconName = "circle.fill"
|
||||
}
|
||||
let iconColor = if case .local = chat.chatInfo { theme.appColors.primaryVariant2 } else { color }
|
||||
return ProfileImage(
|
||||
imageStr: chat.chatInfo.image,
|
||||
iconName: iconName,
|
||||
iconName: chatIconName(chat.chatInfo),
|
||||
size: size,
|
||||
color: iconColor
|
||||
)
|
||||
|
||||
@@ -23,8 +23,10 @@ struct ChatViewBackground: ViewModifier {
|
||||
var image = context.resolve(image)
|
||||
let rect = CGRectMake(0, 0, size.width, size.height)
|
||||
func repeatDraw(_ imageScale: CGFloat) {
|
||||
// Prevent range bounds crash and dividing by zero
|
||||
if size.height == 0 || size.width == 0 || image.size.height == 0 || image.size.width == 0 { return }
|
||||
image.shading = .color(tint)
|
||||
let scale = imageScale * 1.57 // for some reason a wallpaper on iOS looks smaller than on Android
|
||||
let scale = imageScale * 2.5 // scale wallpaper for iOS
|
||||
for h in 0 ... Int(size.height / image.size.height / scale) {
|
||||
for w in 0 ... Int(size.width / image.size.width / scale) {
|
||||
let rect = CGRectMake(CGFloat(w) * image.size.width * scale, CGFloat(h) * image.size.height * scale, image.size.width * scale, image.size.height * scale)
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
//
|
||||
// VideoUtils.swift
|
||||
// SimpleX (iOS)
|
||||
//
|
||||
// Created by Avently on 25.12.2023.
|
||||
// Copyright © 2023 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import AVFoundation
|
||||
import Foundation
|
||||
import SimpleXChat
|
||||
|
||||
func makeVideoQualityLower(_ input: URL, outputUrl: URL) async -> Bool {
|
||||
let asset: AVURLAsset = AVURLAsset(url: input, options: nil)
|
||||
if let s = AVAssetExportSession(asset: asset, presetName: AVAssetExportPreset640x480) {
|
||||
s.outputURL = outputUrl
|
||||
s.outputFileType = .mp4
|
||||
s.metadataItemFilter = AVMetadataItemFilter.forSharing()
|
||||
await s.export()
|
||||
if let err = s.error {
|
||||
logger.error("Failed to export video with error: \(err)")
|
||||
}
|
||||
return s.status == .completed
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -17,3 +17,37 @@ extension View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Notification.Name {
|
||||
static let chatViewWillBeginScrolling = Notification.Name("chatWillBeginScrolling")
|
||||
}
|
||||
|
||||
struct PrivacyBlur: ViewModifier {
|
||||
var enabled: Bool = true
|
||||
@Binding var blurred: Bool
|
||||
@AppStorage(DEFAULT_PRIVACY_MEDIA_BLUR_RADIUS) private var blurRadius: Int = 0
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
if blurRadius > 0 {
|
||||
// parallel ifs are necessary here because otherwise some views flicker,
|
||||
// e.g. when playing video
|
||||
content
|
||||
.blur(radius: blurred && enabled ? CGFloat(blurRadius) * 0.5 : 0)
|
||||
.overlay {
|
||||
if (blurred && enabled) {
|
||||
Color.clear.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
blurred = false
|
||||
}
|
||||
}
|
||||
}
|
||||
.onReceive(NotificationCenter.default.publisher(for: .chatViewWillBeginScrolling)) { _ in
|
||||
if !blurred {
|
||||
blurred = true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
content
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,7 +662,7 @@ private struct PassphraseConfirmationView: View {
|
||||
if case .chatCmdError(_, .errorDatabase(.errorOpen(.errorNotADatabase))) = error as? ChatResponse {
|
||||
showErrorOnMigrationIfNeeded(.errorNotADatabase(dbFile: ""), $alert)
|
||||
} else {
|
||||
alert = .error(title: "Error", error: NSLocalizedString("Error verifying passphrase:", comment: "") + " " + String(String(describing: error)))
|
||||
alert = .error(title: "Error", error: NSLocalizedString("Error verifying passphrase:", comment: "") + " " + String(responseError(error)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,7 +331,7 @@ struct MigrateToDevice: View {
|
||||
case let .migrationError(mtrError):
|
||||
("Incompatible database version",
|
||||
nil,
|
||||
"\(NSLocalizedString("Error: ", comment: "")) \(DatabaseErrorView.mtrErrorDescription(mtrError))",
|
||||
"\(NSLocalizedString("Error: ", comment: "")) \(mtrErrorDescription(mtrError))",
|
||||
nil)
|
||||
}
|
||||
default: ("Error", nil, "Unknown error", nil)
|
||||
|
||||
@@ -37,7 +37,7 @@ struct ConnectDesktopView: View {
|
||||
case badInvitationError
|
||||
case badVersionError(version: String?)
|
||||
case desktopDisconnectedError
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey = "")
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey?)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@@ -160,7 +160,7 @@ struct ConnectDesktopView: View {
|
||||
case .desktopDisconnectedError:
|
||||
Alert(title: Text("Connection terminated"))
|
||||
case let .error(title, error):
|
||||
Alert(title: Text(title), message: Text(error))
|
||||
mkAlert(title: title, message: error)
|
||||
}
|
||||
}
|
||||
.interactiveDismissDisabled(m.activeRemoteCtrl)
|
||||
|
||||
@@ -32,6 +32,7 @@ extension AppSettings {
|
||||
if let val = privacyShowChatPreviews { def.setValue(val, forKey: DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS) }
|
||||
if let val = privacySaveLastDraft { def.setValue(val, forKey: DEFAULT_PRIVACY_SAVE_LAST_DRAFT) }
|
||||
if let val = privacyProtectScreen { def.setValue(val, forKey: DEFAULT_PRIVACY_PROTECT_SCREEN) }
|
||||
if let val = privacyMediaBlurRadius { def.setValue(val, forKey: DEFAULT_PRIVACY_MEDIA_BLUR_RADIUS) }
|
||||
if let val = notificationMode { ChatModel.shared.notificationMode = val.toNotificationsMode() }
|
||||
if let val = notificationPreviewMode { ntfPreviewModeGroupDefault.set(val) }
|
||||
if let val = webrtcPolicyRelay { def.setValue(val, forKey: DEFAULT_WEBRTC_POLICY_RELAY) }
|
||||
@@ -62,6 +63,7 @@ extension AppSettings {
|
||||
c.privacyShowChatPreviews = def.bool(forKey: DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS)
|
||||
c.privacySaveLastDraft = def.bool(forKey: DEFAULT_PRIVACY_SAVE_LAST_DRAFT)
|
||||
c.privacyProtectScreen = def.bool(forKey: DEFAULT_PRIVACY_PROTECT_SCREEN)
|
||||
c.privacyMediaBlurRadius = def.integer(forKey: DEFAULT_PRIVACY_MEDIA_BLUR_RADIUS)
|
||||
c.notificationMode = AppSettingsNotificationMode.from(ChatModel.shared.notificationMode)
|
||||
c.notificationPreviewMode = ntfPreviewModeGroupDefault.get()
|
||||
c.webrtcPolicyRelay = def.bool(forKey: DEFAULT_WEBRTC_POLICY_RELAY)
|
||||
|
||||
@@ -32,7 +32,6 @@ struct NetworkAndServers: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
|
||||
@AppStorage(DEFAULT_SHOW_SENT_VIA_RPOXY) private var showSentViaProxy = false
|
||||
@AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false
|
||||
@State private var cfgLoaded = false
|
||||
@State private var currentNetCfg = NetCfg.defaults
|
||||
@State private var netCfg = NetCfg.defaults
|
||||
@@ -62,8 +61,6 @@ struct NetworkAndServers: View {
|
||||
Text("XFTP servers")
|
||||
}
|
||||
|
||||
Toggle("Subscription percentage", isOn: $showSubscriptionPercentage)
|
||||
|
||||
Picker("Use .onion hosts", selection: $onionHosts) {
|
||||
ForEach(OnionHosts.values, id: \.self) { Text($0.text) }
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ struct PrivacySettings: View {
|
||||
@AppStorage(DEFAULT_PRIVACY_PROTECT_SCREEN) private var protectScreen = false
|
||||
@AppStorage(DEFAULT_PERFORM_LA) private var prefPerformLA = false
|
||||
@State private var currentLAMode = privacyLocalAuthModeDefault.get()
|
||||
@AppStorage(DEFAULT_PRIVACY_MEDIA_BLUR_RADIUS) private var privacyMediaBlurRadius: Int = 0
|
||||
@State private var contactReceipts = false
|
||||
@State private var contactReceiptsReset = false
|
||||
@State private var contactReceiptsOverrides = 0
|
||||
@@ -113,6 +114,22 @@ struct PrivacySettings: View {
|
||||
privacyAcceptImagesGroupDefault.set($0)
|
||||
}
|
||||
}
|
||||
settingsRow("circle.rectangle.filled.pattern.diagonalline", color: theme.colors.secondary) {
|
||||
Picker("Blur media", selection: $privacyMediaBlurRadius) {
|
||||
let values = [0, 12, 24, 48] + ([0, 12, 24, 48].contains(privacyMediaBlurRadius) ? [] : [privacyMediaBlurRadius])
|
||||
ForEach(values, id: \.self) { radius in
|
||||
let text: String = switch radius {
|
||||
case 0: NSLocalizedString("Off", comment: "blur media")
|
||||
case 12: NSLocalizedString("Soft", comment: "blur media")
|
||||
case 24: NSLocalizedString("Medium", comment: "blur media")
|
||||
case 48: NSLocalizedString("Strong", comment: "blur media")
|
||||
default: "\(radius)"
|
||||
}
|
||||
Text(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(height: 36)
|
||||
settingsRow("network.badge.shield.half.filled", color: theme.colors.secondary) {
|
||||
Toggle("Protect IP address", isOn: $askToApproveRelays)
|
||||
}
|
||||
|
||||
@@ -175,10 +175,6 @@ func testServerConnection(server: Binding<ServerCfg>) async -> ProtocolTestFailu
|
||||
}
|
||||
}
|
||||
|
||||
func serverHostname(_ srv: String) -> String {
|
||||
parseServerAddress(srv)?.hostnames.first ?? srv
|
||||
}
|
||||
|
||||
struct ProtocolServerView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ProtocolServerView(
|
||||
|
||||
@@ -34,6 +34,7 @@ let DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS = "privacyShowChatPreviews"
|
||||
let DEFAULT_PRIVACY_SAVE_LAST_DRAFT = "privacySaveLastDraft"
|
||||
let DEFAULT_PRIVACY_PROTECT_SCREEN = "privacyProtectScreen"
|
||||
let DEFAULT_PRIVACY_DELIVERY_RECEIPTS_SET = "privacyDeliveryReceiptsSet"
|
||||
let DEFAULT_PRIVACY_MEDIA_BLUR_RADIUS = "privacyMediaBlurRadius"
|
||||
let DEFAULT_EXPERIMENTAL_CALLS = "experimentalCalls"
|
||||
let DEFAULT_CHAT_ARCHIVE_NAME = "chatArchiveName"
|
||||
let DEFAULT_CHAT_ARCHIVE_TIME = "chatArchiveTime"
|
||||
@@ -87,6 +88,7 @@ let appDefaults: [String: Any] = [
|
||||
DEFAULT_PRIVACY_SAVE_LAST_DRAFT: true,
|
||||
DEFAULT_PRIVACY_PROTECT_SCREEN: false,
|
||||
DEFAULT_PRIVACY_DELIVERY_RECEIPTS_SET: false,
|
||||
DEFAULT_PRIVACY_MEDIA_BLUR_RADIUS: 0,
|
||||
DEFAULT_EXPERIMENTAL_CALLS: false,
|
||||
DEFAULT_CHAT_V3_DB_MIGRATION: V3DBMigrationState.offer.rawValue,
|
||||
DEFAULT_DEVELOPER_TOOLS: false,
|
||||
|
||||
@@ -30,7 +30,7 @@ struct UserAddressView: View {
|
||||
case deleteAddress
|
||||
case profileAddress(on: Bool)
|
||||
case shareOnCreate
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey = "")
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey?)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@@ -185,7 +185,7 @@ struct UserAddressView: View {
|
||||
}, secondaryButton: .cancel()
|
||||
)
|
||||
case let .error(title, error):
|
||||
return Alert(title: Text(title), message: Text(error))
|
||||
return mkAlert(title: title, message: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ struct UserProfilesView: View {
|
||||
case hiddenProfilesNotice
|
||||
case muteProfileAlert
|
||||
case activateUserError(error: String)
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey = "")
|
||||
case error(title: LocalizedStringKey, error: LocalizedStringKey?)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@@ -172,7 +172,7 @@ struct UserProfilesView: View {
|
||||
message: Text(err)
|
||||
)
|
||||
case let .error(title, error):
|
||||
return Alert(title: Text(title), message: Text(error))
|
||||
return mkAlert(title: title, message: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,8 +709,8 @@
|
||||
<target>Всички нови съобщения от %@ ще бъдат скрити!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1705,8 +1705,8 @@ This is your own one-time link!</source>
|
||||
<target>Текуща парола…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5639,6 +5639,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server version is incompatible with network settings.</source>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5779,6 +5783,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Show message status</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Показване на визуализация</target>
|
||||
@@ -6002,10 +6010,6 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -7060,8 +7064,8 @@ Repeat join request?</source>
|
||||
<target>Можете да го направите видим за вашите контакти в SimpleX чрез Настройки.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Вече можете да изпращате съобщения до %@</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7468,7 +7472,7 @@ SimpleX сървърите не могат да видят вашия профи
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>блокиран от админ</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -687,8 +687,8 @@
|
||||
<source>All new messages from %@ will be hidden!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1635,8 +1635,8 @@ This is your own one-time link!</source>
|
||||
<target>Aktuální přístupová fráze…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5437,6 +5437,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server version is incompatible with network settings.</source>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5572,6 +5576,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Show message status</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Zobrazení náhledu</target>
|
||||
@@ -5789,10 +5797,6 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6793,8 +6797,8 @@ Repeat join request?</source>
|
||||
<source>You can make it visible to your SimpleX contacts via Settings.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Nyní můžete posílat zprávy %@</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7187,7 +7191,7 @@ Servery SimpleX nevidí váš profil.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -554,6 +554,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Accent" xml:space="preserve">
|
||||
<source>Accent</source>
|
||||
<target>Akzent</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept" xml:space="preserve">
|
||||
@@ -579,10 +580,12 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
<target>Bestätigt</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledgement errors" xml:space="preserve">
|
||||
<source>Acknowledgement errors</source>
|
||||
<target>Fehler bei der Bestätigung</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
@@ -631,14 +634,17 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Additional accent" xml:space="preserve">
|
||||
<source>Additional accent</source>
|
||||
<target>Erste Akzentfarbe</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Additional accent 2" xml:space="preserve">
|
||||
<source>Additional accent 2</source>
|
||||
<target>Zusätzlicher Akzent 2</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Additional secondary" xml:space="preserve">
|
||||
<source>Additional secondary</source>
|
||||
<target>Zweite Akzentfarbe</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Address" xml:space="preserve">
|
||||
@@ -668,6 +674,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Advanced settings" xml:space="preserve">
|
||||
<source>Advanced settings</source>
|
||||
<target>Erweiterte Einstellungen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All app data is deleted." xml:space="preserve">
|
||||
@@ -677,7 +684,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="All chats and messages will be deleted - this cannot be undone!" xml:space="preserve">
|
||||
<source>All chats and messages will be deleted - this cannot be undone!</source>
|
||||
<target>Alle Chats und Nachrichten werden gelöscht! Dies kann nicht rückgängig gemacht werden!</target>
|
||||
<target>Alle Chats und Nachrichten werden gelöscht. Dies kann nicht rückgängig gemacht werden!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All data is erased when it is entered." xml:space="preserve">
|
||||
@@ -687,6 +694,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="All data is private to your device." xml:space="preserve">
|
||||
<source>All data is private to your device.</source>
|
||||
<target>Alle Daten sind auf Ihrem Gerät geschützt.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All group members will remain connected." xml:space="preserve">
|
||||
@@ -696,12 +704,12 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="All messages will be deleted - this cannot be undone!" xml:space="preserve">
|
||||
<source>All messages will be deleted - this cannot be undone!</source>
|
||||
<target>Es werden alle Nachrichten gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden!</target>
|
||||
<target>Es werden alle Nachrichten gelöscht. Dies kann nicht rückgängig gemacht werden!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." xml:space="preserve">
|
||||
<source>All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you.</source>
|
||||
<target>Alle Nachrichten werden gelöscht - dies kann nicht rückgängig gemacht werden! Die Nachrichten werden NUR bei Ihnen gelöscht.</target>
|
||||
<target>Alle Nachrichten werden gelöscht . Dies kann nicht rückgängig gemacht werden! Die Nachrichten werden NUR bei Ihnen gelöscht.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All new messages from %@ will be hidden!" xml:space="preserve">
|
||||
@@ -709,8 +717,9 @@
|
||||
<target>Von %@ werden alle neuen Nachrichten ausgeblendet!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<target>Alle Profile</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -915,6 +924,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Apply to" xml:space="preserve">
|
||||
<source>Apply to</source>
|
||||
<target>Anwenden auf</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive and upload" xml:space="preserve">
|
||||
@@ -994,6 +1004,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Background" xml:space="preserve">
|
||||
<source>Background</source>
|
||||
<target>Hintergrund-Farbe</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Bad desktop address" xml:space="preserve">
|
||||
@@ -1023,6 +1034,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Schwarz</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block" xml:space="preserve">
|
||||
@@ -1137,6 +1149,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Cannot forward message" xml:space="preserve">
|
||||
<source>Cannot forward message</source>
|
||||
<target>Die Nachricht kann nicht weitergeleitet werden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cannot receive file" xml:space="preserve">
|
||||
@@ -1212,6 +1225,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat colors" xml:space="preserve">
|
||||
<source>Chat colors</source>
|
||||
<target>Chat-Farben</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat console" xml:space="preserve">
|
||||
@@ -1261,6 +1275,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Chat-Design</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chats" xml:space="preserve">
|
||||
@@ -1295,14 +1310,17 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chunks deleted" xml:space="preserve">
|
||||
<source>Chunks deleted</source>
|
||||
<target>Daten-Pakete gelöscht</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chunks downloaded" xml:space="preserve">
|
||||
<source>Chunks downloaded</source>
|
||||
<target>Daten-Pakete heruntergeladen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chunks uploaded" xml:space="preserve">
|
||||
<source>Chunks uploaded</source>
|
||||
<target>Daten-Pakete hochgeladen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
@@ -1332,6 +1350,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<target>Farbvariante</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Compare file" xml:space="preserve">
|
||||
@@ -1346,6 +1365,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Completed" xml:space="preserve">
|
||||
<source>Completed</source>
|
||||
<target>Abgeschlossen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configure ICE servers" xml:space="preserve">
|
||||
@@ -1463,6 +1483,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected" xml:space="preserve">
|
||||
<source>Connected</source>
|
||||
<target>Verbunden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected desktop" xml:space="preserve">
|
||||
@@ -1472,6 +1493,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected servers" xml:space="preserve">
|
||||
<source>Connected servers</source>
|
||||
<target>Verbundene Server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected to desktop" xml:space="preserve">
|
||||
@@ -1481,6 +1503,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting" xml:space="preserve">
|
||||
<source>Connecting</source>
|
||||
<target>Verbinden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting server…" xml:space="preserve">
|
||||
@@ -1530,10 +1553,12 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection with desktop stopped" xml:space="preserve">
|
||||
<source>Connection with desktop stopped</source>
|
||||
<target>Die Verbindung mit dem Desktop wurde gestoppt</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections" xml:space="preserve">
|
||||
<source>Connections</source>
|
||||
<target>Verbindungen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
@@ -1593,6 +1618,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy error" xml:space="preserve">
|
||||
<source>Copy error</source>
|
||||
<target>Fehlermeldung kopieren</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Core version: v%@" xml:space="preserve">
|
||||
@@ -1672,6 +1698,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Created" xml:space="preserve">
|
||||
<source>Created</source>
|
||||
<target>Erstellt</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Created at" xml:space="preserve">
|
||||
@@ -1709,8 +1736,9 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<target>Aktuelles Passwort…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<target>Aktueller Profil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -1725,6 +1753,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Design anpassen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Dark" xml:space="preserve">
|
||||
@@ -1734,6 +1763,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Dark mode colors" xml:space="preserve">
|
||||
<source>Dark mode colors</source>
|
||||
<target>Farben für die dunkle Variante</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Database ID" xml:space="preserve">
|
||||
@@ -1923,7 +1953,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<source>Delete contact?
|
||||
This cannot be undone!</source>
|
||||
<target>Kontakt löschen?
|
||||
Das kann nicht rückgängig gemacht werden!</target>
|
||||
Dies kann nicht rückgängig gemacht werden!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete database" xml:space="preserve">
|
||||
@@ -2023,7 +2053,7 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Die ausstehende Verbindung löschen?</target>
|
||||
<target>Ausstehende Verbindung löschen?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete profile" xml:space="preserve">
|
||||
@@ -2043,6 +2073,7 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted" xml:space="preserve">
|
||||
<source>Deleted</source>
|
||||
<target>Gelöscht</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted at" xml:space="preserve">
|
||||
@@ -2057,6 +2088,7 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<target>Fehler beim Löschen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delivery" xml:space="preserve">
|
||||
@@ -2101,10 +2133,12 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Detailed statistics" xml:space="preserve">
|
||||
<source>Detailed statistics</source>
|
||||
<target>Detaillierte Statistiken</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Details" xml:space="preserve">
|
||||
<source>Details</source>
|
||||
<target>Details</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Develop" xml:space="preserve">
|
||||
@@ -2264,6 +2298,7 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Download errors" xml:space="preserve">
|
||||
<source>Download errors</source>
|
||||
<target>Fehler beim Herunterladen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Download failed" xml:space="preserve">
|
||||
@@ -2278,10 +2313,12 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Downloaded" xml:space="preserve">
|
||||
<source>Downloaded</source>
|
||||
<target>Heruntergeladen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Downloaded files" xml:space="preserve">
|
||||
<source>Downloaded files</source>
|
||||
<target>Heruntergeladene Dateien</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Downloading archive" xml:space="preserve">
|
||||
@@ -2656,6 +2693,7 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error exporting theme: %@" xml:space="preserve">
|
||||
<source>Error exporting theme: %@</source>
|
||||
<target>Fehler beim Exportieren des Designs: %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error importing chat database" xml:space="preserve">
|
||||
@@ -2685,10 +2723,12 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error reconnecting server" xml:space="preserve">
|
||||
<source>Error reconnecting server</source>
|
||||
<target>Fehler beim Wiederherstellen der Verbindung zum Server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error reconnecting servers" xml:space="preserve">
|
||||
<source>Error reconnecting servers</source>
|
||||
<target>Fehler beim Wiederherstellen der Verbindungen zu den Servern</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error removing member" xml:space="preserve">
|
||||
@@ -2698,6 +2738,7 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error resetting statistics" xml:space="preserve">
|
||||
<source>Error resetting statistics</source>
|
||||
<target>Fehler beim Zurücksetzen der Statistiken</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error saving %@ servers" xml:space="preserve">
|
||||
@@ -2833,6 +2874,7 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Errors" xml:space="preserve">
|
||||
<source>Errors</source>
|
||||
<target>Fehler</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when disabled in the conversation." xml:space="preserve">
|
||||
@@ -2862,6 +2904,7 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Export theme" xml:space="preserve">
|
||||
<source>Export theme</source>
|
||||
<target>Design exportieren</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exported database archive." xml:space="preserve">
|
||||
@@ -2901,22 +2944,27 @@ Das kann nicht rückgängig gemacht werden!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
<target>Datei-Fehler</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
|
||||
<source>File not found - most likely file was deleted or cancelled.</source>
|
||||
<target>Datei nicht gefunden - höchstwahrscheinlich wurde die Datei gelöscht oder der Transfer abgebrochen.</target>
|
||||
<note>file error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File server error: %@" xml:space="preserve">
|
||||
<source>File server error: %@</source>
|
||||
<target>Datei-Server Fehler: %@</target>
|
||||
<note>file error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File status" xml:space="preserve">
|
||||
<source>File status</source>
|
||||
<target>Datei-Status</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File status: %@" xml:space="preserve">
|
||||
<source>File status: %@</source>
|
||||
<target>Datei-Status: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File will be deleted from servers." xml:space="preserve">
|
||||
@@ -3110,10 +3158,12 @@ Fehler: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Good afternoon!" xml:space="preserve">
|
||||
<source>Good afternoon!</source>
|
||||
<target>Guten Nachmittag!</target>
|
||||
<note>message preview</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Good morning!" xml:space="preserve">
|
||||
<source>Good morning!</source>
|
||||
<target>Guten Morgen!</target>
|
||||
<note>message preview</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Group" xml:space="preserve">
|
||||
@@ -3238,12 +3288,12 @@ Fehler: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Group will be deleted for all members - this cannot be undone!" xml:space="preserve">
|
||||
<source>Group will be deleted for all members - this cannot be undone!</source>
|
||||
<target>Die Gruppe wird für alle Mitglieder gelöscht - dies kann nicht rückgängig gemacht werden!</target>
|
||||
<target>Die Gruppe wird für alle Mitglieder gelöscht. Dies kann nicht rückgängig gemacht werden!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Group will be deleted for you - this cannot be undone!" xml:space="preserve">
|
||||
<source>Group will be deleted for you - this cannot be undone!</source>
|
||||
<target>Die Gruppe wird für Sie gelöscht - dies kann nicht rückgängig gemacht werden!</target>
|
||||
<target>Die Gruppe wird für Sie gelöscht. Dies kann nicht rückgängig gemacht werden!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Help" xml:space="preserve">
|
||||
@@ -3398,6 +3448,7 @@ Fehler: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Import theme" xml:space="preserve">
|
||||
<source>Import theme</source>
|
||||
<target>Design importieren</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Importing archive" xml:space="preserve">
|
||||
@@ -3524,6 +3575,7 @@ Fehler: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Interface colors" xml:space="preserve">
|
||||
<source>Interface colors</source>
|
||||
<target>Interface-Farben</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Invalid QR code" xml:space="preserve">
|
||||
@@ -3871,6 +3923,7 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<target>Mitglied inaktiv</target>
|
||||
<note>item status text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member role will be changed to "%@". All group members will be notified." xml:space="preserve">
|
||||
@@ -3885,11 +3938,12 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member will be removed from group - this cannot be undone!" xml:space="preserve">
|
||||
<source>Member will be removed from group - this cannot be undone!</source>
|
||||
<target>Das Mitglied wird aus der Gruppe entfernt - dies kann nicht rückgängig gemacht werden!</target>
|
||||
<target>Das Mitglied wird aus der Gruppe entfernt. Dies kann nicht rückgängig gemacht werden!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Menus" xml:space="preserve">
|
||||
<source>Menus</source>
|
||||
<target>Menüs</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message delivery error" xml:space="preserve">
|
||||
@@ -3914,10 +3968,12 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<target>Nachricht weitergeleitet</target>
|
||||
<note>item status text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message may be delivered later if member becomes active." xml:space="preserve">
|
||||
<source>Message may be delivered later if member becomes active.</source>
|
||||
<target>Die Nachricht kann später zugestellt werden, wenn das Mitglied aktiv wird.</target>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
@@ -3961,10 +4017,12 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message status" xml:space="preserve">
|
||||
<source>Message status</source>
|
||||
<target>Nachrichten-Status</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message status: %@" xml:space="preserve">
|
||||
<source>Message status: %@</source>
|
||||
<target>Nachrichten-Status: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
@@ -3994,10 +4052,12 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages received" xml:space="preserve">
|
||||
<source>Messages received</source>
|
||||
<target>Empfangene Nachrichten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages sent" xml:space="preserve">
|
||||
<source>Messages sent</source>
|
||||
<target>Gesendete Nachrichten</target>
|
||||
<note>No comment provided by engineer.</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">
|
||||
@@ -4237,6 +4297,7 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="No direct connection yet, message is forwarded by admin." xml:space="preserve">
|
||||
<source>No direct connection yet, message is forwarded by admin.</source>
|
||||
<target>Bisher keine direkte Verbindung. Nachricht wird von einem Admin weitergeleitet.</target>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
@@ -4256,6 +4317,7 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="No info, try to reload" xml:space="preserve">
|
||||
<source>No info, try to reload</source>
|
||||
<target>Keine Information - es wird versucht neu zu laden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No network connection" xml:space="preserve">
|
||||
@@ -4444,6 +4506,7 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Open server settings" xml:space="preserve">
|
||||
<source>Open server settings</source>
|
||||
<target>Server-Einstellungen öffnen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Open user profiles" xml:space="preserve">
|
||||
@@ -4557,6 +4620,7 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Pending" xml:space="preserve">
|
||||
<source>Pending</source>
|
||||
<target>Ausstehend</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="People can connect to you only via the links you share." xml:space="preserve">
|
||||
@@ -4587,6 +4651,8 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<trans-unit id="Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. Please share any other issues with the developers." xml:space="preserve">
|
||||
<source>Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection.
|
||||
Please share any other issues with the developers.</source>
|
||||
<target>Bitte überprüfen Sie, ob sich das Mobiltelefon und die Desktop-App im gleichen lokalen Netzwerk befinden, und die Desktop-Firewall die Verbindung erlaubt.
|
||||
Bitte teilen Sie weitere mögliche Probleme den Entwicklern mit.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please check that you used the correct link or ask your contact to send you another one." xml:space="preserve">
|
||||
@@ -4692,6 +4758,7 @@ Fehler: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Previously connected servers" xml:space="preserve">
|
||||
<source>Previously connected servers</source>
|
||||
<target>Bisher verbundene Server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Privacy & security" xml:space="preserve">
|
||||
@@ -4765,6 +4832,7 @@ Fehler: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile theme" xml:space="preserve">
|
||||
<source>Profile theme</source>
|
||||
<target>Profil-Design</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile update will be sent to your contacts." xml:space="preserve">
|
||||
@@ -4851,10 +4919,12 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proxied" xml:space="preserve">
|
||||
<source>Proxied</source>
|
||||
<target>Proxy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proxied servers" xml:space="preserve">
|
||||
<source>Proxied servers</source>
|
||||
<target>Proxy-Server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
@@ -4924,6 +4994,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Receive errors" xml:space="preserve">
|
||||
<source>Receive errors</source>
|
||||
<target>Fehler beim Empfang</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Received at" xml:space="preserve">
|
||||
@@ -4948,14 +5019,17 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Received messages" xml:space="preserve">
|
||||
<source>Received messages</source>
|
||||
<target>Empfangene Nachrichten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Received reply" xml:space="preserve">
|
||||
<source>Received reply</source>
|
||||
<target>Empfangene Antwort</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Received total" xml:space="preserve">
|
||||
<source>Received total</source>
|
||||
<target>Summe aller empfangenen Nachrichten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Receiving address will be changed to a different server. Address change will complete after sender comes online." xml:space="preserve">
|
||||
@@ -4990,6 +5064,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect" xml:space="preserve">
|
||||
<source>Reconnect</source>
|
||||
<target>Neu verbinden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect all connected servers to force message delivery. It uses additional traffic." xml:space="preserve">
|
||||
@@ -4999,18 +5074,22 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect all servers" xml:space="preserve">
|
||||
<source>Reconnect all servers</source>
|
||||
<target>Alle Server neu verbinden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect all servers?" xml:space="preserve">
|
||||
<source>Reconnect all servers?</source>
|
||||
<target>Alle Server neu verbinden?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect server to force message delivery. It uses additional traffic." xml:space="preserve">
|
||||
<source>Reconnect server to force message delivery. It uses additional traffic.</source>
|
||||
<target>Um die Auslieferung von Nachrichten zu erzwingen, wird der Server neu verbunden. Dafür wird weiterer Datenverkehr benötigt.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect server?" xml:space="preserve">
|
||||
<source>Reconnect server?</source>
|
||||
<target>Server neu verbinden?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect servers?" xml:space="preserve">
|
||||
@@ -5065,6 +5144,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove image" xml:space="preserve">
|
||||
<source>Remove image</source>
|
||||
<target>Bild entfernen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove member" xml:space="preserve">
|
||||
@@ -5139,10 +5219,12 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<target>Alle Statistiken zurücksetzen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics?" xml:space="preserve">
|
||||
<source>Reset all statistics?</source>
|
||||
<target>Alle Statistiken zurücksetzen?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset colors" xml:space="preserve">
|
||||
@@ -5152,6 +5234,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset to app theme" xml:space="preserve">
|
||||
<source>Reset to app theme</source>
|
||||
<target>Auf das App-Design zurücksetzen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset to defaults" xml:space="preserve">
|
||||
@@ -5161,6 +5244,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset to user theme" xml:space="preserve">
|
||||
<source>Reset to user theme</source>
|
||||
<target>Auf das Benutzer-spezifische Design zurücksetzen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Restart the app to create a new chat profile" xml:space="preserve">
|
||||
@@ -5235,6 +5319,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="SMP server" xml:space="preserve">
|
||||
<source>SMP server</source>
|
||||
<target>SMP-Server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SMP servers" xml:space="preserve">
|
||||
@@ -5354,10 +5439,12 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Scale" xml:space="preserve">
|
||||
<source>Scale</source>
|
||||
<target>Skalieren</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Scan / Paste link" xml:space="preserve">
|
||||
<source>Scan / Paste link</source>
|
||||
<target>Link scannen / einfügen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Scan QR code" xml:space="preserve">
|
||||
@@ -5402,6 +5489,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Secondary" xml:space="preserve">
|
||||
<source>Secondary</source>
|
||||
<target>Zweite Farbe</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Secure queue" xml:space="preserve">
|
||||
@@ -5411,6 +5499,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Secured" xml:space="preserve">
|
||||
<source>Secured</source>
|
||||
<target>Abgesichert</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Security assessment" xml:space="preserve">
|
||||
@@ -5430,6 +5519,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected chat preferences prohibit this message." xml:space="preserve">
|
||||
<source>Selected chat preferences prohibit this message.</source>
|
||||
<target>Diese Nachricht ist wegen der gewählten Chat-Einstellungen nicht erlaubt.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Self-destruct" xml:space="preserve">
|
||||
@@ -5484,6 +5574,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send errors" xml:space="preserve">
|
||||
<source>Send errors</source>
|
||||
<target>Fehler beim Senden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send link previews" xml:space="preserve">
|
||||
@@ -5598,6 +5689,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent directly" xml:space="preserve">
|
||||
<source>Sent directly</source>
|
||||
<target>Direkt gesendet</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent file event" xml:space="preserve">
|
||||
@@ -5612,6 +5704,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent messages" xml:space="preserve">
|
||||
<source>Sent messages</source>
|
||||
<target>Gesendete Nachrichten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent messages will be deleted after set time." xml:space="preserve">
|
||||
@@ -5621,18 +5714,22 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent reply" xml:space="preserve">
|
||||
<source>Sent reply</source>
|
||||
<target>Gesendete Antwort</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent total" xml:space="preserve">
|
||||
<source>Sent total</source>
|
||||
<target>Summe aller gesendeten Nachrichten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent via proxy" xml:space="preserve">
|
||||
<source>Sent via proxy</source>
|
||||
<target>Über einen Proxy gesendet</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>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings." xml:space="preserve">
|
||||
@@ -5661,6 +5758,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server type" xml:space="preserve">
|
||||
<source>Server type</source>
|
||||
<target>Server-Typ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings." xml:space="preserve">
|
||||
@@ -5668,6 +5766,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<target>Die Server-Version ist nicht mit den Netzwerk-Einstellungen kompatibel.</target>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5679,10 +5781,12 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers info" xml:space="preserve">
|
||||
<source>Servers info</source>
|
||||
<target>Server-Informationen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers statistics will be reset - this cannot be undone!" xml:space="preserve">
|
||||
<source>Servers statistics will be reset - this cannot be undone!</source>
|
||||
<target>Die Serverstatistiken werden zurückgesetzt. Dies kann nicht rückgängig gemacht werden!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Session code" xml:space="preserve">
|
||||
@@ -5702,6 +5806,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Set default theme" xml:space="preserve">
|
||||
<source>Set default theme</source>
|
||||
<target>Default-Design einstellen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Set group preferences" xml:space="preserve">
|
||||
@@ -5809,6 +5914,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<target>Nachrichtenstatus anzeigen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Vorschau anzeigen</target>
|
||||
@@ -5826,6 +5935,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX" xml:space="preserve">
|
||||
<source>SimpleX</source>
|
||||
<target>SimpleX</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX Address" xml:space="preserve">
|
||||
@@ -5905,6 +6015,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Size" xml:space="preserve">
|
||||
<source>Size</source>
|
||||
<target>Größe</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Skip" xml:space="preserve">
|
||||
@@ -5954,10 +6065,12 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Starting from %@." xml:space="preserve">
|
||||
<source>Starting from %@.</source>
|
||||
<target>Beginnend mit %@.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Statistics" xml:space="preserve">
|
||||
<source>Statistics</source>
|
||||
<target>Statistiken</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Stop" xml:space="preserve">
|
||||
@@ -6027,18 +6140,17 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscribed" xml:space="preserve">
|
||||
<source>Subscribed</source>
|
||||
<target>Abonniert</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription errors" xml:space="preserve">
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<target>Fehler beim Abonnieren</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<target>Nicht beachtete Abonnements</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Support SimpleX Chat" xml:space="preserve">
|
||||
@@ -6123,6 +6235,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Temporary file error" xml:space="preserve">
|
||||
<source>Temporary file error</source>
|
||||
<target>Temporärer Datei-Fehler</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Test failed at step %@." xml:space="preserve">
|
||||
@@ -6264,6 +6377,7 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro
|
||||
</trans-unit>
|
||||
<trans-unit id="Themes" xml:space="preserve">
|
||||
<source>Themes</source>
|
||||
<target>Design</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="These settings are for your current profile **%@**." xml:space="preserve">
|
||||
@@ -6333,6 +6447,7 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro
|
||||
</trans-unit>
|
||||
<trans-unit id="This link was used with another mobile device, please create a new link on the desktop." xml:space="preserve">
|
||||
<source>This link was used with another mobile device, please create a new link on the desktop.</source>
|
||||
<target>Dieser Link wurde schon mit einem anderen Mobiltelefon genutzt. Bitte erstellen sie einen neuen Link in der Desktop-App.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="This setting applies to messages in your current chat profile **%@**." xml:space="preserve">
|
||||
@@ -6342,6 +6457,7 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro
|
||||
</trans-unit>
|
||||
<trans-unit id="Title" xml:space="preserve">
|
||||
<source>Title</source>
|
||||
<target>Bezeichnung</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To ask any questions and to receive updates:" xml:space="preserve">
|
||||
@@ -6413,6 +6529,7 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<target>Summe aller Abonnements</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Transport isolation" xml:space="preserve">
|
||||
@@ -6422,6 +6539,7 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt
|
||||
</trans-unit>
|
||||
<trans-unit id="Transport sessions" xml:space="preserve">
|
||||
<source>Transport sessions</source>
|
||||
<target>Transport-Sitzungen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Trying to connect to the server used to receive messages from this contact (error: %@)." xml:space="preserve">
|
||||
@@ -6618,6 +6736,7 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
|
||||
</trans-unit>
|
||||
<trans-unit id="Upload errors" xml:space="preserve">
|
||||
<source>Upload errors</source>
|
||||
<target>Fehler beim Hochladen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Upload failed" xml:space="preserve">
|
||||
@@ -6632,10 +6751,12 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
|
||||
</trans-unit>
|
||||
<trans-unit id="Uploaded" xml:space="preserve">
|
||||
<source>Uploaded</source>
|
||||
<target>Hochgeladen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Uploaded files" xml:space="preserve">
|
||||
<source>Uploaded files</source>
|
||||
<target>Hochgeladene Dateien</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Uploading archive" xml:space="preserve">
|
||||
@@ -6715,6 +6836,7 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>Benutzer-Auswahl</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Using .onion hosts requires compatible VPN provider." xml:space="preserve">
|
||||
@@ -6854,10 +6976,12 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
|
||||
</trans-unit>
|
||||
<trans-unit id="Wallpaper accent" xml:space="preserve">
|
||||
<source>Wallpaper accent</source>
|
||||
<target>Wallpaper-Akzent</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Wallpaper background" xml:space="preserve">
|
||||
<source>Wallpaper background</source>
|
||||
<target>Wallpaper-Hintergrund</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Warning: starting chat on multiple devices is not supported and will cause message delivery failures" xml:space="preserve">
|
||||
@@ -6967,6 +7091,7 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
|
||||
</trans-unit>
|
||||
<trans-unit id="Wrong key or unknown file chunk address - most likely file is deleted." xml:space="preserve">
|
||||
<source>Wrong key or unknown file chunk address - most likely file is deleted.</source>
|
||||
<target>Falscher Schlüssel oder unbekannte Daten-Paketadresse der Datei - höchstwahrscheinlich wurde die Datei gelöscht.</target>
|
||||
<note>file error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Wrong passphrase!" xml:space="preserve">
|
||||
@@ -6976,6 +7101,7 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
|
||||
</trans-unit>
|
||||
<trans-unit id="XFTP server" xml:space="preserve">
|
||||
<source>XFTP server</source>
|
||||
<target>XFTP-Server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="XFTP servers" xml:space="preserve">
|
||||
@@ -7062,6 +7188,7 @@ Verbindungsanfrage wiederholen?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You are not connected to these servers. Private routing is used to deliver messages to them." xml:space="preserve">
|
||||
<source>You are not connected to these servers. Private routing is used to deliver messages to them.</source>
|
||||
<target>Sie sind nicht mit diesen Servern verbunden. Zur Auslieferung von Nachrichten an diese Server wird privates Routing genutzt.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can accept calls from lock screen, without device and app authentication." xml:space="preserve">
|
||||
@@ -7099,8 +7226,8 @@ Verbindungsanfrage wiederholen?</target>
|
||||
<target>Sie können sie über Einstellungen für Ihre SimpleX-Kontakte sichtbar machen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Sie können nun Nachrichten an %@ versenden</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7472,6 +7599,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="attempts" xml:space="preserve">
|
||||
<source>attempts</source>
|
||||
<target>Versuche</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="audio call (not e2e encrypted)" xml:space="preserve">
|
||||
@@ -7507,7 +7635,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>wurde vom Administrator blockiert</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
@@ -7666,6 +7794,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="decryption errors" xml:space="preserve">
|
||||
<source>decryption errors</source>
|
||||
<target>Entschlüsselungs-Fehler</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="default (%@)" xml:space="preserve">
|
||||
@@ -7720,6 +7849,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="duplicates" xml:space="preserve">
|
||||
<source>duplicates</source>
|
||||
<target>Duplikate</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="e2e encrypted" xml:space="preserve">
|
||||
@@ -7804,6 +7934,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="expired" xml:space="preserve">
|
||||
<source>expired</source>
|
||||
<target>abgelaufen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="forwarded" xml:space="preserve">
|
||||
@@ -7838,6 +7969,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<target>Inaktiv</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
@@ -8019,10 +8151,12 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="other" xml:space="preserve">
|
||||
<source>other</source>
|
||||
<target>andere</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="other errors" xml:space="preserve">
|
||||
<source>other errors</source>
|
||||
<target>Andere Fehler</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="owner" xml:space="preserve">
|
||||
@@ -8348,7 +8482,7 @@ Zuletzt empfangene Nachricht: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="NSCameraUsageDescription" xml:space="preserve">
|
||||
<source>SimpleX needs camera access to scan QR codes to connect to other users and for video calls.</source>
|
||||
<target>SimpleX benötigt Zugriff auf die Kamera, um QR Codes für die Verbindung mit anderen Nutzern zu scannen und Videoanrufe durchzuführen.</target>
|
||||
<target>SimpleX benötigt Zugriff auf die Kamera, um QR Codes für die Verbindung mit anderen Benutzern zu scannen und Videoanrufe durchzuführen.</target>
|
||||
<note>Privacy - Camera Usage Description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="NSFaceIDUsageDescription" xml:space="preserve">
|
||||
|
||||
@@ -718,9 +718,9 @@
|
||||
<target>All new messages from %@ will be hidden!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<target>All users</target>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<target>All profiles</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1738,9 +1738,9 @@ This is your own one-time link!</target>
|
||||
<target>Current passphrase…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<target>Current user</target>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<target>Current profile</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5773,6 +5773,11 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>Server version is incompatible with network settings.</target>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<target>Server version is incompatible with network settings: %@.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<target>Server version is incompatible with your app: %@.</target>
|
||||
@@ -5918,6 +5923,11 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>Show message status</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<target>Show percentage</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Show preview</target>
|
||||
@@ -6148,11 +6158,6 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>Subscription errors</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<target>Subscription percentage</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<target>Subscriptions ignored</target>
|
||||
@@ -7231,9 +7236,9 @@ Repeat join request?</target>
|
||||
<target>You can make it visible to your SimpleX contacts via Settings.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<target>You can now send messages to %@</target>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>You can now chat with %@</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can set lock screen notification preview via settings." xml:space="preserve">
|
||||
@@ -7640,7 +7645,7 @@ SimpleX servers cannot see your profile.</target>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>blocked by admin</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -709,8 +709,8 @@
|
||||
<target>¡Los mensajes nuevos de %@ estarán ocultos!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1709,8 +1709,8 @@ This is your own one-time link!</source>
|
||||
<target>Contraseña actual…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5668,6 +5668,10 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
<target>La versión del servidor es incompatible con la configuración de red.</target>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5809,6 +5813,10 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
<target>Estado del mensaje</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Mostrar vista previa</target>
|
||||
@@ -6033,10 +6041,6 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -7099,8 +7103,8 @@ Repeat join request?</source>
|
||||
<target>Puedes hacerlo visible para tus contactos de SimpleX en Configuración.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Ya puedes enviar mensajes a %@</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7507,7 +7511,7 @@ Los servidores SimpleX no pueden ver tu perfil.</target>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>bloqueado por administrador</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -682,8 +682,8 @@
|
||||
<source>All new messages from %@ will be hidden!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1628,8 +1628,8 @@ This is your own one-time link!</source>
|
||||
<target>Nykyinen tunnuslause…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5424,6 +5424,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server version is incompatible with network settings.</source>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5559,6 +5563,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Show message status</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Näytä esikatselu</target>
|
||||
@@ -5775,10 +5783,6 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6778,8 +6782,8 @@ Repeat join request?</source>
|
||||
<source>You can make it visible to your SimpleX contacts via Settings.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Voit nyt lähettää viestejä %@:lle</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7172,7 +7176,7 @@ SimpleX-palvelimet eivät näe profiiliasi.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -709,8 +709,8 @@
|
||||
<target>Tous les nouveaux messages de %@ seront cachés !</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1709,8 +1709,8 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<target>Phrase secrète actuelle…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5668,6 +5668,10 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>La version du serveur est incompatible avec les paramètres du réseau.</target>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5809,6 +5813,10 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>Afficher le statut du message</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Afficher l'aperçu</target>
|
||||
@@ -6033,10 +6041,6 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -7099,8 +7103,8 @@ Répéter la demande d'adhésion ?</target>
|
||||
<target>Vous pouvez le rendre visible à vos contacts SimpleX via Paramètres.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Vous pouvez maintenant envoyer des messages à %@</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7507,7 +7511,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>bloqué par l'administrateur</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -554,6 +554,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Accent" xml:space="preserve">
|
||||
<source>Accent</source>
|
||||
<target>Kiemelés</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept" xml:space="preserve">
|
||||
@@ -579,10 +580,12 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
<target>Nyugtázva</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledgement errors" xml:space="preserve">
|
||||
<source>Acknowledgement errors</source>
|
||||
<target>Nyugtázott hibák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
@@ -631,14 +634,17 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Additional accent" xml:space="preserve">
|
||||
<source>Additional accent</source>
|
||||
<target>További kiemelés</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Additional accent 2" xml:space="preserve">
|
||||
<source>Additional accent 2</source>
|
||||
<target>További kiemelés 2</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Additional secondary" xml:space="preserve">
|
||||
<source>Additional secondary</source>
|
||||
<target>További másodlagos</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Address" xml:space="preserve">
|
||||
@@ -668,6 +674,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Advanced settings" xml:space="preserve">
|
||||
<source>Advanced settings</source>
|
||||
<target>Haladó beállítások</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All app data is deleted." xml:space="preserve">
|
||||
@@ -687,6 +694,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="All data is private to your device." xml:space="preserve">
|
||||
<source>All data is private to your device.</source>
|
||||
<target>Minden adat biztonságban van a készülékén.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All group members will remain connected." xml:space="preserve">
|
||||
@@ -709,8 +717,9 @@
|
||||
<target>Minden új üzenet elrejtésre kerül tőle: %@!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<target>Minden profil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -915,6 +924,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Apply to" xml:space="preserve">
|
||||
<source>Apply to</source>
|
||||
<target>Alkalmazás erre</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive and upload" xml:space="preserve">
|
||||
@@ -994,6 +1004,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Background" xml:space="preserve">
|
||||
<source>Background</source>
|
||||
<target>Háttér</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Bad desktop address" xml:space="preserve">
|
||||
@@ -1023,6 +1034,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Fekete</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block" xml:space="preserve">
|
||||
@@ -1137,6 +1149,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Cannot forward message" xml:space="preserve">
|
||||
<source>Cannot forward message</source>
|
||||
<target>Nem lehet továbbítani az üzenetet</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cannot receive file" xml:space="preserve">
|
||||
@@ -1212,6 +1225,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat colors" xml:space="preserve">
|
||||
<source>Chat colors</source>
|
||||
<target>Csevegés színei</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat console" xml:space="preserve">
|
||||
@@ -1261,6 +1275,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Csevegés témája</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chats" xml:space="preserve">
|
||||
@@ -1295,14 +1310,17 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chunks deleted" xml:space="preserve">
|
||||
<source>Chunks deleted</source>
|
||||
<target>Törölt fájltöredékek</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chunks downloaded" xml:space="preserve">
|
||||
<source>Chunks downloaded</source>
|
||||
<target>Letöltött fájltöredékek</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chunks uploaded" xml:space="preserve">
|
||||
<source>Chunks uploaded</source>
|
||||
<target>Feltöltött fájltöredékek</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
@@ -1332,6 +1350,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<target>Színmód</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Compare file" xml:space="preserve">
|
||||
@@ -1346,6 +1365,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Completed" xml:space="preserve">
|
||||
<source>Completed</source>
|
||||
<target>Elkészült</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configure ICE servers" xml:space="preserve">
|
||||
@@ -1463,6 +1483,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected" xml:space="preserve">
|
||||
<source>Connected</source>
|
||||
<target>Kapcsolódva</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected desktop" xml:space="preserve">
|
||||
@@ -1472,6 +1493,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected servers" xml:space="preserve">
|
||||
<source>Connected servers</source>
|
||||
<target>Kapcsolódott kiszolgálók</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected to desktop" xml:space="preserve">
|
||||
@@ -1481,6 +1503,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting" xml:space="preserve">
|
||||
<source>Connecting</source>
|
||||
<target>Kapcsolódás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting server…" xml:space="preserve">
|
||||
@@ -1530,10 +1553,12 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection with desktop stopped" xml:space="preserve">
|
||||
<source>Connection with desktop stopped</source>
|
||||
<target>A kapcsolat a számítógéppel megszakadt</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections" xml:space="preserve">
|
||||
<source>Connections</source>
|
||||
<target>Kapcsolatok</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
@@ -1593,6 +1618,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy error" xml:space="preserve">
|
||||
<source>Copy error</source>
|
||||
<target>Másolási hiba</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Core version: v%@" xml:space="preserve">
|
||||
@@ -1672,6 +1698,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Created" xml:space="preserve">
|
||||
<source>Created</source>
|
||||
<target>Létrehozva</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Created at" xml:space="preserve">
|
||||
@@ -1709,8 +1736,9 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
<target>Jelenlegi jelmondat…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<target>Jelenlegi profil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -1725,6 +1753,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Téma személyre szabása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Dark" xml:space="preserve">
|
||||
@@ -1734,6 +1763,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Dark mode colors" xml:space="preserve">
|
||||
<source>Dark mode colors</source>
|
||||
<target>Sötét mód színei</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Database ID" xml:space="preserve">
|
||||
@@ -2043,6 +2073,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted" xml:space="preserve">
|
||||
<source>Deleted</source>
|
||||
<target>Törölve</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted at" xml:space="preserve">
|
||||
@@ -2057,6 +2088,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<target>Törlési hibák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delivery" xml:space="preserve">
|
||||
@@ -2101,10 +2133,12 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Detailed statistics" xml:space="preserve">
|
||||
<source>Detailed statistics</source>
|
||||
<target>Részletes statisztikák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Details" xml:space="preserve">
|
||||
<source>Details</source>
|
||||
<target>Részletek</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Develop" xml:space="preserve">
|
||||
@@ -2264,6 +2298,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Download errors" xml:space="preserve">
|
||||
<source>Download errors</source>
|
||||
<target>Letöltési hibák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Download failed" xml:space="preserve">
|
||||
@@ -2278,10 +2313,12 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Downloaded" xml:space="preserve">
|
||||
<source>Downloaded</source>
|
||||
<target>Letöltve</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Downloaded files" xml:space="preserve">
|
||||
<source>Downloaded files</source>
|
||||
<target>Letöltött fájlok</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Downloading archive" xml:space="preserve">
|
||||
@@ -2656,6 +2693,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error exporting theme: %@" xml:space="preserve">
|
||||
<source>Error exporting theme: %@</source>
|
||||
<target>Hiba a téma exportálásakor: %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error importing chat database" xml:space="preserve">
|
||||
@@ -2685,10 +2723,12 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error reconnecting server" xml:space="preserve">
|
||||
<source>Error reconnecting server</source>
|
||||
<target>Hiba a kiszolgálóhoz való újrakapcsolódáskor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error reconnecting servers" xml:space="preserve">
|
||||
<source>Error reconnecting servers</source>
|
||||
<target>Hiba a kiszolgálókhoz való újrakapcsolódáskor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error removing member" xml:space="preserve">
|
||||
@@ -2698,6 +2738,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error resetting statistics" xml:space="preserve">
|
||||
<source>Error resetting statistics</source>
|
||||
<target>Hiba a statisztikák visszaállításakor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error saving %@ servers" xml:space="preserve">
|
||||
@@ -2833,6 +2874,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Errors" xml:space="preserve">
|
||||
<source>Errors</source>
|
||||
<target>Hibák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when disabled in the conversation." xml:space="preserve">
|
||||
@@ -2862,6 +2904,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Export theme" xml:space="preserve">
|
||||
<source>Export theme</source>
|
||||
<target>Téma exportálása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exported database archive." xml:space="preserve">
|
||||
@@ -2901,22 +2944,27 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
<target>Fájlhiba</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
|
||||
<source>File not found - most likely file was deleted or cancelled.</source>
|
||||
<target>A fájl nem található - valószínűleg a fájlt törölték vagy visszavonták.</target>
|
||||
<note>file error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File server error: %@" xml:space="preserve">
|
||||
<source>File server error: %@</source>
|
||||
<target>Fájlkiszolgáló hiba: %@</target>
|
||||
<note>file error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File status" xml:space="preserve">
|
||||
<source>File status</source>
|
||||
<target>Fájlállapot</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File status: %@" xml:space="preserve">
|
||||
<source>File status: %@</source>
|
||||
<target>Fájlállapot: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File will be deleted from servers." xml:space="preserve">
|
||||
@@ -3110,10 +3158,12 @@ Hiba: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Good afternoon!" xml:space="preserve">
|
||||
<source>Good afternoon!</source>
|
||||
<target>Jó napot!</target>
|
||||
<note>message preview</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Good morning!" xml:space="preserve">
|
||||
<source>Good morning!</source>
|
||||
<target>Jó reggelt!</target>
|
||||
<note>message preview</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Group" xml:space="preserve">
|
||||
@@ -3398,6 +3448,7 @@ Hiba: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Import theme" xml:space="preserve">
|
||||
<source>Import theme</source>
|
||||
<target>Téma importálása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Importing archive" xml:space="preserve">
|
||||
@@ -3524,6 +3575,7 @@ Hiba: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Interface colors" xml:space="preserve">
|
||||
<source>Interface colors</source>
|
||||
<target>Kezelőfelület színei</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Invalid QR code" xml:space="preserve">
|
||||
@@ -3871,6 +3923,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<target>Inaktív tag</target>
|
||||
<note>item status text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member role will be changed to "%@". All group members will be notified." xml:space="preserve">
|
||||
@@ -3890,6 +3943,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Menus" xml:space="preserve">
|
||||
<source>Menus</source>
|
||||
<target>Menük</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message delivery error" xml:space="preserve">
|
||||
@@ -3914,10 +3968,12 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<target>Továbbított üzenet</target>
|
||||
<note>item status text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message may be delivered later if member becomes active." xml:space="preserve">
|
||||
<source>Message may be delivered later if member becomes active.</source>
|
||||
<target>Az üzenet később is kézbesíthető, ha a tag aktívvá válik.</target>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
@@ -3961,10 +4017,12 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message status" xml:space="preserve">
|
||||
<source>Message status</source>
|
||||
<target>Üzenetállapot</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message status: %@" xml:space="preserve">
|
||||
<source>Message status: %@</source>
|
||||
<target>Üzenetállapot: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
@@ -3994,10 +4052,12 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages received" xml:space="preserve">
|
||||
<source>Messages received</source>
|
||||
<target>Fogadott üzenetek</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages sent" xml:space="preserve">
|
||||
<source>Messages sent</source>
|
||||
<target>Elküldött üzenetek</target>
|
||||
<note>No comment provided by engineer.</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">
|
||||
@@ -4237,6 +4297,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="No direct connection yet, message is forwarded by admin." xml:space="preserve">
|
||||
<source>No direct connection yet, message is forwarded by admin.</source>
|
||||
<target>Még nincs közvetlen kapcsolat, az üzenetet az admin továbbítja.</target>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
@@ -4256,6 +4317,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="No info, try to reload" xml:space="preserve">
|
||||
<source>No info, try to reload</source>
|
||||
<target>Nincs információ, próbálja meg újratölteni</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No network connection" xml:space="preserve">
|
||||
@@ -4444,6 +4506,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Open server settings" xml:space="preserve">
|
||||
<source>Open server settings</source>
|
||||
<target>Kiszolgáló beállításainak megnyitása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Open user profiles" xml:space="preserve">
|
||||
@@ -4557,6 +4620,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Pending" xml:space="preserve">
|
||||
<source>Pending</source>
|
||||
<target>Függő</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="People can connect to you only via the links you share." xml:space="preserve">
|
||||
@@ -4587,6 +4651,8 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
<trans-unit id="Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. Please share any other issues with the developers." xml:space="preserve">
|
||||
<source>Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection.
|
||||
Please share any other issues with the developers.</source>
|
||||
<target>Ellenőrizze, hogy a mobil és az asztali számítógép ugyanahhoz a helyi hálózathoz csatlakozik-e, valamint az asztali számítógép tűzfalában engedélyezve van-e a kapcsolat.
|
||||
Minden további problémát osszon meg a fejlesztőkkel.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please check that you used the correct link or ask your contact to send you another one." xml:space="preserve">
|
||||
@@ -4692,6 +4758,7 @@ Hiba: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Previously connected servers" xml:space="preserve">
|
||||
<source>Previously connected servers</source>
|
||||
<target>Korábban kapcsolódott kiszolgálók</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Privacy & security" xml:space="preserve">
|
||||
@@ -4765,6 +4832,7 @@ Hiba: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile theme" xml:space="preserve">
|
||||
<source>Profile theme</source>
|
||||
<target>Profiltéma</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile update will be sent to your contacts." xml:space="preserve">
|
||||
@@ -4851,10 +4919,12 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Proxied" xml:space="preserve">
|
||||
<source>Proxied</source>
|
||||
<target>Proxyzott</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proxied servers" xml:space="preserve">
|
||||
<source>Proxied servers</source>
|
||||
<target>Proxyzott kiszolgálók</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
@@ -4924,6 +4994,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Receive errors" xml:space="preserve">
|
||||
<source>Receive errors</source>
|
||||
<target>Üzenetfogadási hibák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Received at" xml:space="preserve">
|
||||
@@ -4948,14 +5019,17 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Received messages" xml:space="preserve">
|
||||
<source>Received messages</source>
|
||||
<target>Fogadott üzenetek</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Received reply" xml:space="preserve">
|
||||
<source>Received reply</source>
|
||||
<target>Fogadott válasz</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Received total" xml:space="preserve">
|
||||
<source>Received total</source>
|
||||
<target>Összes fogadott</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Receiving address will be changed to a different server. Address change will complete after sender comes online." xml:space="preserve">
|
||||
@@ -4990,6 +5064,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect" xml:space="preserve">
|
||||
<source>Reconnect</source>
|
||||
<target>Újrakapcsolás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect all connected servers to force message delivery. It uses additional traffic." xml:space="preserve">
|
||||
@@ -4999,18 +5074,22 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect all servers" xml:space="preserve">
|
||||
<source>Reconnect all servers</source>
|
||||
<target>Újrakapcsolódás minden kiszolgálóhoz</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect all servers?" xml:space="preserve">
|
||||
<source>Reconnect all servers?</source>
|
||||
<target>Újrakapcsolódás minden kiszolgálóhoz?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect server to force message delivery. It uses additional traffic." xml:space="preserve">
|
||||
<source>Reconnect server to force message delivery. It uses additional traffic.</source>
|
||||
<target>A kiszolgálóhoz való újrakapcsolódás az üzenet kézbesítésének kikényszerítéséhez. Ez további adatforgalmat használ.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect server?" xml:space="preserve">
|
||||
<source>Reconnect server?</source>
|
||||
<target>Újrakapcsolódás a kiszolgálóhoz?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect servers?" xml:space="preserve">
|
||||
@@ -5065,6 +5144,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove image" xml:space="preserve">
|
||||
<source>Remove image</source>
|
||||
<target>Kép eltávolítása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove member" xml:space="preserve">
|
||||
@@ -5139,10 +5219,12 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<target>Minden statisztika visszaállítása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics?" xml:space="preserve">
|
||||
<source>Reset all statistics?</source>
|
||||
<target>Minden statisztika visszaállítása?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset colors" xml:space="preserve">
|
||||
@@ -5152,6 +5234,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset to app theme" xml:space="preserve">
|
||||
<source>Reset to app theme</source>
|
||||
<target>Alkalmazás témájának visszaállítása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset to defaults" xml:space="preserve">
|
||||
@@ -5161,6 +5244,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset to user theme" xml:space="preserve">
|
||||
<source>Reset to user theme</source>
|
||||
<target>Felhasználó által létrehozott téma visszaállítása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Restart the app to create a new chat profile" xml:space="preserve">
|
||||
@@ -5235,6 +5319,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="SMP server" xml:space="preserve">
|
||||
<source>SMP server</source>
|
||||
<target>SMP-kiszolgáló</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SMP servers" xml:space="preserve">
|
||||
@@ -5354,10 +5439,12 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Scale" xml:space="preserve">
|
||||
<source>Scale</source>
|
||||
<target>Méretezés</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Scan / Paste link" xml:space="preserve">
|
||||
<source>Scan / Paste link</source>
|
||||
<target>Hivatkozás beolvasása / beillesztése</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Scan QR code" xml:space="preserve">
|
||||
@@ -5402,6 +5489,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Secondary" xml:space="preserve">
|
||||
<source>Secondary</source>
|
||||
<target>Másodlagos</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Secure queue" xml:space="preserve">
|
||||
@@ -5411,6 +5499,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Secured" xml:space="preserve">
|
||||
<source>Secured</source>
|
||||
<target>Biztosítva</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Security assessment" xml:space="preserve">
|
||||
@@ -5430,6 +5519,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected chat preferences prohibit this message." xml:space="preserve">
|
||||
<source>Selected chat preferences prohibit this message.</source>
|
||||
<target>A kiválasztott csevegési beállítások tiltják ezt az üzenetet.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Self-destruct" xml:space="preserve">
|
||||
@@ -5484,6 +5574,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Send errors" xml:space="preserve">
|
||||
<source>Send errors</source>
|
||||
<target>Üzenetküldési hibák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send link previews" xml:space="preserve">
|
||||
@@ -5598,6 +5689,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent directly" xml:space="preserve">
|
||||
<source>Sent directly</source>
|
||||
<target>Közvetlenül küldött</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent file event" xml:space="preserve">
|
||||
@@ -5612,6 +5704,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent messages" xml:space="preserve">
|
||||
<source>Sent messages</source>
|
||||
<target>Elküldött üzenetek</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent messages will be deleted after set time." xml:space="preserve">
|
||||
@@ -5621,18 +5714,22 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent reply" xml:space="preserve">
|
||||
<source>Sent reply</source>
|
||||
<target>Elküldött válasz</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent total" xml:space="preserve">
|
||||
<source>Sent total</source>
|
||||
<target>Összes elküldött</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent via proxy" xml:space="preserve">
|
||||
<source>Sent via proxy</source>
|
||||
<target>Proxyn keresztül küldve</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<target>Kiszolgáló címe</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings." xml:space="preserve">
|
||||
@@ -5661,6 +5758,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Server type" xml:space="preserve">
|
||||
<source>Server type</source>
|
||||
<target>Kiszolgáló típusa</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings." xml:space="preserve">
|
||||
@@ -5668,6 +5766,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
<target>A kiszolgáló verziója nem kompatibilis a hálózati beállításokkal.</target>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5679,10 +5781,12 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers info" xml:space="preserve">
|
||||
<source>Servers info</source>
|
||||
<target>információk a kiszolgálókról</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers statistics will be reset - this cannot be undone!" xml:space="preserve">
|
||||
<source>Servers statistics will be reset - this cannot be undone!</source>
|
||||
<target>A kiszolgálók statisztikái visszaállnak - ez nem vonható vissza!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Session code" xml:space="preserve">
|
||||
@@ -5702,6 +5806,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Set default theme" xml:space="preserve">
|
||||
<source>Set default theme</source>
|
||||
<target>Alapértelmezett téma beállítása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Set group preferences" xml:space="preserve">
|
||||
@@ -5809,6 +5914,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
<target>Üzenet állapot megjelenítése</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Előnézet megjelenítése</target>
|
||||
@@ -5826,6 +5935,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX" xml:space="preserve">
|
||||
<source>SimpleX</source>
|
||||
<target>SimpleX</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX Address" xml:space="preserve">
|
||||
@@ -5905,6 +6015,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Size" xml:space="preserve">
|
||||
<source>Size</source>
|
||||
<target>Méret</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Skip" xml:space="preserve">
|
||||
@@ -5954,10 +6065,12 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Starting from %@." xml:space="preserve">
|
||||
<source>Starting from %@.</source>
|
||||
<target>Kezdve ettől %@.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Statistics" xml:space="preserve">
|
||||
<source>Statistics</source>
|
||||
<target>Statisztikák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Stop" xml:space="preserve">
|
||||
@@ -6027,18 +6140,17 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscribed" xml:space="preserve">
|
||||
<source>Subscribed</source>
|
||||
<target>Feliratkozva</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription errors" xml:space="preserve">
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<target>Feliratkozási hibák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<target>Elutasított feliratkozások</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Support SimpleX Chat" xml:space="preserve">
|
||||
@@ -6123,6 +6235,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Temporary file error" xml:space="preserve">
|
||||
<source>Temporary file error</source>
|
||||
<target>Ideiglenes fájlhiba</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Test failed at step %@." xml:space="preserve">
|
||||
@@ -6264,6 +6377,7 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Themes" xml:space="preserve">
|
||||
<source>Themes</source>
|
||||
<target>Témák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="These settings are for your current profile **%@**." xml:space="preserve">
|
||||
@@ -6333,6 +6447,7 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="This link was used with another mobile device, please create a new link on the desktop." xml:space="preserve">
|
||||
<source>This link was used with another mobile device, please create a new link on the desktop.</source>
|
||||
<target>Ezt a hivatkozást egy másik mobilleszközön már használták, hozzon létre egy új hivatkozást az asztali számítógépén.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="This setting applies to messages in your current chat profile **%@**." xml:space="preserve">
|
||||
@@ -6342,6 +6457,7 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Title" xml:space="preserve">
|
||||
<source>Title</source>
|
||||
<target>Cím</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To ask any questions and to receive updates:" xml:space="preserve">
|
||||
@@ -6413,6 +6529,7 @@ A funkció engedélyezése előtt a rendszer felszólítja a hitelesítés befej
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<target>Összesen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Transport isolation" xml:space="preserve">
|
||||
@@ -6422,6 +6539,7 @@ A funkció engedélyezése előtt a rendszer felszólítja a hitelesítés befej
|
||||
</trans-unit>
|
||||
<trans-unit id="Transport sessions" xml:space="preserve">
|
||||
<source>Transport sessions</source>
|
||||
<target>Munkamenetek átvitele</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Trying to connect to the server used to receive messages from this contact (error: %@)." xml:space="preserve">
|
||||
@@ -6618,6 +6736,7 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol
|
||||
</trans-unit>
|
||||
<trans-unit id="Upload errors" xml:space="preserve">
|
||||
<source>Upload errors</source>
|
||||
<target>Feltöltési hibák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Upload failed" xml:space="preserve">
|
||||
@@ -6632,10 +6751,12 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol
|
||||
</trans-unit>
|
||||
<trans-unit id="Uploaded" xml:space="preserve">
|
||||
<source>Uploaded</source>
|
||||
<target>Feltöltve</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Uploaded files" xml:space="preserve">
|
||||
<source>Uploaded files</source>
|
||||
<target>Feltöltött fájlok</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Uploading archive" xml:space="preserve">
|
||||
@@ -6715,6 +6836,7 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>Felhasználó kiválasztása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Using .onion hosts requires compatible VPN provider." xml:space="preserve">
|
||||
@@ -6854,10 +6976,12 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol
|
||||
</trans-unit>
|
||||
<trans-unit id="Wallpaper accent" xml:space="preserve">
|
||||
<source>Wallpaper accent</source>
|
||||
<target>Háttérkép kiemelés</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Wallpaper background" xml:space="preserve">
|
||||
<source>Wallpaper background</source>
|
||||
<target>Háttérkép háttérszíne</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Warning: starting chat on multiple devices is not supported and will cause message delivery failures" xml:space="preserve">
|
||||
@@ -6967,6 +7091,7 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol
|
||||
</trans-unit>
|
||||
<trans-unit id="Wrong key or unknown file chunk address - most likely file is deleted." xml:space="preserve">
|
||||
<source>Wrong key or unknown file chunk address - most likely file is deleted.</source>
|
||||
<target>Hibás kulcs vagy ismeretlen fájltöredék cím - valószínűleg a fájl törlődött.</target>
|
||||
<note>file error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Wrong passphrase!" xml:space="preserve">
|
||||
@@ -6976,6 +7101,7 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol
|
||||
</trans-unit>
|
||||
<trans-unit id="XFTP server" xml:space="preserve">
|
||||
<source>XFTP server</source>
|
||||
<target>XFTP-kiszolgáló</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="XFTP servers" xml:space="preserve">
|
||||
@@ -7062,6 +7188,7 @@ Csatlakozási kérés megismétlése?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You are not connected to these servers. Private routing is used to deliver messages to them." xml:space="preserve">
|
||||
<source>You are not connected to these servers. Private routing is used to deliver messages to them.</source>
|
||||
<target>Ön nem kapcsolódik ezekhez a kiszolgálókhoz. A privát útválasztás az üzenetek kézbesítésére szolgál.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can accept calls from lock screen, without device and app authentication." xml:space="preserve">
|
||||
@@ -7099,8 +7226,8 @@ Csatlakozási kérés megismétlése?</target>
|
||||
<target>Láthatóvá teheti SimpleX ismerősök számára a Beállításokban.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Mostantól küldhet üzeneteket %@ számára</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7472,6 +7599,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="attempts" xml:space="preserve">
|
||||
<source>attempts</source>
|
||||
<target>próbálkozások</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="audio call (not e2e encrypted)" xml:space="preserve">
|
||||
@@ -7507,7 +7635,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>letiltva az admin által</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
@@ -7666,6 +7794,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="decryption errors" xml:space="preserve">
|
||||
<source>decryption errors</source>
|
||||
<target>visszafejtési hibák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="default (%@)" xml:space="preserve">
|
||||
@@ -7720,6 +7849,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="duplicates" xml:space="preserve">
|
||||
<source>duplicates</source>
|
||||
<target>duplikációk</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="e2e encrypted" xml:space="preserve">
|
||||
@@ -7804,6 +7934,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="expired" xml:space="preserve">
|
||||
<source>expired</source>
|
||||
<target>lejárt</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="forwarded" xml:space="preserve">
|
||||
@@ -7838,6 +7969,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<target>inaktív</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
@@ -8019,10 +8151,12 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="other" xml:space="preserve">
|
||||
<source>other</source>
|
||||
<target>egyéb</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="other errors" xml:space="preserve">
|
||||
<source>other errors</source>
|
||||
<target>egyéb hibák</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="owner" xml:space="preserve">
|
||||
|
||||
@@ -554,6 +554,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Accent" xml:space="preserve">
|
||||
<source>Accent</source>
|
||||
<target>Principale</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept" xml:space="preserve">
|
||||
@@ -579,10 +580,12 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
<target>Riconosciuto</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledgement errors" xml:space="preserve">
|
||||
<source>Acknowledgement errors</source>
|
||||
<target>Errori di riconoscimento</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
@@ -631,14 +634,17 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Additional accent" xml:space="preserve">
|
||||
<source>Additional accent</source>
|
||||
<target>Principale aggiuntivo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Additional accent 2" xml:space="preserve">
|
||||
<source>Additional accent 2</source>
|
||||
<target>Principale aggiuntivo 2</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Additional secondary" xml:space="preserve">
|
||||
<source>Additional secondary</source>
|
||||
<target>Secondario aggiuntivo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Address" xml:space="preserve">
|
||||
@@ -668,6 +674,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Advanced settings" xml:space="preserve">
|
||||
<source>Advanced settings</source>
|
||||
<target>Impostazioni avanzate</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All app data is deleted." xml:space="preserve">
|
||||
@@ -687,6 +694,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="All data is private to your device." xml:space="preserve">
|
||||
<source>All data is private to your device.</source>
|
||||
<target>Tutti i dati sono privati, nel tuo dispositivo.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All group members will remain connected." xml:space="preserve">
|
||||
@@ -709,8 +717,9 @@
|
||||
<target>Tutti i nuovi messaggi da %@ verrranno nascosti!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<target>Tutti gli profili</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -915,6 +924,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Apply to" xml:space="preserve">
|
||||
<source>Apply to</source>
|
||||
<target>Applica a</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive and upload" xml:space="preserve">
|
||||
@@ -994,6 +1004,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Background" xml:space="preserve">
|
||||
<source>Background</source>
|
||||
<target>Sfondo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Bad desktop address" xml:space="preserve">
|
||||
@@ -1023,6 +1034,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Nero</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block" xml:space="preserve">
|
||||
@@ -1137,6 +1149,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Cannot forward message" xml:space="preserve">
|
||||
<source>Cannot forward message</source>
|
||||
<target>Impossibile inoltrare il messaggio</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cannot receive file" xml:space="preserve">
|
||||
@@ -1212,6 +1225,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat colors" xml:space="preserve">
|
||||
<source>Chat colors</source>
|
||||
<target>Colori della chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat console" xml:space="preserve">
|
||||
@@ -1261,6 +1275,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Tema della chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chats" xml:space="preserve">
|
||||
@@ -1295,14 +1310,17 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chunks deleted" xml:space="preserve">
|
||||
<source>Chunks deleted</source>
|
||||
<target>Blocchi eliminati</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chunks downloaded" xml:space="preserve">
|
||||
<source>Chunks downloaded</source>
|
||||
<target>Blocchi scaricati</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chunks uploaded" xml:space="preserve">
|
||||
<source>Chunks uploaded</source>
|
||||
<target>Blocchi inviati</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
@@ -1332,6 +1350,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<target>Modalità di colore</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Compare file" xml:space="preserve">
|
||||
@@ -1346,6 +1365,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Completed" xml:space="preserve">
|
||||
<source>Completed</source>
|
||||
<target>Completato</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configure ICE servers" xml:space="preserve">
|
||||
@@ -1463,6 +1483,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected" xml:space="preserve">
|
||||
<source>Connected</source>
|
||||
<target>Connesso</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected desktop" xml:space="preserve">
|
||||
@@ -1472,6 +1493,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected servers" xml:space="preserve">
|
||||
<source>Connected servers</source>
|
||||
<target>Server connessi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connected to desktop" xml:space="preserve">
|
||||
@@ -1481,6 +1503,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting" xml:space="preserve">
|
||||
<source>Connecting</source>
|
||||
<target>In connessione</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting server…" xml:space="preserve">
|
||||
@@ -1530,10 +1553,12 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection with desktop stopped" xml:space="preserve">
|
||||
<source>Connection with desktop stopped</source>
|
||||
<target>Connessione con il desktop fermata</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections" xml:space="preserve">
|
||||
<source>Connections</source>
|
||||
<target>Connessioni</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
@@ -1593,6 +1618,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy error" xml:space="preserve">
|
||||
<source>Copy error</source>
|
||||
<target>Copia errore</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Core version: v%@" xml:space="preserve">
|
||||
@@ -1672,6 +1698,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Created" xml:space="preserve">
|
||||
<source>Created</source>
|
||||
<target>Creato</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Created at" xml:space="preserve">
|
||||
@@ -1709,8 +1736,9 @@ Questo è il tuo link una tantum!</target>
|
||||
<target>Password attuale…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<target>Profilo attuale</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -1725,6 +1753,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Personalizza il tema</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Dark" xml:space="preserve">
|
||||
@@ -1734,6 +1763,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Dark mode colors" xml:space="preserve">
|
||||
<source>Dark mode colors</source>
|
||||
<target>Colori modalità scura</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Database ID" xml:space="preserve">
|
||||
@@ -2043,6 +2073,7 @@ Non è reversibile!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted" xml:space="preserve">
|
||||
<source>Deleted</source>
|
||||
<target>Eliminato</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted at" xml:space="preserve">
|
||||
@@ -2057,6 +2088,7 @@ Non è reversibile!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<target>Errori di eliminazione</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delivery" xml:space="preserve">
|
||||
@@ -2101,10 +2133,12 @@ Non è reversibile!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Detailed statistics" xml:space="preserve">
|
||||
<source>Detailed statistics</source>
|
||||
<target>Statistiche dettagliate</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Details" xml:space="preserve">
|
||||
<source>Details</source>
|
||||
<target>Dettagli</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Develop" xml:space="preserve">
|
||||
@@ -2264,6 +2298,7 @@ Non è reversibile!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Download errors" xml:space="preserve">
|
||||
<source>Download errors</source>
|
||||
<target>Errori di scaricamento</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Download failed" xml:space="preserve">
|
||||
@@ -2278,10 +2313,12 @@ Non è reversibile!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Downloaded" xml:space="preserve">
|
||||
<source>Downloaded</source>
|
||||
<target>Scaricato</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Downloaded files" xml:space="preserve">
|
||||
<source>Downloaded files</source>
|
||||
<target>File scaricati</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Downloading archive" xml:space="preserve">
|
||||
@@ -2656,6 +2693,7 @@ Non è reversibile!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error exporting theme: %@" xml:space="preserve">
|
||||
<source>Error exporting theme: %@</source>
|
||||
<target>Errore di esportazione del tema: %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error importing chat database" xml:space="preserve">
|
||||
@@ -2685,10 +2723,12 @@ Non è reversibile!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error reconnecting server" xml:space="preserve">
|
||||
<source>Error reconnecting server</source>
|
||||
<target>Errore di riconnessione al server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error reconnecting servers" xml:space="preserve">
|
||||
<source>Error reconnecting servers</source>
|
||||
<target>Errore di riconnessione ai server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error removing member" xml:space="preserve">
|
||||
@@ -2698,6 +2738,7 @@ Non è reversibile!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error resetting statistics" xml:space="preserve">
|
||||
<source>Error resetting statistics</source>
|
||||
<target>Errore di azzeramento statistiche</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error saving %@ servers" xml:space="preserve">
|
||||
@@ -2833,6 +2874,7 @@ Non è reversibile!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Errors" xml:space="preserve">
|
||||
<source>Errors</source>
|
||||
<target>Errori</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when disabled in the conversation." xml:space="preserve">
|
||||
@@ -2862,6 +2904,7 @@ Non è reversibile!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Export theme" xml:space="preserve">
|
||||
<source>Export theme</source>
|
||||
<target>Esporta tema</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exported database archive." xml:space="preserve">
|
||||
@@ -2901,22 +2944,27 @@ Non è reversibile!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
<target>Errore del file</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
|
||||
<source>File not found - most likely file was deleted or cancelled.</source>
|
||||
<target>File non trovato - probabilmente è stato eliminato o annullato.</target>
|
||||
<note>file error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File server error: %@" xml:space="preserve">
|
||||
<source>File server error: %@</source>
|
||||
<target>Errore del server dei file: %@</target>
|
||||
<note>file error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File status" xml:space="preserve">
|
||||
<source>File status</source>
|
||||
<target>Stato del file</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File status: %@" xml:space="preserve">
|
||||
<source>File status: %@</source>
|
||||
<target>Stato del file: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File will be deleted from servers." xml:space="preserve">
|
||||
@@ -3110,10 +3158,12 @@ Errore: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Good afternoon!" xml:space="preserve">
|
||||
<source>Good afternoon!</source>
|
||||
<target>Buon pomeriggio!</target>
|
||||
<note>message preview</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Good morning!" xml:space="preserve">
|
||||
<source>Good morning!</source>
|
||||
<target>Buongiorno!</target>
|
||||
<note>message preview</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Group" xml:space="preserve">
|
||||
@@ -3398,6 +3448,7 @@ Errore: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Import theme" xml:space="preserve">
|
||||
<source>Import theme</source>
|
||||
<target>Importa tema</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Importing archive" xml:space="preserve">
|
||||
@@ -3524,6 +3575,7 @@ Errore: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Interface colors" xml:space="preserve">
|
||||
<source>Interface colors</source>
|
||||
<target>Colori dell'interfaccia</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Invalid QR code" xml:space="preserve">
|
||||
@@ -3871,6 +3923,7 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<target>Membro inattivo</target>
|
||||
<note>item status text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member role will be changed to "%@". All group members will be notified." xml:space="preserve">
|
||||
@@ -3890,6 +3943,7 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Menus" xml:space="preserve">
|
||||
<source>Menus</source>
|
||||
<target>Menu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message delivery error" xml:space="preserve">
|
||||
@@ -3914,10 +3968,12 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<target>Messaggio inoltrato</target>
|
||||
<note>item status text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message may be delivered later if member becomes active." xml:space="preserve">
|
||||
<source>Message may be delivered later if member becomes active.</source>
|
||||
<target>Il messaggio può essere consegnato più tardi se il membro diventa attivo.</target>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
@@ -3961,10 +4017,12 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message status" xml:space="preserve">
|
||||
<source>Message status</source>
|
||||
<target>Stato del messaggio</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message status: %@" xml:space="preserve">
|
||||
<source>Message status: %@</source>
|
||||
<target>Stato del messaggio: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
@@ -3994,10 +4052,12 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages received" xml:space="preserve">
|
||||
<source>Messages received</source>
|
||||
<target>Messaggi ricevuti</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages sent" xml:space="preserve">
|
||||
<source>Messages sent</source>
|
||||
<target>Messaggi inviati</target>
|
||||
<note>No comment provided by engineer.</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">
|
||||
@@ -4237,6 +4297,7 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="No direct connection yet, message is forwarded by admin." xml:space="preserve">
|
||||
<source>No direct connection yet, message is forwarded by admin.</source>
|
||||
<target>Ancora nessuna connessione diretta, il messaggio viene inoltrato dall'amministratore.</target>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
@@ -4256,6 +4317,7 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="No info, try to reload" xml:space="preserve">
|
||||
<source>No info, try to reload</source>
|
||||
<target>Nessuna informazione, prova a ricaricare</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No network connection" xml:space="preserve">
|
||||
@@ -4444,6 +4506,7 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Open server settings" xml:space="preserve">
|
||||
<source>Open server settings</source>
|
||||
<target>Apri impostazioni server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Open user profiles" xml:space="preserve">
|
||||
@@ -4557,6 +4620,7 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Pending" xml:space="preserve">
|
||||
<source>Pending</source>
|
||||
<target>In attesa</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="People can connect to you only via the links you share." xml:space="preserve">
|
||||
@@ -4587,6 +4651,8 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<trans-unit id="Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. Please share any other issues with the developers." xml:space="preserve">
|
||||
<source>Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection.
|
||||
Please share any other issues with the developers.</source>
|
||||
<target>Controlla che mobile e desktop siano collegati alla stessa rete locale e che il firewall del desktop consenta la connessione.
|
||||
Si prega di condividere qualsiasi altro problema con gli sviluppatori.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please check that you used the correct link or ask your contact to send you another one." xml:space="preserve">
|
||||
@@ -4692,6 +4758,7 @@ Errore: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Previously connected servers" xml:space="preserve">
|
||||
<source>Previously connected servers</source>
|
||||
<target>Server precedentemente connessi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Privacy & security" xml:space="preserve">
|
||||
@@ -4765,6 +4832,7 @@ Errore: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile theme" xml:space="preserve">
|
||||
<source>Profile theme</source>
|
||||
<target>Tema del profilo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile update will be sent to your contacts." xml:space="preserve">
|
||||
@@ -4851,10 +4919,12 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proxied" xml:space="preserve">
|
||||
<source>Proxied</source>
|
||||
<target>Via proxy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proxied servers" xml:space="preserve">
|
||||
<source>Proxied servers</source>
|
||||
<target>Server via proxy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
@@ -4924,6 +4994,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Receive errors" xml:space="preserve">
|
||||
<source>Receive errors</source>
|
||||
<target>Errori di ricezione</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Received at" xml:space="preserve">
|
||||
@@ -4948,14 +5019,17 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Received messages" xml:space="preserve">
|
||||
<source>Received messages</source>
|
||||
<target>Messaggi ricevuti</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Received reply" xml:space="preserve">
|
||||
<source>Received reply</source>
|
||||
<target>Risposta ricevuta</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Received total" xml:space="preserve">
|
||||
<source>Received total</source>
|
||||
<target>Totale ricevuto</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Receiving address will be changed to a different server. Address change will complete after sender comes online." xml:space="preserve">
|
||||
@@ -4990,6 +5064,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect" xml:space="preserve">
|
||||
<source>Reconnect</source>
|
||||
<target>Riconnetti</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect all connected servers to force message delivery. It uses additional traffic." xml:space="preserve">
|
||||
@@ -4999,18 +5074,22 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect all servers" xml:space="preserve">
|
||||
<source>Reconnect all servers</source>
|
||||
<target>Riconnetti tutti i server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect all servers?" xml:space="preserve">
|
||||
<source>Reconnect all servers?</source>
|
||||
<target>Riconnettere tutti i server?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect server to force message delivery. It uses additional traffic." xml:space="preserve">
|
||||
<source>Reconnect server to force message delivery. It uses additional traffic.</source>
|
||||
<target>Riconnetti il server per forzare la consegna dei messaggi. Usa traffico aggiuntivo.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect server?" xml:space="preserve">
|
||||
<source>Reconnect server?</source>
|
||||
<target>Riconnettere il server?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reconnect servers?" xml:space="preserve">
|
||||
@@ -5065,6 +5144,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove image" xml:space="preserve">
|
||||
<source>Remove image</source>
|
||||
<target>Rimuovi immagine</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove member" xml:space="preserve">
|
||||
@@ -5139,10 +5219,12 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<target>Azzera tutte le statistiche</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics?" xml:space="preserve">
|
||||
<source>Reset all statistics?</source>
|
||||
<target>Azzerare tutte le statistiche?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset colors" xml:space="preserve">
|
||||
@@ -5152,6 +5234,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset to app theme" xml:space="preserve">
|
||||
<source>Reset to app theme</source>
|
||||
<target>Ripristina al tema dell'app</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset to defaults" xml:space="preserve">
|
||||
@@ -5161,6 +5244,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset to user theme" xml:space="preserve">
|
||||
<source>Reset to user theme</source>
|
||||
<target>Ripristina al tema dell'utente</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Restart the app to create a new chat profile" xml:space="preserve">
|
||||
@@ -5235,6 +5319,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="SMP server" xml:space="preserve">
|
||||
<source>SMP server</source>
|
||||
<target>Server SMP</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SMP servers" xml:space="preserve">
|
||||
@@ -5354,10 +5439,12 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Scale" xml:space="preserve">
|
||||
<source>Scale</source>
|
||||
<target>Scala</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Scan / Paste link" xml:space="preserve">
|
||||
<source>Scan / Paste link</source>
|
||||
<target>Scansiona / Incolla link</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Scan QR code" xml:space="preserve">
|
||||
@@ -5402,6 +5489,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Secondary" xml:space="preserve">
|
||||
<source>Secondary</source>
|
||||
<target>Secondario</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Secure queue" xml:space="preserve">
|
||||
@@ -5411,6 +5499,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Secured" xml:space="preserve">
|
||||
<source>Secured</source>
|
||||
<target>Protetto</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Security assessment" xml:space="preserve">
|
||||
@@ -5430,6 +5519,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected chat preferences prohibit this message." xml:space="preserve">
|
||||
<source>Selected chat preferences prohibit this message.</source>
|
||||
<target>Le preferenze della chat selezionata vietano questo messaggio.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Self-destruct" xml:space="preserve">
|
||||
@@ -5484,6 +5574,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send errors" xml:space="preserve">
|
||||
<source>Send errors</source>
|
||||
<target>Errori di invio</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send link previews" xml:space="preserve">
|
||||
@@ -5598,6 +5689,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent directly" xml:space="preserve">
|
||||
<source>Sent directly</source>
|
||||
<target>Inviato direttamente</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent file event" xml:space="preserve">
|
||||
@@ -5612,6 +5704,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent messages" xml:space="preserve">
|
||||
<source>Sent messages</source>
|
||||
<target>Messaggi inviati</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent messages will be deleted after set time." xml:space="preserve">
|
||||
@@ -5621,18 +5714,22 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent reply" xml:space="preserve">
|
||||
<source>Sent reply</source>
|
||||
<target>Risposta inviata</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent total" xml:space="preserve">
|
||||
<source>Sent total</source>
|
||||
<target>Totale inviato</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sent via proxy" xml:space="preserve">
|
||||
<source>Sent via proxy</source>
|
||||
<target>Inviato via proxy</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>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings." xml:space="preserve">
|
||||
@@ -5661,6 +5758,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server type" xml:space="preserve">
|
||||
<source>Server type</source>
|
||||
<target>Tipo server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings." xml:space="preserve">
|
||||
@@ -5668,6 +5766,10 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<target>La versione del server non è compatibile con le impostazioni di rete.</target>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5679,10 +5781,12 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers info" xml:space="preserve">
|
||||
<source>Servers info</source>
|
||||
<target>Info dei server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers statistics will be reset - this cannot be undone!" xml:space="preserve">
|
||||
<source>Servers statistics will be reset - this cannot be undone!</source>
|
||||
<target>Le statistiche dei server verranno azzerate - è irreversibile!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Session code" xml:space="preserve">
|
||||
@@ -5702,6 +5806,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Set default theme" xml:space="preserve">
|
||||
<source>Set default theme</source>
|
||||
<target>Imposta tema predefinito</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Set group preferences" xml:space="preserve">
|
||||
@@ -5809,6 +5914,10 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<target>Mostra stato del messaggio</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Mostra anteprima</target>
|
||||
@@ -5826,6 +5935,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX" xml:space="preserve">
|
||||
<source>SimpleX</source>
|
||||
<target>SimpleX</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX Address" xml:space="preserve">
|
||||
@@ -5905,6 +6015,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Size" xml:space="preserve">
|
||||
<source>Size</source>
|
||||
<target>Dimensione</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Skip" xml:space="preserve">
|
||||
@@ -5954,10 +6065,12 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Starting from %@." xml:space="preserve">
|
||||
<source>Starting from %@.</source>
|
||||
<target>Inizio da %@.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Statistics" xml:space="preserve">
|
||||
<source>Statistics</source>
|
||||
<target>Statistiche</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Stop" xml:space="preserve">
|
||||
@@ -6027,18 +6140,17 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscribed" xml:space="preserve">
|
||||
<source>Subscribed</source>
|
||||
<target>Iscritto</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription errors" xml:space="preserve">
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<target>Errori di iscrizione</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<target>Iscrizioni ignorate</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Support SimpleX Chat" xml:space="preserve">
|
||||
@@ -6123,6 +6235,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Temporary file error" xml:space="preserve">
|
||||
<source>Temporary file error</source>
|
||||
<target>Errore del file temporaneo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Test failed at step %@." xml:space="preserve">
|
||||
@@ -6264,6 +6377,7 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.</ta
|
||||
</trans-unit>
|
||||
<trans-unit id="Themes" xml:space="preserve">
|
||||
<source>Themes</source>
|
||||
<target>Temi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="These settings are for your current profile **%@**." xml:space="preserve">
|
||||
@@ -6333,6 +6447,7 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.</ta
|
||||
</trans-unit>
|
||||
<trans-unit id="This link was used with another mobile device, please create a new link on the desktop." xml:space="preserve">
|
||||
<source>This link was used with another mobile device, please create a new link on the desktop.</source>
|
||||
<target>Questo link è stato usato con un altro dispositivo mobile, creane uno nuovo sul desktop.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="This setting applies to messages in your current chat profile **%@**." xml:space="preserve">
|
||||
@@ -6342,6 +6457,7 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.</ta
|
||||
</trans-unit>
|
||||
<trans-unit id="Title" xml:space="preserve">
|
||||
<source>Title</source>
|
||||
<target>Titoli</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To ask any questions and to receive updates:" xml:space="preserve">
|
||||
@@ -6413,6 +6529,7 @@ Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzio
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<target>Totale</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Transport isolation" xml:space="preserve">
|
||||
@@ -6422,6 +6539,7 @@ Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzio
|
||||
</trans-unit>
|
||||
<trans-unit id="Transport sessions" xml:space="preserve">
|
||||
<source>Transport sessions</source>
|
||||
<target>Sessioni di trasporto</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Trying to connect to the server used to receive messages from this contact (error: %@)." xml:space="preserve">
|
||||
@@ -6618,6 +6736,7 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
|
||||
</trans-unit>
|
||||
<trans-unit id="Upload errors" xml:space="preserve">
|
||||
<source>Upload errors</source>
|
||||
<target>Errori di invio</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Upload failed" xml:space="preserve">
|
||||
@@ -6632,10 +6751,12 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
|
||||
</trans-unit>
|
||||
<trans-unit id="Uploaded" xml:space="preserve">
|
||||
<source>Uploaded</source>
|
||||
<target>Inviato</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Uploaded files" xml:space="preserve">
|
||||
<source>Uploaded files</source>
|
||||
<target>File inviati</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Uploading archive" xml:space="preserve">
|
||||
@@ -6715,6 +6836,7 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>Selezione utente</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Using .onion hosts requires compatible VPN provider." xml:space="preserve">
|
||||
@@ -6854,10 +6976,12 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
|
||||
</trans-unit>
|
||||
<trans-unit id="Wallpaper accent" xml:space="preserve">
|
||||
<source>Wallpaper accent</source>
|
||||
<target>Tinta dello sfondo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Wallpaper background" xml:space="preserve">
|
||||
<source>Wallpaper background</source>
|
||||
<target>Retro dello sfondo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Warning: starting chat on multiple devices is not supported and will cause message delivery failures" xml:space="preserve">
|
||||
@@ -6967,6 +7091,7 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
|
||||
</trans-unit>
|
||||
<trans-unit id="Wrong key or unknown file chunk address - most likely file is deleted." xml:space="preserve">
|
||||
<source>Wrong key or unknown file chunk address - most likely file is deleted.</source>
|
||||
<target>Chiave sbagliata o indirizzo sconosciuto per frammento del file - probabilmente il file è stato eliminato.</target>
|
||||
<note>file error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Wrong passphrase!" xml:space="preserve">
|
||||
@@ -6976,6 +7101,7 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
|
||||
</trans-unit>
|
||||
<trans-unit id="XFTP server" xml:space="preserve">
|
||||
<source>XFTP server</source>
|
||||
<target>Server XFTP</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="XFTP servers" xml:space="preserve">
|
||||
@@ -7062,6 +7188,7 @@ Ripetere la richiesta di ingresso?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You are not connected to these servers. Private routing is used to deliver messages to them." xml:space="preserve">
|
||||
<source>You are not connected to these servers. Private routing is used to deliver messages to them.</source>
|
||||
<target>Non sei connesso/a a questi server. L'instradamento privato è usato per consegnare loro i messaggi.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can accept calls from lock screen, without device and app authentication." xml:space="preserve">
|
||||
@@ -7099,8 +7226,8 @@ Ripetere la richiesta di ingresso?</target>
|
||||
<target>Puoi renderlo visibile ai tuoi contatti SimpleX nelle impostazioni.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Ora puoi inviare messaggi a %@</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7472,6 +7599,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="attempts" xml:space="preserve">
|
||||
<source>attempts</source>
|
||||
<target>tentativi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="audio call (not e2e encrypted)" xml:space="preserve">
|
||||
@@ -7507,7 +7635,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>bloccato dall'amministratore</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
@@ -7666,6 +7794,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="decryption errors" xml:space="preserve">
|
||||
<source>decryption errors</source>
|
||||
<target>errori di decifrazione</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="default (%@)" xml:space="preserve">
|
||||
@@ -7720,6 +7849,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="duplicates" xml:space="preserve">
|
||||
<source>duplicates</source>
|
||||
<target>doppi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="e2e encrypted" xml:space="preserve">
|
||||
@@ -7804,6 +7934,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="expired" xml:space="preserve">
|
||||
<source>expired</source>
|
||||
<target>scaduto</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="forwarded" xml:space="preserve">
|
||||
@@ -7838,6 +7969,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<target>inattivo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
@@ -8019,10 +8151,12 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="other" xml:space="preserve">
|
||||
<source>other</source>
|
||||
<target>altro</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="other errors" xml:space="preserve">
|
||||
<source>other errors</source>
|
||||
<target>altri errori</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="owner" xml:space="preserve">
|
||||
|
||||
@@ -699,8 +699,8 @@
|
||||
<source>All new messages from %@ will be hidden!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1652,8 +1652,8 @@ This is your own one-time link!</source>
|
||||
<target>現在の暗証フレーズ…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5442,6 +5442,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server version is incompatible with network settings.</source>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5577,6 +5581,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Show message status</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>プレビューを表示</target>
|
||||
@@ -5794,10 +5802,6 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6796,8 +6800,8 @@ Repeat join request?</source>
|
||||
<source>You can make it visible to your SimpleX contacts via Settings.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>%@ にメッセージを送信できるようになりました</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7190,7 +7194,7 @@ SimpleX サーバーはあなたのプロファイルを参照できません。
|
||||
</trans-unit>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -709,8 +709,8 @@
|
||||
<target>Alle nieuwe berichten van %@ worden verborgen!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1709,8 +1709,8 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<target>Huidige wachtwoord…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5668,6 +5668,10 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<target>Serverversie is incompatibel met netwerkinstellingen.</target>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5809,6 +5813,10 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<target>Toon berichtstatus</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Toon voorbeeld</target>
|
||||
@@ -6033,10 +6041,6 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -7099,8 +7103,8 @@ Deelnameverzoek herhalen?</target>
|
||||
<target>Je kunt het via Instellingen zichtbaar maken voor je SimpleX contacten.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Je kunt nu berichten sturen naar %@</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7507,7 +7511,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>geblokkeerd door beheerder</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -709,8 +709,8 @@
|
||||
<target>Wszystkie nowe wiadomości z %@ zostaną ukryte!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1709,8 +1709,8 @@ To jest twój jednorazowy link!</target>
|
||||
<target>Obecne hasło…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5668,6 +5668,10 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
<target>Wersja serwera jest niekompatybilna z ustawieniami sieciowymi.</target>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5809,6 +5813,10 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
<target>Pokaż status wiadomości</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Pokaż podgląd</target>
|
||||
@@ -6033,10 +6041,6 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -7099,8 +7103,8 @@ Powtórzyć prośbę dołączenia?</target>
|
||||
<target>Możesz ustawić go jako widoczny dla swoich kontaktów SimpleX w Ustawieniach.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Możesz teraz wysyłać wiadomości do %@</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7507,7 +7511,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>zablokowany przez admina</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -709,8 +709,8 @@
|
||||
<target>Все новые сообщения от %@ будут скрыты!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1709,8 +1709,8 @@ This is your own one-time link!</source>
|
||||
<target>Текущий пароль…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5666,6 +5666,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Версия сервера несовместима с настройками сети.</target>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5807,6 +5811,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Показать статус сообщения</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Показывать уведомления</target>
|
||||
@@ -6031,10 +6039,6 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -7097,9 +7101,9 @@ Repeat join request?</source>
|
||||
<target>Вы можете сделать его видимым для ваших контактов в SimpleX через Настройки.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<target>Вы теперь можете отправлять сообщения %@</target>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Вы теперь можете общаться с %@</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can set lock screen notification preview via settings." xml:space="preserve">
|
||||
@@ -7505,7 +7509,7 @@ SimpleX серверы не могут получить доступ к Ваше
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>заблокировано администратором</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -674,8 +674,8 @@
|
||||
<source>All new messages from %@ will be hidden!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1617,8 +1617,8 @@ This is your own one-time link!</source>
|
||||
<target>รหัสผ่านปัจจุบัน…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5401,6 +5401,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server version is incompatible with network settings.</source>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5535,6 +5539,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Show message status</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>แสดงตัวอย่าง</target>
|
||||
@@ -5750,10 +5758,6 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6750,8 +6754,8 @@ Repeat join request?</source>
|
||||
<source>You can make it visible to your SimpleX contacts via Settings.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>ตอนนี้คุณสามารถส่งข้อความถึง %@</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7142,7 +7146,7 @@ SimpleX servers cannot see your profile.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -709,8 +709,8 @@
|
||||
<target>%@ 'den gelen bütün yeni mesajlar saklı olacak!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1709,8 +1709,8 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
<target>Şu anki parola…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5668,6 +5668,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Sunucu sürümü ağ ayarlarıyla uyumlu değil.</target>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5809,6 +5813,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Mesaj durumunu göster</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Ön gösterimi göser</target>
|
||||
@@ -6033,10 +6041,6 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -7099,8 +7103,8 @@ Katılma isteği tekrarlansın mı?</target>
|
||||
<target>Ayarlardan SimpleX kişilerinize görünür yapabilirsiniz.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Artık %@ adresine mesaj gönderebilirsin</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7507,7 +7511,7 @@ SimpleX sunucuları profilinizi göremez.</target>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>yönetici tarafından engellendi</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -709,8 +709,8 @@
|
||||
<target>Всі нові повідомлення від %@ будуть приховані!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1709,8 +1709,8 @@ This is your own one-time link!</source>
|
||||
<target>Поточна парольна фраза…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5668,6 +5668,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Серверна версія несумісна з мережевими налаштуваннями.</target>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5809,6 +5813,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Показати статус повідомлення</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Показати попередній перегляд</target>
|
||||
@@ -6033,10 +6041,6 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -7099,8 +7103,8 @@ Repeat join request?</source>
|
||||
<target>Ви можете зробити його видимим для ваших контактів у SimpleX за допомогою налаштувань.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>Тепер ви можете надсилати повідомлення на адресу %@</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7507,7 +7511,7 @@ SimpleX servers cannot see your profile.</source>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>заблоковано адміністратором</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -696,8 +696,8 @@
|
||||
<source>All new messages from %@ will be hidden!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All users" xml:space="preserve">
|
||||
<source>All users</source>
|
||||
<trans-unit id="All profiles" xml:space="preserve">
|
||||
<source>All profiles</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
|
||||
@@ -1683,8 +1683,8 @@ This is your own one-time link!</source>
|
||||
<target>现有密码……</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current user" xml:space="preserve">
|
||||
<source>Current user</source>
|
||||
<trans-unit id="Current profile" xml:space="preserve">
|
||||
<source>Current profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
|
||||
@@ -5589,6 +5589,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server version is incompatible with network settings.</source>
|
||||
<note>srv error text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server version is incompatible with your app: %@." xml:space="preserve">
|
||||
<source>Server version is incompatible with your app: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5729,6 +5733,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Show message status</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show percentage" xml:space="preserve">
|
||||
<source>Show percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>显示预览</target>
|
||||
@@ -5952,10 +5960,6 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Subscription errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription percentage" xml:space="preserve">
|
||||
<source>Subscription percentage</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscriptions ignored" xml:space="preserve">
|
||||
<source>Subscriptions ignored</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -7000,8 +7004,8 @@ Repeat join request?</source>
|
||||
<target>你可以通过设置让它对你的 SimpleX 联系人可见。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can now send messages to %@" xml:space="preserve">
|
||||
<source>You can now send messages to %@</source>
|
||||
<trans-unit id="You can now chat with %@" xml:space="preserve">
|
||||
<source>You can now chat with %@</source>
|
||||
<target>您现在可以给 %@ 发送消息</target>
|
||||
<note>notification body</note>
|
||||
</trans-unit>
|
||||
@@ -7403,7 +7407,7 @@ SimpleX 服务器无法看到您的资料。</target>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
<source>blocked by admin</source>
|
||||
<target>由管理员封禁</target>
|
||||
<note>blocked chat item</note>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bold" xml:space="preserve">
|
||||
<source>bold</source>
|
||||
|
||||
@@ -119,7 +119,7 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
var threadId: UUID? = NSEThreads.shared.newThread()
|
||||
var notificationInfo: NtfMessages?
|
||||
var receiveEntityId: String?
|
||||
var expectedMessages: Set<String> = []
|
||||
var expectedMessage: String?
|
||||
// return true if the message is taken - it prevents sending it to another NotificationService instance for processing
|
||||
var shouldProcessNtf = false
|
||||
var appSubscriber: AppSubscriber?
|
||||
@@ -191,7 +191,7 @@ 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.ntfMessages.count))")
|
||||
logger.debug("NotificationService: receiveNtfMessages: apiGetNtfMessage \(String(describing: ntfInfo.ntfMessage_ == nil ? 0 : 1))")
|
||||
if let connEntity = ntfInfo.connEntity_ {
|
||||
setBestAttemptNtf(
|
||||
ntfInfo.ntfsEnabled
|
||||
@@ -201,7 +201,7 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
if let id = connEntity.id, ntfInfo.msgTs != nil {
|
||||
notificationInfo = ntfInfo
|
||||
receiveEntityId = id
|
||||
expectedMessages = Set(ntfInfo.ntfMessages.map { $0.msgId })
|
||||
expectedMessage = ntfInfo.ntfMessage_.flatMap { $0.msgId }
|
||||
shouldProcessNtf = true
|
||||
return
|
||||
}
|
||||
@@ -224,12 +224,10 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
self.setBestAttemptNtf(.empty)
|
||||
}
|
||||
if case let .msgInfo(info) = ntf {
|
||||
let found = expectedMessages.remove(info.msgId)
|
||||
if found != nil {
|
||||
logger.debug("NotificationService processNtf: msgInfo, last: \(self.expectedMessages.isEmpty)")
|
||||
if expectedMessages.isEmpty {
|
||||
self.deliverBestAttemptNtf()
|
||||
}
|
||||
if info.msgId == expectedMessage {
|
||||
expectedMessage = nil
|
||||
logger.debug("NotificationService processNtf: msgInfo")
|
||||
self.deliverBestAttemptNtf()
|
||||
return true
|
||||
} else if info.msgTs > msgTs {
|
||||
logger.debug("NotificationService processNtf: unexpected msgInfo, let other instance to process it, stopping this one")
|
||||
@@ -392,6 +390,16 @@ func appStateSubscriber(onState: @escaping (AppState) -> Void) -> AppSubscriber
|
||||
}
|
||||
}
|
||||
|
||||
let seSubscriber = seMessageSubscriber {
|
||||
switch $0 {
|
||||
case let .state(state):
|
||||
if state == .sendingMessage && NSEChatState.shared.value.canSuspend {
|
||||
logger.debug("NotificationService: seSubscriber app state \(state.rawValue), suspending")
|
||||
suspendChat(fastNSESuspendSchedule.timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var receiverStarted = false
|
||||
let startLock = DispatchSemaphore(value: 1)
|
||||
let suspendLock = DispatchSemaphore(value: 1)
|
||||
@@ -636,7 +644,7 @@ func apiGetActiveUser() -> User? {
|
||||
}
|
||||
|
||||
func apiStartChat() throws -> Bool {
|
||||
let r = sendSimpleXCmd(.startChat(mainApp: false))
|
||||
let r = sendSimpleXCmd(.startChat(mainApp: false, enableSndFiles: false))
|
||||
switch r {
|
||||
case .chatStarted: return true
|
||||
case .chatRunning: return false
|
||||
@@ -677,9 +685,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, ntfMessages) = r, let user = user {
|
||||
logger.debug("apiGetNtfMessage response ntfMessages: \(ntfMessages.count)")
|
||||
return NtfMessages(user: user, connEntity_: connEntity_, msgTs: msgTs, ntfMessages: ntfMessages)
|
||||
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_)
|
||||
} else if case let .chatCmdError(_, error) = r {
|
||||
logger.debug("apiGetNtfMessage error response: \(String.init(describing: error))")
|
||||
} else {
|
||||
@@ -726,7 +734,7 @@ struct NtfMessages {
|
||||
var user: User
|
||||
var connEntity_: ConnectionEntity?
|
||||
var msgTs: Date?
|
||||
var ntfMessages: [NtfMsgInfo]
|
||||
var ntfMessage_: NtfMsgInfo?
|
||||
|
||||
var ntfsEnabled: Bool {
|
||||
user.showNotifications && (connEntity_?.ntfsEnabled ?? false)
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationSupportsText</key>
|
||||
<true/>
|
||||
<key>NSExtensionActivationSupportsAttachmentsWithMinCount</key>
|
||||
<integer>0</integer>
|
||||
<key>NSExtensionActivationSupportsAttachmentsWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsFileWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsMovieWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.share-services</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>ShareViewController</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// SEChatState.swift
|
||||
// SimpleX SE
|
||||
//
|
||||
// Created by User on 18/07/2024.
|
||||
// Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
// SEStateGroupDefault must not be used in the share extension directly, only via this singleton
|
||||
class SEChatState {
|
||||
static let shared = SEChatState()
|
||||
private var value_ = seStateGroupDefault.get()
|
||||
|
||||
var value: SEState {
|
||||
value_
|
||||
}
|
||||
|
||||
func set(_ state: SEState) {
|
||||
seStateGroupDefault.set(state)
|
||||
sendSEState(state)
|
||||
value_ = state
|
||||
}
|
||||
}
|
||||
|
||||
/// Waits for other processes to set their state to suspended
|
||||
/// Will wait for maximum of two seconds, since they might not be running
|
||||
func waitForOtherProcessesToSuspend() async {
|
||||
let startTime = CFAbsoluteTimeGetCurrent()
|
||||
while CFAbsoluteTimeGetCurrent() - startTime < 2 {
|
||||
try? await Task.sleep(nanoseconds: 100 * NSEC_PER_MSEC)
|
||||
if appStateGroupDefault.get() == .suspended &&
|
||||
nseStateGroupDefault.get() == .suspended {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// ShareAPI.swift
|
||||
// SimpleX SE
|
||||
//
|
||||
// Created by User on 15/07/2024.
|
||||
// Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import OSLog
|
||||
import Foundation
|
||||
import SimpleXChat
|
||||
|
||||
let logger = Logger()
|
||||
|
||||
func apiGetActiveUser() throws -> User? {
|
||||
let r = sendSimpleXCmd(.showActiveUser)
|
||||
switch r {
|
||||
case let .activeUser(user): return user
|
||||
case .chatCmdError(_, .error(.noActiveUser)): return nil
|
||||
default: throw r
|
||||
}
|
||||
}
|
||||
|
||||
func apiStartChat() throws -> Bool {
|
||||
let r = sendSimpleXCmd(.startChat(mainApp: false, enableSndFiles: true))
|
||||
switch r {
|
||||
case .chatStarted: return true
|
||||
case .chatRunning: return false
|
||||
default: throw r
|
||||
}
|
||||
}
|
||||
|
||||
func apiSetNetworkConfig(_ cfg: NetCfg) throws {
|
||||
let r = sendSimpleXCmd(.apiSetNetworkConfig(networkConfig: cfg))
|
||||
if case .cmdOk = r { return }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiSetAppFilePaths(filesFolder: String, tempFolder: String, assetsFolder: String) throws {
|
||||
let r = sendSimpleXCmd(.apiSetAppFilePaths(filesFolder: filesFolder, tempFolder: tempFolder, assetsFolder: assetsFolder))
|
||||
if case .cmdOk = r { return }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiSetEncryptLocalFiles(_ enable: Bool) throws {
|
||||
let r = sendSimpleXCmd(.apiSetEncryptLocalFiles(enable: enable))
|
||||
if case .cmdOk = r { return }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiGetChats(userId: User.ID) throws -> Array<ChatData> {
|
||||
let r = sendSimpleXCmd(.apiGetChats(userId: userId))
|
||||
if case let .apiChats(user: _, chats: chats) = r { return chats }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiSendMessage(
|
||||
chatInfo: ChatInfo,
|
||||
cryptoFile: CryptoFile?,
|
||||
msgContent: MsgContent
|
||||
) throws -> AChatItem {
|
||||
let r = sendSimpleXCmd(
|
||||
chatInfo.chatType == .local
|
||||
? .apiCreateChatItem(
|
||||
noteFolderId: chatInfo.apiId,
|
||||
file: cryptoFile,
|
||||
msg: msgContent
|
||||
)
|
||||
: .apiSendMessage(
|
||||
type: chatInfo.chatType,
|
||||
id: chatInfo.apiId,
|
||||
file: cryptoFile,
|
||||
quotedItemId: nil,
|
||||
msg: msgContent,
|
||||
live: false,
|
||||
ttl: nil
|
||||
)
|
||||
)
|
||||
if case let .newChatItem(_, chatItem) = r {
|
||||
return chatItem
|
||||
} else {
|
||||
if let filePath = cryptoFile?.filePath { removeFile(filePath) }
|
||||
throw r
|
||||
}
|
||||
}
|
||||
|
||||
func apiActivateChat() throws {
|
||||
chatReopenStore()
|
||||
let r = sendSimpleXCmd(.apiActivateChat(restoreChat: false))
|
||||
if case .cmdOk = r { return }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiSuspendChat(expired: Bool) {
|
||||
let r = sendSimpleXCmd(.apiSuspendChat(timeoutMicroseconds: expired ? 0 : 3_000000))
|
||||
// Block until `chatSuspended` received or 3 seconds has passed
|
||||
var suspended = false
|
||||
if case .cmdOk = r, !expired {
|
||||
let startTime = CFAbsoluteTimeGetCurrent()
|
||||
while CFAbsoluteTimeGetCurrent() - startTime < 3 {
|
||||
switch recvSimpleXMsg(messageTimeout: 3_500000) {
|
||||
case .chatSuspended:
|
||||
suspended = false
|
||||
break
|
||||
default: continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if !suspended {
|
||||
_ = sendSimpleXCmd(.apiSuspendChat(timeoutMicroseconds: 0))
|
||||
}
|
||||
logger.debug("close store")
|
||||
chatCloseStore()
|
||||
SEChatState.shared.set(.inactive)
|
||||
}
|
||||
@@ -0,0 +1,500 @@
|
||||
//
|
||||
// ShareModel.swift
|
||||
// SimpleX SE
|
||||
//
|
||||
// Created by Levitating Pineapple on 09/07/2024.
|
||||
// Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import UniformTypeIdentifiers
|
||||
import AVFoundation
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
/// Maximum size of hex encoded media previews
|
||||
private let MAX_DATA_SIZE: Int64 = 14000
|
||||
|
||||
/// Maximum dimension (width or height) of an image, before passed for processing
|
||||
private let MAX_DOWNSAMPLE_SIZE: Int64 = 2000
|
||||
|
||||
class ShareModel: ObservableObject {
|
||||
@Published var sharedContent: SharedContent?
|
||||
@Published var chats = Array<ChatData>()
|
||||
@Published var profileImages = Dictionary<ChatInfo.ID, UIImage>()
|
||||
@Published var search = String()
|
||||
@Published var comment = String()
|
||||
@Published var selected: ChatData?
|
||||
@Published var isLoaded = false
|
||||
@Published var bottomBar: BottomBar = .loadingSpinner
|
||||
@Published var errorAlert: ErrorAlert?
|
||||
|
||||
enum BottomBar {
|
||||
case sendButton
|
||||
case loadingSpinner
|
||||
case loadingBar(progress: Double)
|
||||
|
||||
var isLoading: Bool {
|
||||
switch self {
|
||||
case .sendButton: false
|
||||
case .loadingSpinner: true
|
||||
case .loadingBar: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var completion: () -> Void = {
|
||||
fatalError("completion has not been set")
|
||||
}
|
||||
|
||||
private var itemProvider: NSItemProvider?
|
||||
|
||||
var isSendDisbled: Bool { sharedContent == nil || selected == nil }
|
||||
|
||||
var filteredChats: Array<ChatData> {
|
||||
search.isEmpty
|
||||
? filterChatsToForwardTo(chats: chats)
|
||||
: filterChatsToForwardTo(chats: chats)
|
||||
.filter { foundChat($0, search.localizedLowercase) }
|
||||
}
|
||||
|
||||
func setup(context: NSExtensionContext) {
|
||||
if let item = context.inputItems.first as? NSExtensionItem,
|
||||
let itemProvider = item.attachments?.first {
|
||||
self.itemProvider = itemProvider
|
||||
self.completion = {
|
||||
ShareModel.CompletionHandler.isEventLoopEnabled = false
|
||||
context.completeRequest(returningItems: [item]) {
|
||||
apiSuspendChat(expired: $0)
|
||||
}
|
||||
}
|
||||
// Init Chat
|
||||
Task {
|
||||
if let e = initChat() {
|
||||
await MainActor.run { errorAlert = e }
|
||||
} else {
|
||||
// Load Chats
|
||||
Task {
|
||||
switch fetchChats() {
|
||||
case let .success(chats):
|
||||
// Decode base64 images on background thread
|
||||
let profileImages = chats.reduce(into: Dictionary<ChatInfo.ID, UIImage>()) { dict, chatData in
|
||||
if let profileImage = chatData.chatInfo.image,
|
||||
let uiImage = UIImage(base64Encoded: profileImage) {
|
||||
dict[chatData.id] = uiImage
|
||||
}
|
||||
}
|
||||
await MainActor.run {
|
||||
self.chats = chats
|
||||
self.profileImages = profileImages
|
||||
withAnimation { isLoaded = true }
|
||||
}
|
||||
case let .failure(error):
|
||||
await MainActor.run { errorAlert = error }
|
||||
}
|
||||
}
|
||||
// Process Attachment
|
||||
Task {
|
||||
switch await self.itemProvider!.sharedContent() {
|
||||
case let .success(chatItemContent):
|
||||
await MainActor.run {
|
||||
self.sharedContent = chatItemContent
|
||||
self.bottomBar = .sendButton
|
||||
if case let .text(string) = chatItemContent { comment = string }
|
||||
}
|
||||
case let .failure(errorAlert):
|
||||
await MainActor.run { self.errorAlert = errorAlert }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func send() {
|
||||
if let sharedContent, let selected {
|
||||
Task {
|
||||
await MainActor.run { self.bottomBar = .loadingSpinner }
|
||||
do {
|
||||
SEChatState.shared.set(.sendingMessage)
|
||||
await waitForOtherProcessesToSuspend()
|
||||
let ci = try apiSendMessage(
|
||||
chatInfo: selected.chatInfo,
|
||||
cryptoFile: sharedContent.cryptoFile,
|
||||
msgContent: sharedContent.msgContent(comment: self.comment)
|
||||
)
|
||||
if selected.chatInfo.chatType == .local {
|
||||
completion()
|
||||
} else {
|
||||
await MainActor.run { self.bottomBar = .loadingBar(progress: .zero) }
|
||||
if let e = await handleEvents(
|
||||
isGroupChat: ci.chatInfo.chatType == .group,
|
||||
isWithoutFile: sharedContent.cryptoFile == nil,
|
||||
chatItemId: ci.chatItem.id
|
||||
) {
|
||||
await MainActor.run { errorAlert = e }
|
||||
} else {
|
||||
completion()
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
if let e = error as? ErrorAlert {
|
||||
await MainActor.run { errorAlert = e }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func initChat() -> ErrorAlert? {
|
||||
do {
|
||||
if hasChatCtrl() {
|
||||
try apiActivateChat()
|
||||
} else {
|
||||
registerGroupDefaults()
|
||||
haskell_init_se()
|
||||
let (_, result) = chatMigrateInit(confirmMigrations: defaultMigrationConfirmation())
|
||||
if let e = migrationError(result) { return e }
|
||||
try apiSetAppFilePaths(
|
||||
filesFolder: getAppFilesDirectory().path,
|
||||
tempFolder: getTempFilesDirectory().path,
|
||||
assetsFolder: getWallpaperDirectory().deletingLastPathComponent().path
|
||||
)
|
||||
let isRunning = try apiStartChat()
|
||||
logger.log(level: .debug, "chat started, running: \(isRunning)")
|
||||
}
|
||||
try apiSetNetworkConfig(getNetCfg())
|
||||
try apiSetEncryptLocalFiles(privacyEncryptLocalFilesGroupDefault.get())
|
||||
} catch { return ErrorAlert(error) }
|
||||
return nil
|
||||
}
|
||||
|
||||
private func migrationError(_ r: DBMigrationResult) -> ErrorAlert? {
|
||||
let useKeychain = storeDBPassphraseGroupDefault.get()
|
||||
let storedDBKey = kcDatabasePassword.get()
|
||||
// This switch duplicates DatabaseErrorView.
|
||||
// TODO allow entering passphrase and make messages the same as in DatabaseErrorView.
|
||||
return switch r {
|
||||
case .errorNotADatabase:
|
||||
if useKeychain && storedDBKey != nil && storedDBKey != "" {
|
||||
ErrorAlert(
|
||||
title: "Wrong database passphrase",
|
||||
message: "Database passphrase is different from saved in the keychain."
|
||||
)
|
||||
} else {
|
||||
ErrorAlert(
|
||||
title: "Encrypted database",
|
||||
message: "Sharing is not supported when passphrase is not stored in KeyChain."
|
||||
)
|
||||
}
|
||||
case let .errorMigration(_, migrationError):
|
||||
switch migrationError {
|
||||
case .upgrade:
|
||||
ErrorAlert(
|
||||
title: "Database upgrade required",
|
||||
message: "Open the app to upgrade the database."
|
||||
)
|
||||
case .downgrade:
|
||||
ErrorAlert(
|
||||
title: "Database downgrade required",
|
||||
message: "Open the app to downgrade the database."
|
||||
)
|
||||
case let .migrationError(mtrError):
|
||||
ErrorAlert(
|
||||
title: "Incompatible database version",
|
||||
message: mtrErrorDescription(mtrError)
|
||||
)
|
||||
}
|
||||
case let .errorSQL(_, migrationSQLError):
|
||||
ErrorAlert(
|
||||
title: "Database error",
|
||||
message: "Error: \(migrationSQLError)"
|
||||
)
|
||||
case .errorKeychain:
|
||||
ErrorAlert(
|
||||
title: "Keychain error",
|
||||
message: "Cannot access keychain to save database password"
|
||||
)
|
||||
case .invalidConfirmation:
|
||||
ErrorAlert("Invalid migration confirmation")
|
||||
case let .unknown(json):
|
||||
ErrorAlert(
|
||||
title: "Database error",
|
||||
message: "Unknown database error: \(json)"
|
||||
)
|
||||
case .ok: nil
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchChats() -> Result<Array<ChatData>, ErrorAlert> {
|
||||
do {
|
||||
guard let user = try apiGetActiveUser() else {
|
||||
return .failure(
|
||||
ErrorAlert(
|
||||
title: "No active profile",
|
||||
message: "Please create a profile in the SimpleX app"
|
||||
)
|
||||
)
|
||||
}
|
||||
return .success(try apiGetChats(userId: user.id))
|
||||
} catch {
|
||||
return .failure(ErrorAlert(error))
|
||||
}
|
||||
}
|
||||
|
||||
actor CompletionHandler {
|
||||
static var isEventLoopEnabled = false
|
||||
private var fileCompleted = false
|
||||
private var messageCompleted = false
|
||||
|
||||
func completeFile() { fileCompleted = true }
|
||||
|
||||
func completeMessage() { messageCompleted = true }
|
||||
|
||||
var isRunning: Bool {
|
||||
Self.isEventLoopEnabled && !(fileCompleted && messageCompleted)
|
||||
}
|
||||
}
|
||||
|
||||
/// Polls and processes chat events
|
||||
/// Returns when message sending has completed optionally returning and error.
|
||||
private func handleEvents(isGroupChat: Bool, isWithoutFile: Bool, chatItemId: ChatItem.ID) async -> ErrorAlert? {
|
||||
func isMessage(for item: AChatItem?) -> Bool {
|
||||
item.map { $0.chatItem.id == chatItemId } ?? false
|
||||
}
|
||||
|
||||
CompletionHandler.isEventLoopEnabled = true
|
||||
let ch = CompletionHandler()
|
||||
if isWithoutFile { await ch.completeFile() }
|
||||
var networkTimeout = CFAbsoluteTimeGetCurrent()
|
||||
while await ch.isRunning {
|
||||
if CFAbsoluteTimeGetCurrent() - networkTimeout > 30 {
|
||||
networkTimeout = CFAbsoluteTimeGetCurrent()
|
||||
await MainActor.run {
|
||||
self.errorAlert = ErrorAlert(title: "No network connection") {
|
||||
Button("Keep Trying", role: .cancel) { }
|
||||
Button("Dismiss Sheet", role: .destructive) { self.completion() }
|
||||
}
|
||||
}
|
||||
}
|
||||
switch recvSimpleXMsg(messageTimeout: 1_000_000) {
|
||||
case let .sndFileProgressXFTP(_, ci, _, sentSize, totalSize):
|
||||
guard isMessage(for: ci) else { continue }
|
||||
networkTimeout = CFAbsoluteTimeGetCurrent()
|
||||
await MainActor.run {
|
||||
withAnimation {
|
||||
let progress = Double(sentSize) / Double(totalSize)
|
||||
bottomBar = .loadingBar(progress: progress)
|
||||
}
|
||||
}
|
||||
case let .sndFileCompleteXFTP(_, ci, _):
|
||||
guard isMessage(for: ci) else { continue }
|
||||
if isGroupChat {
|
||||
await MainActor.run { bottomBar = .loadingSpinner }
|
||||
}
|
||||
await ch.completeFile()
|
||||
if await !ch.isRunning { break }
|
||||
case let .chatItemStatusUpdated(_, ci):
|
||||
guard isMessage(for: ci) else { continue }
|
||||
if let (title, message) = ci.chatItem.meta.itemStatus.statusInfo {
|
||||
// `title` and `message` already localized and interpolated
|
||||
return ErrorAlert(
|
||||
title: "\(title)",
|
||||
message: "\(message)"
|
||||
)
|
||||
} else if case let .sndSent(sndProgress) = ci.chatItem.meta.itemStatus {
|
||||
switch sndProgress {
|
||||
case .complete:
|
||||
await ch.completeMessage()
|
||||
case .partial:
|
||||
if isGroupChat {
|
||||
Task {
|
||||
try? await Task.sleep(nanoseconds: 5 * NSEC_PER_SEC)
|
||||
await ch.completeMessage()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case let .sndFileError(_, ci, _, errorMessage):
|
||||
guard isMessage(for: ci) else { continue }
|
||||
if let ci { cleanupFile(ci) }
|
||||
return ErrorAlert(title: "File error", message: "\(fileErrorInfo(ci) ?? errorMessage)")
|
||||
case let .sndFileWarning(_, ci, _, errorMessage):
|
||||
guard isMessage(for: ci) else { continue }
|
||||
if let ci { cleanupFile(ci) }
|
||||
return ErrorAlert(title: "File error", message: "\(fileErrorInfo(ci) ?? errorMessage)")
|
||||
case let .chatError(_, chatError):
|
||||
return ErrorAlert(chatError)
|
||||
case let .chatCmdError(_, chatError):
|
||||
return ErrorAlert(chatError)
|
||||
default: continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
private func fileErrorInfo(_ ci: AChatItem?) -> String? {
|
||||
switch ci?.chatItem.file?.fileStatus {
|
||||
case let .sndError(e): e.errorInfo
|
||||
case let .sndWarning(e): e.errorInfo
|
||||
default: nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Chat Item Content extracted from `NSItemProvider` without the comment
|
||||
enum SharedContent {
|
||||
case image(preview: String, cryptoFile: CryptoFile)
|
||||
case movie(preview: String, duration: Int, cryptoFile: CryptoFile)
|
||||
case url(preview: LinkPreview)
|
||||
case text(string: String)
|
||||
case data(cryptoFile: CryptoFile)
|
||||
|
||||
var cryptoFile: CryptoFile? {
|
||||
switch self {
|
||||
case let .image(_, cryptoFile): cryptoFile
|
||||
case let .movie(_, _, cryptoFile): cryptoFile
|
||||
case .url: nil
|
||||
case .text: nil
|
||||
case let .data(cryptoFile): cryptoFile
|
||||
}
|
||||
}
|
||||
|
||||
func msgContent(comment: String) -> MsgContent {
|
||||
switch self {
|
||||
case let .image(preview, _): .image(text: comment, image: preview)
|
||||
case let .movie(preview, duration, _): .video(text: comment, image: preview, duration: duration)
|
||||
case let .url(preview): .link(text: comment, preview: preview)
|
||||
case .text: .text(comment)
|
||||
case .data: .file(comment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension NSItemProvider {
|
||||
fileprivate func sharedContent() async -> Result<SharedContent, ErrorAlert> {
|
||||
if let type = firstMatching(of: [.image, .movie, .fileURL, .url, .text]) {
|
||||
switch type {
|
||||
// Prepare Image message
|
||||
case .image:
|
||||
|
||||
// Animated
|
||||
return if hasItemConformingToTypeIdentifier(UTType.gif.identifier) {
|
||||
if let url = try? await inPlaceUrl(type: type),
|
||||
let data = try? Data(contentsOf: url),
|
||||
let image = UIImage(data: data),
|
||||
let cryptoFile = saveFile(data, generateNewFileName("IMG", "gif"), encrypted: privacyEncryptLocalFilesGroupDefault.get()),
|
||||
let preview = resizeImageToStrSize(image, maxDataSize: MAX_DATA_SIZE) {
|
||||
.success(.image(preview: preview, cryptoFile: cryptoFile))
|
||||
} else { .failure(ErrorAlert("Error preparing message")) }
|
||||
|
||||
// Static
|
||||
} else {
|
||||
if let url = try? await inPlaceUrl(type: type),
|
||||
let image = downsampleImage(at: url, to: MAX_DOWNSAMPLE_SIZE),
|
||||
let cryptoFile = saveImage(image),
|
||||
let preview = resizeImageToStrSize(image, maxDataSize: MAX_DATA_SIZE) {
|
||||
.success(.image(preview: preview, cryptoFile: cryptoFile))
|
||||
} else { .failure(ErrorAlert("Error preparing message")) }
|
||||
}
|
||||
|
||||
// Prepare Movie message
|
||||
case .movie:
|
||||
if let url = try? await inPlaceUrl(type: type),
|
||||
let trancodedUrl = await transcodeVideo(from: url),
|
||||
let (image, duration) = AVAsset(url: trancodedUrl).generatePreview(),
|
||||
let preview = resizeImageToStrSize(image, maxDataSize: MAX_DATA_SIZE),
|
||||
let cryptoFile = moveTempFileFromURL(trancodedUrl) {
|
||||
try? FileManager.default.removeItem(at: trancodedUrl)
|
||||
return .success(.movie(preview: preview, duration: duration, cryptoFile: cryptoFile))
|
||||
} else { return .failure(ErrorAlert("Error preparing message")) }
|
||||
|
||||
// Prepare Data message
|
||||
case .fileURL:
|
||||
if let url = try? await inPlaceUrl(type: .data) {
|
||||
if isFileTooLarge(for: url) {
|
||||
let sizeString = ByteCountFormatter.string(
|
||||
fromByteCount: Int64(getMaxFileSize(.xftp)),
|
||||
countStyle: .binary
|
||||
)
|
||||
return .failure(
|
||||
ErrorAlert(
|
||||
title: "Large file!",
|
||||
message: "Currently maximum supported file size is \(sizeString)."
|
||||
)
|
||||
)
|
||||
}
|
||||
if let file = saveFileFromURL(url) {
|
||||
return .success(.data(cryptoFile: file))
|
||||
}
|
||||
}
|
||||
return .failure(ErrorAlert("Error preparing file"))
|
||||
|
||||
// Prepare Link message
|
||||
case .url:
|
||||
if let url = try? await loadItem(forTypeIdentifier: type.identifier) as? URL {
|
||||
let content: SharedContent =
|
||||
// Option to disable previews needs to be taken into account
|
||||
// if let linkPreview = await getLinkPreview(for: url) {
|
||||
// .url(preview: linkPreview)
|
||||
// } else {
|
||||
.text(string: url.absoluteString)
|
||||
// }
|
||||
return .success(content)
|
||||
} else { return .failure(ErrorAlert("Error preparing message")) }
|
||||
|
||||
// Prepare Text message
|
||||
case .text:
|
||||
return if let text = try? await loadItem(forTypeIdentifier: type.identifier) as? String {
|
||||
.success(.text(string: text))
|
||||
} else { .failure(ErrorAlert("Error preparing message")) }
|
||||
default: return .failure(ErrorAlert("Unsupported format"))
|
||||
}
|
||||
} else {
|
||||
return .failure(ErrorAlert("Unsupported format"))
|
||||
}
|
||||
}
|
||||
|
||||
private func inPlaceUrl(type: UTType) async throws -> URL {
|
||||
try await withCheckedThrowingContinuation { cont in
|
||||
let _ = loadInPlaceFileRepresentation(forTypeIdentifier: type.identifier) { url, bool, error in
|
||||
if let url = url {
|
||||
cont.resume(returning: url)
|
||||
} else if let error = error {
|
||||
cont.resume(throwing: error)
|
||||
} else {
|
||||
fatalError("Either `url` or `error` must be present")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func firstMatching(of types: Array<UTType>) -> UTType? {
|
||||
for type in types {
|
||||
if hasItemConformingToTypeIdentifier(type.identifier) { return type }
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fileprivate func transcodeVideo(from input: URL) async -> URL? {
|
||||
let outputUrl = URL(
|
||||
fileURLWithPath: generateNewFileName(
|
||||
getTempFilesDirectory().path + "/" + "video", "mp4",
|
||||
fullPath: true
|
||||
)
|
||||
)
|
||||
if await makeVideoQualityLower(input, outputUrl: outputUrl) {
|
||||
return outputUrl
|
||||
} else {
|
||||
try? FileManager.default.removeItem(at: outputUrl)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func isFileTooLarge(for url: URL) -> Bool {
|
||||
fileSize(url)
|
||||
.map { $0 > getMaxFileSize(.xftp) }
|
||||
?? false
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
//
|
||||
// ShareView.swift
|
||||
// SimpleX SE
|
||||
//
|
||||
// Created by Levitating Pineapple on 09/07/2024.
|
||||
// Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
struct ShareView: View {
|
||||
@ObservedObject var model: ShareModel
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
ZStack(alignment: .bottom) {
|
||||
if model.isLoaded {
|
||||
List(model.filteredChats) { chat in
|
||||
HStack {
|
||||
profileImage(
|
||||
chatInfoId: chat.chatInfo.id,
|
||||
systemFallback: chatIconName(chat.chatInfo),
|
||||
size: 30
|
||||
)
|
||||
Text(chat.chatInfo.displayName)
|
||||
Spacer()
|
||||
radioButton(selected: chat == model.selected)
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture { model.selected = model.selected == chat ? nil : chat }
|
||||
.tag(chat)
|
||||
}
|
||||
} else {
|
||||
ProgressView().frame(maxHeight: .infinity)
|
||||
}
|
||||
}
|
||||
.navigationTitle("Share")
|
||||
.safeAreaInset(edge: .bottom) {
|
||||
switch model.bottomBar {
|
||||
case .sendButton:
|
||||
compose(isLoading: false)
|
||||
case .loadingSpinner:
|
||||
compose(isLoading: true)
|
||||
case .loadingBar(let progress):
|
||||
loadingBar(progress: progress)
|
||||
}
|
||||
}
|
||||
}
|
||||
.searchable(
|
||||
text: $model.search,
|
||||
placement: .navigationBarDrawer(displayMode: .always)
|
||||
)
|
||||
.alert($model.errorAlert) { alert in
|
||||
Button("Ok") { model.completion() }
|
||||
}
|
||||
}
|
||||
|
||||
private func compose(isLoading: Bool) -> some View {
|
||||
VStack(spacing: .zero) {
|
||||
Divider()
|
||||
if let content = model.sharedContent {
|
||||
itemPreview(content)
|
||||
}
|
||||
HStack {
|
||||
Group {
|
||||
if #available(iOSApplicationExtension 16.0, *) {
|
||||
TextField("Comment", text: $model.comment, axis: .vertical)
|
||||
} else {
|
||||
TextField("Comment", text: $model.comment)
|
||||
}
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.disabled(isLoading)
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 4)
|
||||
Group {
|
||||
if isLoading {
|
||||
ProgressView()
|
||||
} else {
|
||||
Button(action: model.send) {
|
||||
Image(systemName: "arrow.up.circle.fill")
|
||||
.resizable()
|
||||
}
|
||||
.disabled(model.isSendDisbled)
|
||||
}
|
||||
}
|
||||
.frame(width: 28, height: 28)
|
||||
.padding(6)
|
||||
|
||||
}
|
||||
.background(Color(.systemBackground))
|
||||
.clipShape(RoundedRectangle(cornerRadius: 20))
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 20)
|
||||
.strokeBorder(.secondary, lineWidth: 0.5).opacity(0.7)
|
||||
)
|
||||
.padding(8)
|
||||
}
|
||||
.background(.thinMaterial)
|
||||
}
|
||||
|
||||
@ViewBuilder private func itemPreview(_ content: SharedContent) -> some View {
|
||||
switch content {
|
||||
case let .image(preview, _): imagePreview(preview)
|
||||
case let .movie(preview, _, _): imagePreview(preview)
|
||||
case let .url(linkPreview): imagePreview(linkPreview.image)
|
||||
case let .data(cryptoFile):
|
||||
previewArea {
|
||||
Image(systemName: "doc.fill")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 30, height: 30)
|
||||
.foregroundColor(Color(uiColor: .tertiaryLabel))
|
||||
.padding(.leading, 4)
|
||||
Text(cryptoFile.filePath)
|
||||
}
|
||||
case .text: EmptyView()
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func imagePreview(_ img: String) -> some View {
|
||||
if let img = UIImage(base64Encoded: img) {
|
||||
previewArea {
|
||||
Image(uiImage: img)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(minHeight: 40, maxHeight: 60)
|
||||
}
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func previewArea<V: View>(@ViewBuilder content: @escaping () -> V) -> some View {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
content()
|
||||
Spacer()
|
||||
}
|
||||
.padding(.vertical, 1)
|
||||
.frame(minHeight: 54)
|
||||
.background {
|
||||
switch colorScheme {
|
||||
case .light: LightColorPaletteApp.sentMessage
|
||||
case .dark: DarkColorPaletteApp.sentMessage
|
||||
@unknown default: Color(.tertiarySystemBackground)
|
||||
}
|
||||
}
|
||||
Divider()
|
||||
}
|
||||
|
||||
private func loadingBar(progress: Double) -> some View {
|
||||
VStack {
|
||||
Text("Sending File")
|
||||
ProgressView(value: progress)
|
||||
}
|
||||
.padding()
|
||||
.background(Material.ultraThin)
|
||||
}
|
||||
|
||||
private func profileImage(chatInfoId: ChatInfo.ID, systemFallback: String, size: Double) -> some View {
|
||||
Group {
|
||||
if let uiImage = model.profileImages[chatInfoId] {
|
||||
Image(uiImage: uiImage).resizable()
|
||||
} else {
|
||||
Image(systemName: systemFallback).resizable()
|
||||
}
|
||||
}
|
||||
.foregroundStyle(Color(.tertiaryLabel))
|
||||
.frame(width: size, height: size)
|
||||
.clipShape(RoundedRectangle(cornerRadius: size * 0.225, style: .continuous))
|
||||
}
|
||||
|
||||
private func radioButton(selected: Bool) -> some View {
|
||||
Image(systemName: selected ? "checkmark.circle.fill" : "circle")
|
||||
.imageScale(.large)
|
||||
.foregroundStyle(selected ? Color.accentColor : Color(.tertiaryLabel))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// ShareViewController.swift
|
||||
// SimpleX SE
|
||||
//
|
||||
// Created by Levitating Pineapple on 08/07/2024.
|
||||
// Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
/// Extension Entry point
|
||||
/// System will create this controller each time share sheet is invoked
|
||||
/// using `NSExtensionPrincipalClass` in the info.plist
|
||||
@objc(ShareViewController)
|
||||
class ShareViewController: UIHostingController<ShareView> {
|
||||
private let model = ShareModel()
|
||||
// Assuming iOS continues to only allow single share sheet to be presented at once
|
||||
static var isVisible: Bool = false
|
||||
|
||||
@objc init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
|
||||
super.init(rootView: ShareView(model: model))
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder aDecoder: NSCoder) { fatalError() }
|
||||
|
||||
override func viewDidLoad() {
|
||||
ShareModel.CompletionHandler.isEventLoopEnabled = false
|
||||
model.setup(context: extensionContext!)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
logger.debug("ShareSheet will appear")
|
||||
super.viewWillAppear(animated)
|
||||
Self.isVisible = true
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
logger.debug("ShareSheet will dissappear")
|
||||
super.viewWillDisappear(animated)
|
||||
ShareModel.CompletionHandler.isEventLoopEnabled = false
|
||||
Self.isVisible = false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.chat.simplex.app</string>
|
||||
</array>
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>$(AppIdentifierPrefix)chat.simplex.app</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -178,7 +178,6 @@
|
||||
64E972072881BB22008DBC02 /* CIGroupInvitationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64E972062881BB22008DBC02 /* CIGroupInvitationView.swift */; };
|
||||
64EEB0F72C353F1C00972D62 /* ServersSummaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64EEB0F62C353F1C00972D62 /* ServersSummaryView.swift */; };
|
||||
64F1CC3B28B39D8600CD1FB1 /* IncognitoHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */; };
|
||||
8C05382E2B39887E006436DC /* VideoUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C05382D2B39887E006436DC /* VideoUtils.swift */; };
|
||||
8C69FE7D2B8C7D2700267E38 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C69FE7C2B8C7D2700267E38 /* AppSettings.swift */; };
|
||||
8C74C3E52C1B900600039E77 /* ThemeTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C7E3CE32C0DEAC400BFF63A /* ThemeTypes.swift */; };
|
||||
8C74C3E72C1B901900039E77 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C852B072C1086D100BA61E8 /* Color.swift */; };
|
||||
@@ -194,9 +193,17 @@
|
||||
8C9BC2652C240D5200875A27 /* ThemeModeEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */; };
|
||||
8CC4ED902BD7B8530078AEE8 /* CallAudioDeviceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC4ED8F2BD7B8530078AEE8 /* CallAudioDeviceManager.swift */; };
|
||||
8CC956EE2BC0041000412A11 /* NetworkObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC956ED2BC0041000412A11 /* NetworkObserver.swift */; };
|
||||
CE1EB0E42C459A660099D896 /* ShareAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1EB0E32C459A660099D896 /* ShareAPI.swift */; };
|
||||
CE2AD9CE2C452A4D00E844E3 /* ChatUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2AD9CD2C452A4D00E844E3 /* ChatUtils.swift */; };
|
||||
CE3097FB2C4C0C9F00180898 /* ErrorAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3097FA2C4C0C9F00180898 /* ErrorAlert.swift */; };
|
||||
CE38A29A2C3FCA54005ED185 /* ImageUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBD2859295711D700EC2CF4 /* ImageUtils.swift */; };
|
||||
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = CE38A29B2C3FCD72005ED185 /* SwiftyGif */; };
|
||||
CE984D4B2C36C5D500E3AEFF /* ChatItemClipShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */; };
|
||||
CEDE70222C48FD9500233B1F /* SEChatState.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDE70212C48FD9500233B1F /* SEChatState.swift */; };
|
||||
CEE723AA2C3BD3D70009AE93 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE723A92C3BD3D70009AE93 /* ShareViewController.swift */; };
|
||||
CEE723B12C3BD3D70009AE93 /* SimpleX SE.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = CEE723A72C3BD3D70009AE93 /* SimpleX SE.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
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 */; };
|
||||
D7197A1829AE89660055C05A /* WebRTC in Frameworks */ = {isa = PBXBuildFile; productRef = D7197A1729AE89660055C05A /* WebRTC */; };
|
||||
D72A9088294BD7A70047C86D /* NativeTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A9087294BD7A70047C86D /* NativeTextEditor.swift */; };
|
||||
@@ -205,11 +212,12 @@
|
||||
D77B92DC2952372200A5A1CC /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = D77B92DB2952372200A5A1CC /* SwiftyGif */; };
|
||||
D7F0E33929964E7E0068AF69 /* LZString in Frameworks */ = {isa = PBXBuildFile; productRef = D7F0E33829964E7E0068AF69 /* LZString */; };
|
||||
E50581062C3DDD9D009C3F71 /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = E50581052C3DDD9D009C3F71 /* Yams */; };
|
||||
E505810C2C4656A4009C3F71 /* libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50581072C4656A4009C3F71 /* libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4-ghc9.6.3.a */; };
|
||||
E505810D2C4656A4009C3F71 /* libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50581082C4656A4009C3F71 /* libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4.a */; };
|
||||
E505810E2C4656A4009C3F71 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50581092C4656A4009C3F71 /* libgmpxx.a */; };
|
||||
E505810F2C4656A4009C3F71 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E505810A2C4656A4009C3F71 /* libffi.a */; };
|
||||
E50581102C4656A4009C3F71 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E505810B2C4656A4009C3F71 /* libgmp.a */; };
|
||||
E5DCF8D52C56F7EF007928CC /* libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5DCF8D02C56F7EF007928CC /* libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp-ghc9.6.3.a */; };
|
||||
E5DCF8D62C56F7EF007928CC /* libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5DCF8D12C56F7EF007928CC /* libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp.a */; };
|
||||
E5DCF8D72C56F7EF007928CC /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5DCF8D22C56F7EF007928CC /* libffi.a */; };
|
||||
E5DCF8D82C56F7EF007928CC /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5DCF8D32C56F7EF007928CC /* libgmp.a */; };
|
||||
E5DCF8D92C56F7EF007928CC /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5DCF8D42C56F7EF007928CC /* libgmpxx.a */; };
|
||||
E5DCF8DB2C56FAC1007928CC /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -241,6 +249,20 @@
|
||||
remoteGlobalIDString = 5CE2BA672845308900EC33A6;
|
||||
remoteInfo = SimpleXChat;
|
||||
};
|
||||
CEE723AF2C3BD3D70009AE93 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 5CA059BE279559F40002BEB4 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = CEE723A62C3BD3D70009AE93;
|
||||
remoteInfo = "SimpleX SE";
|
||||
};
|
||||
CEE723D12C3C21C90009AE93 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 5CA059BE279559F40002BEB4 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 5CE2BA672845308900EC33A6;
|
||||
remoteInfo = SimpleXChat;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@@ -261,6 +283,7 @@
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
CEE723B12C3BD3D70009AE93 /* SimpleX SE.appex in Embed App Extensions */,
|
||||
5CE2BA9D284555F500EC33A6 /* SimpleX NSE.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
@@ -489,7 +512,6 @@
|
||||
64E972062881BB22008DBC02 /* CIGroupInvitationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIGroupInvitationView.swift; sourceTree = "<group>"; };
|
||||
64EEB0F62C353F1C00972D62 /* ServersSummaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServersSummaryView.swift; sourceTree = "<group>"; };
|
||||
64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncognitoHelp.swift; sourceTree = "<group>"; };
|
||||
8C05382D2B39887E006436DC /* VideoUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoUtils.swift; sourceTree = "<group>"; };
|
||||
8C69FE7C2B8C7D2700267E38 /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = "<group>"; };
|
||||
8C74C3EB2C1B92A900039E77 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
|
||||
8C74C3ED2C1B942300039E77 /* ChatWallpaper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatWallpaper.swift; sourceTree = "<group>"; };
|
||||
@@ -504,17 +526,27 @@
|
||||
8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeModeEditor.swift; sourceTree = "<group>"; };
|
||||
8CC4ED8F2BD7B8530078AEE8 /* CallAudioDeviceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallAudioDeviceManager.swift; sourceTree = "<group>"; };
|
||||
8CC956ED2BC0041000412A11 /* NetworkObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkObserver.swift; sourceTree = "<group>"; };
|
||||
CE1EB0E32C459A660099D896 /* ShareAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareAPI.swift; sourceTree = "<group>"; };
|
||||
CE2AD9CD2C452A4D00E844E3 /* ChatUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatUtils.swift; sourceTree = "<group>"; };
|
||||
CE3097FA2C4C0C9F00180898 /* ErrorAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorAlert.swift; sourceTree = "<group>"; };
|
||||
CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemClipShape.swift; sourceTree = "<group>"; };
|
||||
CEDE70212C48FD9500233B1F /* SEChatState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SEChatState.swift; sourceTree = "<group>"; };
|
||||
CEE723A72C3BD3D70009AE93 /* SimpleX SE.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "SimpleX SE.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
CEE723A92C3BD3D70009AE93 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
||||
CEE723AE2C3BD3D70009AE93 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
CEE723D42C3C21F50009AE93 /* SimpleX SE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "SimpleX SE.entitlements"; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
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; };
|
||||
E50581072C4656A4009C3F71 /* libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
E50581082C4656A4009C3F71 /* libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4.a"; sourceTree = "<group>"; };
|
||||
E50581092C4656A4009C3F71 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
E505810A2C4656A4009C3F71 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
E505810B2C4656A4009C3F71 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
E5DCF8D02C56F7EF007928CC /* libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
E5DCF8D12C56F7EF007928CC /* libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp.a"; sourceTree = "<group>"; };
|
||||
E5DCF8D22C56F7EF007928CC /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
E5DCF8D32C56F7EF007928CC /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
E5DCF8D42C56F7EF007928CC /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -554,14 +586,22 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
|
||||
E50581102C4656A4009C3F71 /* libgmp.a in Frameworks */,
|
||||
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
|
||||
E505810C2C4656A4009C3F71 /* libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4-ghc9.6.3.a in Frameworks */,
|
||||
E505810F2C4656A4009C3F71 /* libffi.a in Frameworks */,
|
||||
E5DCF8D82C56F7EF007928CC /* libgmp.a in Frameworks */,
|
||||
E50581062C3DDD9D009C3F71 /* Yams in Frameworks */,
|
||||
E505810D2C4656A4009C3F71 /* libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4.a in Frameworks */,
|
||||
E5DCF8D62C56F7EF007928CC /* libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp.a in Frameworks */,
|
||||
E5DCF8D72C56F7EF007928CC /* libffi.a in Frameworks */,
|
||||
E5DCF8D92C56F7EF007928CC /* libgmpxx.a in Frameworks */,
|
||||
E5DCF8D52C56F7EF007928CC /* libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp-ghc9.6.3.a in Frameworks */,
|
||||
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
|
||||
E505810E2C4656A4009C3F71 /* libgmpxx.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E5DCF8DA2C56FABA007928CC /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E5DCF8DB2C56FAC1007928CC /* SimpleXChat.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -628,11 +668,11 @@
|
||||
5C764E5C279C70B7000C6508 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E505810A2C4656A4009C3F71 /* libffi.a */,
|
||||
E505810B2C4656A4009C3F71 /* libgmp.a */,
|
||||
E50581092C4656A4009C3F71 /* libgmpxx.a */,
|
||||
E50581072C4656A4009C3F71 /* libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4-ghc9.6.3.a */,
|
||||
E50581082C4656A4009C3F71 /* libHSsimplex-chat-6.0.0.1-6hE2sENjTY0J94Us5F3bT4.a */,
|
||||
E5DCF8D22C56F7EF007928CC /* libffi.a */,
|
||||
E5DCF8D32C56F7EF007928CC /* libgmp.a */,
|
||||
E5DCF8D42C56F7EF007928CC /* libgmpxx.a */,
|
||||
E5DCF8D02C56F7EF007928CC /* libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp-ghc9.6.3.a */,
|
||||
E5DCF8D12C56F7EF007928CC /* libHSsimplex-chat-6.0.0.2-B4oiZFZeYN0AY2321yyqdp.a */,
|
||||
);
|
||||
path = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@@ -684,7 +724,6 @@
|
||||
64466DCB29FFE3E800E3D48D /* MailView.swift */,
|
||||
64C3B0202A0D359700E19930 /* CustomTimePicker.swift */,
|
||||
5CEBD7452A5C0A8F00665FE2 /* KeyboardPadding.swift */,
|
||||
8C05382D2B39887E006436DC /* VideoUtils.swift */,
|
||||
8C7F8F0D2C19C0C100D16888 /* ViewModifiers.swift */,
|
||||
8C74C3ED2C1B942300039E77 /* ChatWallpaper.swift */,
|
||||
8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */,
|
||||
@@ -703,6 +742,7 @@
|
||||
5C764E5C279C70B7000C6508 /* Libraries */,
|
||||
5CA059C2279559F40002BEB4 /* Shared */,
|
||||
5CDCAD462818589900503DA2 /* SimpleX NSE */,
|
||||
CEE723A82C3BD3D70009AE93 /* SimpleX SE */,
|
||||
5CA059DA279559F40002BEB4 /* Tests iOS */,
|
||||
5CE2BA692845308900EC33A6 /* SimpleXChat */,
|
||||
5CA059CB279559F40002BEB4 /* Products */,
|
||||
@@ -733,6 +773,7 @@
|
||||
5CA059D7279559F40002BEB4 /* Tests iOS.xctest */,
|
||||
5CDCAD452818589900503DA2 /* SimpleX NSE.appex */,
|
||||
5CE2BA682845308900EC33A6 /* SimpleXChat.framework */,
|
||||
CEE723A72C3BD3D70009AE93 /* SimpleX SE.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -856,10 +897,12 @@
|
||||
5CDCAD7228188CFF00503DA2 /* ChatTypes.swift */,
|
||||
5CDCAD7428188D2900503DA2 /* APITypes.swift */,
|
||||
5C5E5D3C282447AB00B0488A /* CallTypes.swift */,
|
||||
CE3097FA2C4C0C9F00180898 /* ErrorAlert.swift */,
|
||||
5C9FD96A27A56D4D0075386C /* JSON.swift */,
|
||||
5CDCAD7D2818941F00503DA2 /* API.swift */,
|
||||
5CDCAD80281A7E2700503DA2 /* Notifications.swift */,
|
||||
5CBD2859295711D700EC2CF4 /* ImageUtils.swift */,
|
||||
CE2AD9CD2C452A4D00E844E3 /* ChatUtils.swift */,
|
||||
64DAE1502809D9F5000DA960 /* FileUtils.swift */,
|
||||
5C9D81182AA7A4F1001D49FD /* CryptoFile.swift */,
|
||||
5C00168028C4FE760094D739 /* KeyChain.swift */,
|
||||
@@ -974,6 +1017,20 @@
|
||||
path = Theme;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CEE723A82C3BD3D70009AE93 /* SimpleX SE */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CEE723D42C3C21F50009AE93 /* SimpleX SE.entitlements */,
|
||||
CEE723AE2C3BD3D70009AE93 /* Info.plist */,
|
||||
CEDE70212C48FD9500233B1F /* SEChatState.swift */,
|
||||
CE1EB0E32C459A660099D896 /* ShareAPI.swift */,
|
||||
CEE723F12C3D25ED0009AE93 /* ShareModel.swift */,
|
||||
CEE723EF2C3D25C70009AE93 /* ShareView.swift */,
|
||||
CEE723A92C3BD3D70009AE93 /* ShareViewController.swift */,
|
||||
);
|
||||
path = "SimpleX SE";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
@@ -1005,6 +1062,7 @@
|
||||
dependencies = (
|
||||
5CE2BA6F2845308900EC33A6 /* PBXTargetDependency */,
|
||||
5CE2BA9F284555F500EC33A6 /* PBXTargetDependency */,
|
||||
CEE723B02C3BD3D70009AE93 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "SimpleX (iOS)";
|
||||
packageProductDependencies = (
|
||||
@@ -1076,6 +1134,24 @@
|
||||
productReference = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
CEE723A62C3BD3D70009AE93 /* SimpleX SE */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = CEE723B42C3BD3D70009AE93 /* Build configuration list for PBXNativeTarget "SimpleX SE" */;
|
||||
buildPhases = (
|
||||
CEE723A32C3BD3D70009AE93 /* Sources */,
|
||||
CEE723A52C3BD3D70009AE93 /* Resources */,
|
||||
E5DCF8DA2C56FABA007928CC /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
CEE723D22C3C21C90009AE93 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "SimpleX SE";
|
||||
productName = "SimpleX SE";
|
||||
productReference = CEE723A72C3BD3D70009AE93 /* SimpleX SE.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
@@ -1083,7 +1159,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastSwiftUpdateCheck = 1330;
|
||||
LastSwiftUpdateCheck = 1540;
|
||||
LastUpgradeCheck = 1340;
|
||||
ORGANIZATIONNAME = "SimpleX Chat";
|
||||
TargetAttributes = {
|
||||
@@ -1103,6 +1179,9 @@
|
||||
CreatedOnToolsVersion = 13.3;
|
||||
LastSwiftMigration = 1330;
|
||||
};
|
||||
CEE723A62C3BD3D70009AE93 = {
|
||||
CreatedOnToolsVersion = 15.4;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 5CA059C1279559F40002BEB4 /* Build configuration list for PBXProject "SimpleX" */;
|
||||
@@ -1144,6 +1223,7 @@
|
||||
5CA059C9279559F40002BEB4 /* SimpleX (iOS) */,
|
||||
5CA059D6279559F40002BEB4 /* Tests iOS */,
|
||||
5CDCAD442818589900503DA2 /* SimpleX NSE */,
|
||||
CEE723A62C3BD3D70009AE93 /* SimpleX SE */,
|
||||
5CE2BA672845308900EC33A6 /* SimpleXChat */,
|
||||
);
|
||||
};
|
||||
@@ -1183,6 +1263,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CEE723A52C3BD3D70009AE93 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
@@ -1299,7 +1386,6 @@
|
||||
5C55A91F283AD0E400C4E99E /* CallManager.swift in Sources */,
|
||||
5CFA59D12864782E00863A68 /* ChatArchiveView.swift in Sources */,
|
||||
649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */,
|
||||
8C05382E2B39887E006436DC /* VideoUtils.swift in Sources */,
|
||||
5CADE79C292131E900072E13 /* ContactPreferencesView.swift in Sources */,
|
||||
5CB346E52868AA7F001FD2EF /* SuspendChat.swift in Sources */,
|
||||
5C9C2DA52894777E00CC63B1 /* GroupProfileView.swift in Sources */,
|
||||
@@ -1368,6 +1454,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5CF937202B24DE8C00E1D781 /* SharedFileSubscriber.swift in Sources */,
|
||||
CE3097FB2C4C0C9F00180898 /* ErrorAlert.swift in Sources */,
|
||||
5C00168128C4FE760094D739 /* KeyChain.swift in Sources */,
|
||||
5CE2BA97284537A800EC33A6 /* dummy.m in Sources */,
|
||||
5CE2BA922845340900EC33A6 /* FileUtils.swift in Sources */,
|
||||
@@ -1384,10 +1471,23 @@
|
||||
8C74C3E52C1B900600039E77 /* ThemeTypes.swift in Sources */,
|
||||
5CE2BA8D284533A300EC33A6 /* CallTypes.swift in Sources */,
|
||||
8C74C3E82C1B905B00039E77 /* ChatWallpaperTypes.swift in Sources */,
|
||||
CE2AD9CE2C452A4D00E844E3 /* ChatUtils.swift in Sources */,
|
||||
5CE2BA8E284533A300EC33A6 /* API.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CEE723A32C3BD3D70009AE93 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CEDE70222C48FD9500233B1F /* SEChatState.swift in Sources */,
|
||||
CEE723F02C3D25C70009AE93 /* ShareView.swift in Sources */,
|
||||
CE1EB0E42C459A660099D896 /* ShareAPI.swift in Sources */,
|
||||
CEE723F22C3D25ED0009AE93 /* ShareModel.swift in Sources */,
|
||||
CEE723AA2C3BD3D70009AE93 /* ShareViewController.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
@@ -1412,6 +1512,16 @@
|
||||
target = 5CE2BA672845308900EC33A6 /* SimpleXChat */;
|
||||
targetProxy = 5CE2BAA82845617C00EC33A6 /* PBXContainerItemProxy */;
|
||||
};
|
||||
CEE723B02C3BD3D70009AE93 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = CEE723A62C3BD3D70009AE93 /* SimpleX SE */;
|
||||
targetProxy = CEE723AF2C3BD3D70009AE93 /* PBXContainerItemProxy */;
|
||||
};
|
||||
CEE723D22C3C21C90009AE93 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 5CE2BA672845308900EC33A6 /* SimpleXChat */;
|
||||
targetProxy = CEE723D12C3C21C90009AE93 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
@@ -1922,6 +2032,74 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
CEE723B22C3BD3D70009AE93 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "SimpleX SE/Info.plist";
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "SimpleX SE";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 SimpleX Chat. All rights reserved.";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
CEE723B32C3BD3D70009AE93 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "SimpleX SE/Info.plist";
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "SimpleX SE";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 SimpleX Chat. All rights reserved.";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
@@ -1970,6 +2148,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
CEE723B42C3BD3D70009AE93 /* Build configuration list for PBXNativeTarget "SimpleX SE" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
CEE723B22C3BD3D70009AE93 /* Debug */,
|
||||
CEE723B32C3BD3D70009AE93 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
@@ -1977,8 +2164,8 @@
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/twostraws/CodeScanner";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 2.0.0;
|
||||
kind = exactVersion;
|
||||
version = 2.1.1;
|
||||
};
|
||||
};
|
||||
8C73C1162C21E17B00892670 /* XCRemoteSwiftPackageReference "Yams" */ = {
|
||||
@@ -2001,8 +2188,8 @@
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/kirualex/SwiftyGif";
|
||||
requirement = {
|
||||
branch = master;
|
||||
kind = branch;
|
||||
kind = revision;
|
||||
revision = 5e8619335d394901379c9add5c4c1c2f420b3800;
|
||||
};
|
||||
};
|
||||
D7F0E33729964E7D0068AF69 /* XCRemoteSwiftPackageReference "lzstring-swift" */ = {
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1540"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES"
|
||||
buildArchitectures = "Automatic">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "CEE723A62C3BD3D70009AE93"
|
||||
BuildableName = "SimpleX SE.appex"
|
||||
BlueprintName = "SimpleX SE"
|
||||
ReferencedContainer = "container:SimpleX.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "5CA059C9279559F40002BEB4"
|
||||
BuildableName = "SimpleX.app"
|
||||
BlueprintName = "SimpleX (iOS)"
|
||||
ReferencedContainer = "container:SimpleX.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
launchStyle = "0"
|
||||
askForAppToLaunch = "Yes"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "5CA059C9279559F40002BEB4"
|
||||
BuildableName = "SimpleX.app"
|
||||
BlueprintName = "SimpleX (iOS)"
|
||||
ReferencedContainer = "container:SimpleX.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
askForAppToLaunch = "Yes"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "5CA059C9279559F40002BEB4"
|
||||
BuildableName = "SimpleX.app"
|
||||
BlueprintName = "SimpleX (iOS)"
|
||||
ReferencedContainer = "container:SimpleX.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -117,10 +117,10 @@ public func sendSimpleXCmd(_ cmd: ChatCommand, _ ctrl: chat_ctrl? = nil) -> Chat
|
||||
}
|
||||
|
||||
// in microseconds
|
||||
let MESSAGE_TIMEOUT: Int32 = 15_000_000
|
||||
public let MESSAGE_TIMEOUT: Int32 = 15_000_000
|
||||
|
||||
public func recvSimpleXMsg(_ ctrl: chat_ctrl? = nil) -> ChatResponse? {
|
||||
if let cjson = chat_recv_msg_wait(ctrl ?? getChatCtrl(), MESSAGE_TIMEOUT) {
|
||||
public func recvSimpleXMsg(_ ctrl: chat_ctrl? = nil, messageTimeout: Int32 = MESSAGE_TIMEOUT) -> ChatResponse? {
|
||||
if let cjson = chat_recv_msg_wait(ctrl ?? getChatCtrl(), messageTimeout) {
|
||||
let s = fromCString(cjson)
|
||||
return s == "" ? nil : chatResponse(s)
|
||||
}
|
||||
@@ -205,7 +205,7 @@ public func chatResponse(_ s: String) -> ChatResponse {
|
||||
if let chatData = try? parseChatData(jChat) {
|
||||
return chatData
|
||||
}
|
||||
return ChatData.invalidJSON(prettyJSON(jChat) ?? "")
|
||||
return ChatData.invalidJSON(serializeJSON(jChat, options: .prettyPrinted) ?? "")
|
||||
}
|
||||
return .apiChats(user: user, chats: chats)
|
||||
}
|
||||
@@ -218,15 +218,15 @@ public func chatResponse(_ s: String) -> ChatResponse {
|
||||
}
|
||||
} else if type == "chatCmdError" {
|
||||
if let jError = jResp["chatCmdError"] as? NSDictionary {
|
||||
return .chatCmdError(user_: decodeUser_(jError), chatError: .invalidJSON(json: prettyJSON(jError) ?? ""))
|
||||
return .chatCmdError(user_: decodeUser_(jError), chatError: .invalidJSON(json: errorJson(jError) ?? ""))
|
||||
}
|
||||
} else if type == "chatError" {
|
||||
if let jError = jResp["chatError"] as? NSDictionary {
|
||||
return .chatError(user_: decodeUser_(jError), chatError: .invalidJSON(json: prettyJSON(jError) ?? ""))
|
||||
return .chatError(user_: decodeUser_(jError), chatError: .invalidJSON(json: errorJson(jError) ?? ""))
|
||||
}
|
||||
}
|
||||
}
|
||||
json = prettyJSON(j)
|
||||
json = serializeJSON(j, options: .prettyPrinted)
|
||||
}
|
||||
return ChatResponse.response(type: type ?? "invalid", json: json ?? s)
|
||||
}
|
||||
@@ -239,6 +239,14 @@ private func decodeUser_(_ jDict: NSDictionary) -> UserRef? {
|
||||
}
|
||||
}
|
||||
|
||||
private func errorJson(_ jDict: NSDictionary) -> String? {
|
||||
if let chatError = jDict["chatError"] {
|
||||
serializeJSON(chatError)
|
||||
} else {
|
||||
serializeJSON(jDict)
|
||||
}
|
||||
}
|
||||
|
||||
func parseChatData(_ jChat: Any) throws -> ChatData {
|
||||
let jChatDict = jChat as! NSDictionary
|
||||
let chatInfo: ChatInfo = try decodeObject(jChatDict["chatInfo"]!)
|
||||
@@ -251,7 +259,7 @@ func parseChatData(_ jChat: Any) throws -> ChatData {
|
||||
return ChatItem.invalidJSON(
|
||||
chatDir: decodeProperty(jCI, "chatDir"),
|
||||
meta: decodeProperty(jCI, "meta"),
|
||||
json: prettyJSON(jCI) ?? ""
|
||||
json: serializeJSON(jCI, options: .prettyPrinted) ?? ""
|
||||
)
|
||||
}
|
||||
return ChatData(chatInfo: chatInfo, chatItems: chatItems, chatStats: chatStats)
|
||||
@@ -268,8 +276,8 @@ func decodeProperty<T: Decodable>(_ obj: Any, _ prop: NSString) -> T? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func prettyJSON(_ obj: Any) -> String? {
|
||||
if let d = try? JSONSerialization.data(withJSONObject: obj, options: .prettyPrinted) {
|
||||
func serializeJSON(_ obj: Any, options: JSONSerialization.WritingOptions = []) -> String? {
|
||||
if let d = try? JSONSerialization.data(withJSONObject: obj, options: options) {
|
||||
return String(decoding: d, as: UTF8.self)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -26,7 +26,8 @@ public enum ChatCommand {
|
||||
case apiMuteUser(userId: Int64)
|
||||
case apiUnmuteUser(userId: Int64)
|
||||
case apiDeleteUser(userId: Int64, delSMPQueues: Bool, viewPwd: String?)
|
||||
case startChat(mainApp: Bool)
|
||||
case startChat(mainApp: Bool, enableSndFiles: Bool)
|
||||
case checkChatRunning
|
||||
case apiStopChat
|
||||
case apiActivateChat(restoreChat: Bool)
|
||||
case apiSuspendChat(timeoutMicroseconds: Int)
|
||||
@@ -146,6 +147,7 @@ public enum ChatCommand {
|
||||
case apiStandaloneFileInfo(url: String)
|
||||
// misc
|
||||
case showVersion
|
||||
case getAgentSubsTotal(userId: Int64)
|
||||
case getAgentServersSummary(userId: Int64)
|
||||
case resetAgentServersStats
|
||||
case string(String)
|
||||
@@ -171,7 +173,8 @@ public enum ChatCommand {
|
||||
case let .apiMuteUser(userId): return "/_mute user \(userId)"
|
||||
case let .apiUnmuteUser(userId): return "/_unmute user \(userId)"
|
||||
case let .apiDeleteUser(userId, delSMPQueues, viewPwd): return "/_delete user \(userId) del_smp=\(onOff(delSMPQueues))\(maybePwd(viewPwd))"
|
||||
case let .startChat(mainApp): return "/_start main=\(onOff(mainApp))"
|
||||
case let .startChat(mainApp, enableSndFiles): return "/_start main=\(onOff(mainApp)) snd_files=\(onOff(enableSndFiles))"
|
||||
case .checkChatRunning: return "/_check running"
|
||||
case .apiStopChat: return "/_stop"
|
||||
case let .apiActivateChat(restore): return "/_app activate restore=\(onOff(restore))"
|
||||
case let .apiSuspendChat(timeoutMicroseconds): return "/_app suspend \(timeoutMicroseconds)"
|
||||
@@ -309,6 +312,7 @@ public enum ChatCommand {
|
||||
case let .apiDownloadStandaloneFile(userId, link, file): return "/_download \(userId) \(link) \(file.filePath)"
|
||||
case let .apiStandaloneFileInfo(link): return "/_download info \(link)"
|
||||
case .showVersion: return "/version"
|
||||
case let .getAgentSubsTotal(userId): return "/get subs total \(userId)"
|
||||
case let .getAgentServersSummary(userId): return "/get servers summary \(userId)"
|
||||
case .resetAgentServersStats: return "/reset servers stats"
|
||||
case let .string(str): return str
|
||||
@@ -332,6 +336,7 @@ public enum ChatCommand {
|
||||
case .apiUnmuteUser: return "apiUnmuteUser"
|
||||
case .apiDeleteUser: return "apiDeleteUser"
|
||||
case .startChat: return "startChat"
|
||||
case .checkChatRunning: return "checkChatRunning"
|
||||
case .apiStopChat: return "apiStopChat"
|
||||
case .apiActivateChat: return "apiActivateChat"
|
||||
case .apiSuspendChat: return "apiSuspendChat"
|
||||
@@ -447,6 +452,7 @@ public enum ChatCommand {
|
||||
case .apiDownloadStandaloneFile: return "apiDownloadStandaloneFile"
|
||||
case .apiStandaloneFileInfo: return "apiStandaloneFileInfo"
|
||||
case .showVersion: return "showVersion"
|
||||
case .getAgentSubsTotal: return "getAgentSubsTotal"
|
||||
case .getAgentServersSummary: return "getAgentServersSummary"
|
||||
case .resetAgentServersStats: return "resetAgentServersStats"
|
||||
case .string: return "console command"
|
||||
@@ -575,6 +581,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case userContactLinkDeleted(user: User)
|
||||
case contactConnected(user: UserRef, contact: Contact, userCustomProfile: Profile?)
|
||||
case contactConnecting(user: UserRef, contact: Contact)
|
||||
case contactSndReady(user: UserRef, contact: Contact)
|
||||
case receivedContactRequest(user: UserRef, contactRequest: UserContactRequest)
|
||||
case acceptingContactRequest(user: UserRef, contact: Contact)
|
||||
case contactRequestRejected(user: UserRef)
|
||||
@@ -661,7 +668,7 @@ 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?, ntfMessages: [NtfMsgInfo])
|
||||
case ntfMessages(user_: User?, connEntity_: ConnectionEntity?, msgTs: Date?, ntfMessage_: NtfMsgInfo?)
|
||||
case ntfMessage(user: UserRef, connEntity: ConnectionEntity, ntfMessage: NtfMsgInfo)
|
||||
case contactConnectionDeleted(user: UserRef, connection: PendingContactConnection)
|
||||
case contactDisabled(user: UserRef, contact: Contact)
|
||||
@@ -677,6 +684,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
// misc
|
||||
case versionInfo(versionInfo: CoreVersionInfo, chatMigrations: [UpMigration], agentMigrations: [UpMigration])
|
||||
case cmdOk(user: UserRef?)
|
||||
case agentSubsTotal(user: UserRef, subsTotal: SMPServerSubs, hasSession: Bool)
|
||||
case agentServersSummary(user: UserRef, serversSummary: PresentedServersSummary)
|
||||
case agentSubsSummary(user: UserRef, subsSummary: SMPServerSubs)
|
||||
case chatCmdError(user_: UserRef?, chatError: ChatError)
|
||||
@@ -742,6 +750,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case .userContactLinkDeleted: return "userContactLinkDeleted"
|
||||
case .contactConnected: return "contactConnected"
|
||||
case .contactConnecting: return "contactConnecting"
|
||||
case .contactSndReady: return "contactSndReady"
|
||||
case .receivedContactRequest: return "receivedContactRequest"
|
||||
case .acceptingContactRequest: return "acceptingContactRequest"
|
||||
case .contactRequestRejected: return "contactRequestRejected"
|
||||
@@ -837,6 +846,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case .contactPQEnabled: return "contactPQEnabled"
|
||||
case .versionInfo: return "versionInfo"
|
||||
case .cmdOk: return "cmdOk"
|
||||
case .agentSubsTotal: return "agentSubsTotal"
|
||||
case .agentServersSummary: return "agentServersSummary"
|
||||
case .agentSubsSummary: return "agentSubsSummary"
|
||||
case .chatCmdError: return "chatCmdError"
|
||||
@@ -907,6 +917,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case .userContactLinkDeleted: return noDetails
|
||||
case let .contactConnected(u, contact, _): return withUser(u, String(describing: contact))
|
||||
case let .contactConnecting(u, contact): return withUser(u, String(describing: contact))
|
||||
case let .contactSndReady(u, contact): return withUser(u, String(describing: contact))
|
||||
case let .receivedContactRequest(u, contactRequest): return withUser(u, String(describing: contactRequest))
|
||||
case let .acceptingContactRequest(u, contact): return withUser(u, String(describing: contact))
|
||||
case .contactRequestRejected: return noDetails
|
||||
@@ -1002,6 +1013,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case let .contactPQEnabled(u, contact, pqEnabled): return withUser(u, "contact: \(String(describing: contact))\npqEnabled: \(pqEnabled)")
|
||||
case let .versionInfo(versionInfo, chatMigrations, agentMigrations): return "\(String(describing: versionInfo))\n\nchat migrations: \(chatMigrations.map(\.upName))\n\nagent migrations: \(agentMigrations.map(\.upName))"
|
||||
case .cmdOk: return noDetails
|
||||
case let .agentSubsTotal(u, subsTotal, hasSession): return withUser(u, "subsTotal: \(String(describing: subsTotal))\nhasSession: \(hasSession)")
|
||||
case let .agentServersSummary(u, serversSummary): return withUser(u, String(describing: serversSummary))
|
||||
case let .agentSubsSummary(u, subsSummary): return withUser(u, String(describing: subsSummary))
|
||||
case let .chatCmdError(u, chatError): return withUser(u, String(describing: chatError))
|
||||
@@ -1228,7 +1240,7 @@ public struct ProtocolTestFailure: Decodable, Error, Equatable {
|
||||
public var localizedDescription: String {
|
||||
let err = String.localizedStringWithFormat(NSLocalizedString("Test failed at step %@.", comment: "server test failure"), testStep.text)
|
||||
switch testError {
|
||||
case .SMP(.AUTH):
|
||||
case .SMP(_, .AUTH):
|
||||
return err + " " + NSLocalizedString("Server requires authorization to create queues, check password", comment: "server test error")
|
||||
case .XFTP(.AUTH):
|
||||
return err + " " + NSLocalizedString("Server requires authorization to upload, check password", comment: "server test error")
|
||||
@@ -1887,7 +1899,7 @@ public enum SQLiteError: Decodable, Hashable {
|
||||
public enum AgentErrorType: Decodable, Hashable {
|
||||
case CMD(cmdErr: CommandErrorType)
|
||||
case CONN(connErr: ConnectionErrorType)
|
||||
case SMP(smpErr: ProtocolErrorType)
|
||||
case SMP(serverAddress: String, smpErr: ProtocolErrorType)
|
||||
case NTF(ntfErr: ProtocolErrorType)
|
||||
case XFTP(xftpErr: XFTPErrorType)
|
||||
case PROXY(proxyServer: String, relayServer: String, proxyErr: ProxyClientError)
|
||||
@@ -2087,6 +2099,7 @@ public struct AppSettings: Codable, Equatable, Hashable {
|
||||
public var privacyShowChatPreviews: Bool? = nil
|
||||
public var privacySaveLastDraft: Bool? = nil
|
||||
public var privacyProtectScreen: Bool? = nil
|
||||
public var privacyMediaBlurRadius: Int? = nil
|
||||
public var notificationMode: AppSettingsNotificationMode? = nil
|
||||
public var notificationPreviewMode: NotificationPreviewMode? = nil
|
||||
public var webrtcPolicyRelay: Bool? = nil
|
||||
@@ -2116,6 +2129,7 @@ public struct AppSettings: Codable, Equatable, Hashable {
|
||||
if privacyShowChatPreviews != def.privacyShowChatPreviews { empty.privacyShowChatPreviews = privacyShowChatPreviews }
|
||||
if privacySaveLastDraft != def.privacySaveLastDraft { empty.privacySaveLastDraft = privacySaveLastDraft }
|
||||
if privacyProtectScreen != def.privacyProtectScreen { empty.privacyProtectScreen = privacyProtectScreen }
|
||||
if privacyMediaBlurRadius != def.privacyMediaBlurRadius { empty.privacyMediaBlurRadius = privacyMediaBlurRadius }
|
||||
if notificationMode != def.notificationMode { empty.notificationMode = notificationMode }
|
||||
if notificationPreviewMode != def.notificationPreviewMode { empty.notificationPreviewMode = notificationPreviewMode }
|
||||
if webrtcPolicyRelay != def.webrtcPolicyRelay { empty.webrtcPolicyRelay = webrtcPolicyRelay }
|
||||
@@ -2146,6 +2160,7 @@ public struct AppSettings: Codable, Equatable, Hashable {
|
||||
privacyShowChatPreviews: true,
|
||||
privacySaveLastDraft: true,
|
||||
privacyProtectScreen: false,
|
||||
privacyMediaBlurRadius: 0,
|
||||
notificationMode: AppSettingsNotificationMode.instant,
|
||||
notificationPreviewMode: NotificationPreviewMode.message,
|
||||
webrtcPolicyRelay: true,
|
||||
@@ -2321,6 +2336,8 @@ public struct ServerSessions: Codable {
|
||||
ssErrors: 0,
|
||||
ssConnecting: 0
|
||||
)
|
||||
|
||||
public var hasSess: Bool { ssConnected > 0 }
|
||||
}
|
||||
|
||||
public struct SMPServerSubs: Codable {
|
||||
@@ -2374,6 +2391,10 @@ public struct AgentSMPServerStatsData: Codable {
|
||||
public var _connSubAttempts: Int
|
||||
public var _connSubIgnored: Int
|
||||
public var _connSubErrs: Int
|
||||
public var _ntfKey: Int
|
||||
public var _ntfKeyAttempts: Int
|
||||
public var _ntfKeyDeleted: Int
|
||||
public var _ntfKeyDeleteAttempts: Int
|
||||
}
|
||||
|
||||
public struct XFTPServersSummary: Codable {
|
||||
@@ -2413,3 +2434,12 @@ public struct AgentXFTPServerStatsData: Codable {
|
||||
public var _deleteAttempts: Int
|
||||
public var _deleteErrs: Int
|
||||
}
|
||||
|
||||
public struct AgentNtfServerStatsData: Codable {
|
||||
public var _ntfCreated: Int
|
||||
public var _ntfCreateAttempts: Int
|
||||
public var _ntfChecked: Int
|
||||
public var _ntfCheckAttempts: Int
|
||||
public var _ntfDeleted: Int
|
||||
public var _ntfDelAttempts: Int
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public let appSuspendTimeout: Int = 15 // seconds
|
||||
|
||||
let GROUP_DEFAULT_APP_STATE = "appState"
|
||||
let GROUP_DEFAULT_NSE_STATE = "nseState"
|
||||
let GROUP_DEFAULT_SE_STATE = "seState"
|
||||
let GROUP_DEFAULT_DB_CONTAINER = "dbContainer"
|
||||
public let GROUP_DEFAULT_CHAT_LAST_START = "chatLastStart"
|
||||
public let GROUP_DEFAULT_CHAT_LAST_BACKGROUND_RUN = "chatLastBackgroundRun"
|
||||
@@ -136,6 +137,11 @@ public enum NSEState: String, Codable {
|
||||
}
|
||||
}
|
||||
|
||||
public enum SEState: String, Codable {
|
||||
case inactive
|
||||
case sendingMessage
|
||||
}
|
||||
|
||||
public enum DBContainer: String {
|
||||
case documents
|
||||
case group
|
||||
@@ -155,6 +161,12 @@ public let nseStateGroupDefault = EnumDefault<NSEState>(
|
||||
withDefault: .suspended // so that NSE that was never launched does not delay the app from resuming
|
||||
)
|
||||
|
||||
public let seStateGroupDefault = EnumDefault<SEState>(
|
||||
defaults: groupDefaults,
|
||||
forKey: GROUP_DEFAULT_SE_STATE,
|
||||
withDefault: .inactive
|
||||
)
|
||||
|
||||
// inactive app states do not include "stopped" state
|
||||
public func allowBackgroundRefresh() -> Bool {
|
||||
appStateGroupDefault.get().inactive && nseStateGroupDefault.get().inactive
|
||||
|
||||
@@ -1463,7 +1463,7 @@ public enum ChatInfo: Identifiable, Decodable, NamedChat, Hashable {
|
||||
)
|
||||
}
|
||||
|
||||
public struct ChatData: Decodable, Identifiable, Hashable {
|
||||
public struct ChatData: Decodable, Identifiable, Hashable, ChatLike {
|
||||
public var chatInfo: ChatInfo
|
||||
public var chatItems: [ChatItem]
|
||||
public var chatStats: ChatStats
|
||||
@@ -1512,10 +1512,11 @@ public struct Contact: Identifiable, Decodable, NamedChat, Hashable {
|
||||
public var id: ChatId { get { "@\(contactId)" } }
|
||||
public var apiId: Int64 { get { contactId } }
|
||||
public var ready: Bool { get { activeConn?.connStatus == .ready } }
|
||||
public var sndReady: Bool { get { ready || activeConn?.connStatus == .sndReady } }
|
||||
public var active: Bool { get { contactStatus == .active } }
|
||||
public var sendMsgEnabled: Bool { get {
|
||||
(
|
||||
ready
|
||||
sndReady
|
||||
&& active
|
||||
&& !(activeConn?.connectionStats?.ratchetSyncSendProhibited ?? false)
|
||||
&& !(activeConn?.connDisabled ?? true)
|
||||
@@ -1824,7 +1825,7 @@ public enum ConnStatus: String, Decodable, Hashable {
|
||||
case .joined: return false
|
||||
case .requested: return true
|
||||
case .accepted: return true
|
||||
case .sndReady: return false
|
||||
case .sndReady: return nil
|
||||
case .ready: return nil
|
||||
case .deleted: return nil
|
||||
}
|
||||
@@ -3293,6 +3294,28 @@ public struct CIFile: Decodable, Hashable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var showStatusIconInSmallView: Bool {
|
||||
get {
|
||||
switch fileStatus {
|
||||
case .sndStored: fileProtocol != .local
|
||||
case .sndTransfer: true
|
||||
case .sndComplete: false
|
||||
case .sndCancelled: true
|
||||
case .sndError: true
|
||||
case .sndWarning: true
|
||||
case .rcvInvitation: false
|
||||
case .rcvAccepted: true
|
||||
case .rcvTransfer: true
|
||||
case .rcvAborted: true
|
||||
case .rcvCancelled: true
|
||||
case .rcvComplete: false
|
||||
case .rcvError: true
|
||||
case .rcvWarning: true
|
||||
case .invalid: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct CryptoFile: Codable, Hashable {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// ChatUtils.swift
|
||||
// SimpleXChat
|
||||
//
|
||||
// Created by Levitating Pineapple on 15/07/2024.
|
||||
// Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol ChatLike {
|
||||
var chatInfo: ChatInfo { get}
|
||||
var chatItems: [ChatItem] { get }
|
||||
var chatStats: ChatStats { get }
|
||||
}
|
||||
|
||||
public func filterChatsToForwardTo<C: ChatLike>(chats: [C]) -> [C] {
|
||||
var filteredChats = chats.filter { c in
|
||||
c.chatInfo.chatType != .local && canForwardToChat(c.chatInfo)
|
||||
}
|
||||
if let privateNotes = chats.first(where: { $0.chatInfo.chatType == .local }) {
|
||||
filteredChats.insert(privateNotes, at: 0)
|
||||
}
|
||||
return filteredChats
|
||||
}
|
||||
|
||||
public func foundChat(_ chat: ChatLike, _ searchStr: String) -> Bool {
|
||||
let cInfo = chat.chatInfo
|
||||
return switch cInfo {
|
||||
case let .direct(contact):
|
||||
viewNameContains(cInfo, searchStr) ||
|
||||
contact.profile.displayName.localizedLowercase.contains(searchStr) ||
|
||||
contact.fullName.localizedLowercase.contains(searchStr)
|
||||
default:
|
||||
viewNameContains(cInfo, searchStr)
|
||||
}
|
||||
|
||||
func viewNameContains(_ cInfo: ChatInfo, _ s: String) -> Bool {
|
||||
cInfo.chatViewName.localizedLowercase.contains(s)
|
||||
}
|
||||
}
|
||||
|
||||
private func canForwardToChat(_ cInfo: ChatInfo) -> Bool {
|
||||
switch cInfo {
|
||||
case let .direct(contact): contact.sendMsgEnabled && !contact.nextSendGrpInv
|
||||
case let .group(groupInfo): groupInfo.sendMsgEnabled
|
||||
case let .local(noteFolder): noteFolder.sendMsgEnabled
|
||||
case .contactRequest: false
|
||||
case .contactConnection: false
|
||||
case .invalidJSON: false
|
||||
}
|
||||
}
|
||||
|
||||
public func chatIconName(_ cInfo: ChatInfo) -> String {
|
||||
switch cInfo {
|
||||
case .direct: "person.crop.circle.fill"
|
||||
case .group: "person.2.circle.fill"
|
||||
case .local: "folder.circle.fill"
|
||||
case .contactRequest: "person.crop.circle.fill"
|
||||
default: "circle.fill"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
//
|
||||
// ErrorAlert.swift
|
||||
// SimpleXChat
|
||||
//
|
||||
// Created by Levitating Pineapple on 20/07/2024.
|
||||
// Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
public struct ErrorAlert: Error {
|
||||
public let title: LocalizedStringKey
|
||||
public let message: LocalizedStringKey?
|
||||
public let actions: Optional<() -> AnyView>
|
||||
|
||||
public init(
|
||||
title: LocalizedStringKey,
|
||||
message: LocalizedStringKey? = nil
|
||||
) {
|
||||
self.title = title
|
||||
self.message = message
|
||||
self.actions = nil
|
||||
}
|
||||
|
||||
public init<A: View>(
|
||||
title: LocalizedStringKey,
|
||||
message: LocalizedStringKey? = nil,
|
||||
@ViewBuilder actions: @escaping () -> A
|
||||
) {
|
||||
self.title = title
|
||||
self.message = message
|
||||
self.actions = { AnyView(actions()) }
|
||||
}
|
||||
|
||||
public init(_ title: LocalizedStringKey) {
|
||||
self = ErrorAlert(title: title)
|
||||
}
|
||||
|
||||
public init(_ error: any Error) {
|
||||
self = if let chatResponse = error as? ChatResponse {
|
||||
ErrorAlert(chatResponse)
|
||||
} else {
|
||||
ErrorAlert(LocalizedStringKey(error.localizedDescription))
|
||||
}
|
||||
}
|
||||
|
||||
public init(_ chatError: ChatError) {
|
||||
self = ErrorAlert("\(chatErrorString(chatError))")
|
||||
}
|
||||
|
||||
public init(_ chatResponse: ChatResponse) {
|
||||
self = if let networkErrorAlert = getNetworkErrorAlert(chatResponse) {
|
||||
networkErrorAlert
|
||||
} else {
|
||||
ErrorAlert("\(responseError(chatResponse))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension LocalizedStringKey: @unchecked Sendable { }
|
||||
|
||||
extension View {
|
||||
/// Bridges ``ErrorAlert`` to the generic alert API.
|
||||
/// - Parameters:
|
||||
/// - errorAlert: Binding to the Error, which is rendered in the alert
|
||||
/// - actions: View Builder containing action buttons.
|
||||
/// System defaults to `Ok` dismiss error action, when no actions are provided.
|
||||
/// System implicitly adds `Cancel` action, if a destructive action is present
|
||||
///
|
||||
/// - Returns: View, which displays ErrorAlert?, when set.
|
||||
@ViewBuilder public func alert<A: View>(
|
||||
_ errorAlert: Binding<ErrorAlert?>,
|
||||
@ViewBuilder actions: (ErrorAlert) -> A = { _ in EmptyView() }
|
||||
) -> some View {
|
||||
if let alert = errorAlert.wrappedValue {
|
||||
self.alert(
|
||||
alert.title,
|
||||
isPresented: Binding<Bool>(
|
||||
get: { errorAlert.wrappedValue != nil },
|
||||
set: { if !$0 { errorAlert.wrappedValue = nil } }
|
||||
),
|
||||
actions: {
|
||||
if let actions_ = alert.actions {
|
||||
actions_()
|
||||
} else {
|
||||
actions(alert)
|
||||
}
|
||||
},
|
||||
message: {
|
||||
if let message = alert.message { Text(message) }
|
||||
}
|
||||
)
|
||||
} else { self }
|
||||
}
|
||||
}
|
||||
|
||||
public func getNetworkErrorAlert(_ r: ChatResponse) -> ErrorAlert? {
|
||||
switch r {
|
||||
case let .chatCmdError(_, .errorAgent(.BROKER(addr, .TIMEOUT))):
|
||||
return ErrorAlert(title: "Connection timeout", message: "Please check your network connection with \(serverHostname(addr)) and try again.")
|
||||
case let .chatCmdError(_, .errorAgent(.BROKER(addr, .NETWORK))):
|
||||
return ErrorAlert(title: "Connection error", message: "Please check your network connection with \(serverHostname(addr)) and try again.")
|
||||
case let .chatCmdError(_, .errorAgent(.BROKER(addr, .HOST))):
|
||||
return ErrorAlert(title: "Connection error", message: "Server address is incompatible with network settings: \(serverHostname(addr)).")
|
||||
case let .chatCmdError(_, .errorAgent(.BROKER(addr, .TRANSPORT(.version)))):
|
||||
return ErrorAlert(title: "Connection error", message: "Server version is incompatible with your app: \(serverHostname(addr)).")
|
||||
case let .chatCmdError(_, .errorAgent(.SMP(serverAddress, .PROXY(proxyErr)))):
|
||||
return smpProxyErrorAlert(proxyErr, serverAddress)
|
||||
case let .chatCmdError(_, .errorAgent(.PROXY(proxyServer, relayServer, .protocolError(.PROXY(proxyErr))))):
|
||||
return proxyDestinationErrorAlert(proxyErr, proxyServer, relayServer)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
private func smpProxyErrorAlert(_ proxyErr: ProxyError, _ srvAddr: String) -> ErrorAlert? {
|
||||
switch proxyErr {
|
||||
case .BROKER(brokerErr: .TIMEOUT):
|
||||
return ErrorAlert(title: "Private routing error", message: "Error connecting to forwarding server \(serverHostname(srvAddr)). Please try later.")
|
||||
case .BROKER(brokerErr: .NETWORK):
|
||||
return ErrorAlert(title: "Private routing error", message: "Error connecting to forwarding server \(serverHostname(srvAddr)). Please try later.")
|
||||
case .BROKER(brokerErr: .HOST):
|
||||
return ErrorAlert(title: "Private routing error", message: "Forwarding server address is incompatible with network settings: \(serverHostname(srvAddr)).")
|
||||
case .BROKER(brokerErr: .TRANSPORT(.version)):
|
||||
return ErrorAlert(title: "Private routing error", message: "Forwarding server version is incompatible with network settings: \(serverHostname(srvAddr)).")
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
private func proxyDestinationErrorAlert(_ proxyErr: ProxyError, _ proxyServer: String, _ relayServer: String) -> ErrorAlert? {
|
||||
switch proxyErr {
|
||||
case .BROKER(brokerErr: .TIMEOUT):
|
||||
return ErrorAlert(title: "Private routing error", message: "Forwarding server \(serverHostname(proxyServer)) failed to connect to destination server \(serverHostname(relayServer)). Please try later.")
|
||||
case .BROKER(brokerErr: .NETWORK):
|
||||
return ErrorAlert(title: "Private routing error", message: "Forwarding server \(serverHostname(proxyServer)) failed to connect to destination server \(serverHostname(relayServer)). Please try later.")
|
||||
case .NO_SESSION:
|
||||
return ErrorAlert(title: "Private routing error", message: "Forwarding server \(serverHostname(proxyServer)) failed to connect to destination server \(serverHostname(relayServer)). Please try later.")
|
||||
case .BROKER(brokerErr: .HOST):
|
||||
return ErrorAlert(title: "Private routing error", message: "Destination server address of \(serverHostname(relayServer)) is incompatible with forwarding server \(serverHostname(proxyServer)) settings.")
|
||||
case .BROKER(brokerErr: .TRANSPORT(.version)):
|
||||
return ErrorAlert(title: "Private routing error", message: "Destination server version of \(serverHostname(relayServer)) is incompatible with forwarding server \(serverHostname(proxyServer)).")
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public func serverHostname(_ srv: String) -> String {
|
||||
parseServerAddress(srv)?.hostnames.first ?? srv
|
||||
}
|
||||
|
||||
public func mtrErrorDescription(_ err: MTRError) -> LocalizedStringKey {
|
||||
switch err {
|
||||
case let .noDown(dbMigrations):
|
||||
"database version is newer than the app, but no down migration for: \(dbMigrations.joined(separator: ", "))"
|
||||
case let .different(appMigration, dbMigration):
|
||||
"different migration in the app/database: \(appMigration) / \(dbMigration)"
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import Foundation
|
||||
import SwiftUI
|
||||
import AVKit
|
||||
import SwiftyGif
|
||||
import LinkPresentation
|
||||
|
||||
public func getLoadedFileSource(_ file: CIFile?) -> CryptoFile? {
|
||||
if let file = file, file.loaded {
|
||||
@@ -158,6 +159,34 @@ public func imageHasAlpha(_ img: UIImage) -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
/// Reduces image size, while consuming less RAM
|
||||
///
|
||||
/// Used by ShareExtension to downsize large images
|
||||
/// before passing them to regular image processing pipeline
|
||||
/// to avoid exceeding 120MB memory
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - url: Location of the image data
|
||||
/// - size: Maximum dimension (width or height)
|
||||
/// - Returns: Downsampled image or `nil`, if the image can't be located
|
||||
public func downsampleImage(at url: URL, to size: Int64) -> UIImage? {
|
||||
autoreleasepool {
|
||||
if let source = CGImageSourceCreateWithURL(url as CFURL, nil) {
|
||||
CGImageSourceCreateThumbnailAtIndex(
|
||||
source,
|
||||
Int.zero,
|
||||
[
|
||||
kCGImageSourceCreateThumbnailFromImageAlways: true,
|
||||
kCGImageSourceShouldCacheImmediately: true,
|
||||
kCGImageSourceCreateThumbnailWithTransform: true,
|
||||
kCGImageSourceThumbnailMaxPixelSize: String(size) as CFString
|
||||
] as CFDictionary
|
||||
)
|
||||
.map { UIImage(cgImage: $0) }
|
||||
} else { nil }
|
||||
}
|
||||
}
|
||||
|
||||
public func saveFileFromURL(_ url: URL) -> CryptoFile? {
|
||||
let encrypted = privacyEncryptLocalFilesGroupDefault.get()
|
||||
let savedFile: CryptoFile?
|
||||
@@ -281,6 +310,21 @@ private func dropPrefix(_ s: String, _ prefix: String) -> String {
|
||||
s.hasPrefix(prefix) ? String(s.dropFirst(prefix.count)) : s
|
||||
}
|
||||
|
||||
public func makeVideoQualityLower(_ input: URL, outputUrl: URL) async -> Bool {
|
||||
let asset: AVURLAsset = AVURLAsset(url: input, options: nil)
|
||||
if let s = AVAssetExportSession(asset: asset, presetName: AVAssetExportPreset640x480) {
|
||||
s.outputURL = outputUrl
|
||||
s.outputFileType = .mp4
|
||||
s.metadataItemFilter = AVMetadataItemFilter.forSharing()
|
||||
await s.export()
|
||||
if let err = s.error {
|
||||
logger.error("Failed to export video with error: \(err)")
|
||||
}
|
||||
return s.status == .completed
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
extension AVAsset {
|
||||
public func generatePreview() -> (UIImage, Int)? {
|
||||
let generator = AVAssetImageGenerator(asset: self)
|
||||
@@ -348,3 +392,39 @@ extension UIImage {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func getLinkPreview(url: URL, cb: @escaping (LinkPreview?) -> Void) {
|
||||
logger.debug("getLinkMetadata: fetching URL preview")
|
||||
LPMetadataProvider().startFetchingMetadata(for: url){ metadata, error in
|
||||
if let e = error {
|
||||
logger.error("Error retrieving link metadata: \(e.localizedDescription)")
|
||||
}
|
||||
if let metadata = metadata,
|
||||
let imageProvider = metadata.imageProvider,
|
||||
imageProvider.canLoadObject(ofClass: UIImage.self) {
|
||||
imageProvider.loadObject(ofClass: UIImage.self){ object, error in
|
||||
var linkPreview: LinkPreview? = nil
|
||||
if let error = error {
|
||||
logger.error("Couldn't load image preview from link metadata with error: \(error.localizedDescription)")
|
||||
} else {
|
||||
if let image = object as? UIImage,
|
||||
let resized = resizeImageToStrSize(image, maxDataSize: 14000),
|
||||
let title = metadata.title,
|
||||
let uri = metadata.originalURL {
|
||||
linkPreview = LinkPreview(uri: uri, title: title, image: resized)
|
||||
}
|
||||
}
|
||||
cb(linkPreview)
|
||||
}
|
||||
} else {
|
||||
logger.error("Could not load link preview image")
|
||||
cb(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func getLinkPreview(for url: URL) async -> LinkPreview? {
|
||||
await withCheckedContinuation { cont in
|
||||
getLinkPreview(url: url) { cont.resume(returning: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public func createContactConnectedNtf(_ user: any UserLike, _ contact: Contact)
|
||||
hideContent ? NSLocalizedString("A new contact", comment: "notification title") : contact.displayName
|
||||
),
|
||||
body: String.localizedStringWithFormat(
|
||||
NSLocalizedString("You can now send messages to %@", comment: "notification body"),
|
||||
NSLocalizedString("You can now chat with %@", comment: "notification body"),
|
||||
hideContent ? NSLocalizedString("this contact", comment: "notification title") : contact.chatViewName
|
||||
),
|
||||
targetContentIdentifier: contact.id,
|
||||
|
||||
@@ -12,6 +12,8 @@ public typealias AppSubscriber = SharedFileSubscriber<ProcessMessage<AppProcessM
|
||||
|
||||
public typealias NSESubscriber = SharedFileSubscriber<ProcessMessage<NSEProcessMessage>>
|
||||
|
||||
public typealias SESubscriber = SharedFileSubscriber<ProcessMessage<SEProcessMessage>>
|
||||
|
||||
public class SharedFileSubscriber<Message: Codable>: NSObject, NSFilePresenter {
|
||||
var fileURL: URL
|
||||
public var presentedItemURL: URL?
|
||||
@@ -57,6 +59,8 @@ let appMessagesSharedFile = getGroupContainerDirectory().appendingPathComponent(
|
||||
|
||||
let nseMessagesSharedFile = getGroupContainerDirectory().appendingPathComponent("chat.simplex.app.SimpleX-NSE.messages", isDirectory: false)
|
||||
|
||||
let seMessagesSharedFile = getGroupContainerDirectory().appendingPathComponent("chat.simplex.app.SimpleX-SE.messages", isDirectory: false)
|
||||
|
||||
public struct ProcessMessage<Message: Codable>: Codable {
|
||||
var createdAt: Date = Date.now
|
||||
var message: Message
|
||||
@@ -70,6 +74,10 @@ public enum NSEProcessMessage: Codable {
|
||||
case state(state: NSEState)
|
||||
}
|
||||
|
||||
public enum SEProcessMessage: Codable {
|
||||
case state(state: SEState)
|
||||
}
|
||||
|
||||
public func sendAppProcessMessage(_ message: AppProcessMessage) {
|
||||
SharedFileSubscriber.notify(url: appMessagesSharedFile, message: ProcessMessage(message: message))
|
||||
}
|
||||
@@ -78,6 +86,10 @@ public func sendNSEProcessMessage(_ message: NSEProcessMessage) {
|
||||
SharedFileSubscriber.notify(url: nseMessagesSharedFile, message: ProcessMessage(message: message))
|
||||
}
|
||||
|
||||
public func sendSEProcessMessage(_ message: SEProcessMessage) {
|
||||
SharedFileSubscriber.notify(url: seMessagesSharedFile, message: ProcessMessage(message: message))
|
||||
}
|
||||
|
||||
public func appMessageSubscriber(onMessage: @escaping (AppProcessMessage) -> Void) -> AppSubscriber {
|
||||
SharedFileSubscriber(fileURL: appMessagesSharedFile) { (msg: ProcessMessage<AppProcessMessage>) in
|
||||
onMessage(msg.message)
|
||||
@@ -90,6 +102,12 @@ public func nseMessageSubscriber(onMessage: @escaping (NSEProcessMessage) -> Voi
|
||||
}
|
||||
}
|
||||
|
||||
public func seMessageSubscriber(onMessage: @escaping (SEProcessMessage) -> Void) -> SESubscriber {
|
||||
SharedFileSubscriber(fileURL: seMessagesSharedFile) { (msg: ProcessMessage<SEProcessMessage>) in
|
||||
onMessage(msg.message)
|
||||
}
|
||||
}
|
||||
|
||||
public func sendAppState(_ state: AppState) {
|
||||
sendAppProcessMessage(.state(state: state))
|
||||
}
|
||||
@@ -97,3 +115,7 @@ public func sendAppState(_ state: AppState) {
|
||||
public func sendNSEState(_ state: NSEState) {
|
||||
sendNSEProcessMessage(.state(state: state))
|
||||
}
|
||||
|
||||
public func sendSEState(_ state: SEState) {
|
||||
sendSEProcessMessage(.state(state: state))
|
||||
}
|
||||
|
||||
@@ -39,3 +39,19 @@ void haskell_init_nse(void) {
|
||||
char **pargv = argv;
|
||||
hs_init_with_rtsopts(&argc, &pargv);
|
||||
}
|
||||
|
||||
void haskell_init_se(void) {
|
||||
int argc = 7;
|
||||
char *argv[] = {
|
||||
"simplex",
|
||||
"+RTS", // requires `hs_init_with_rtsopts`
|
||||
"-A1m", // chunk size for new allocations
|
||||
"-H1m", // initial heap size
|
||||
"-F0.5", // heap growth triggering GC
|
||||
"-Fd1", // memory return
|
||||
"-c", // compacting garbage collector
|
||||
0
|
||||
};
|
||||
char **pargv = argv;
|
||||
hs_init_with_rtsopts(&argc, &pargv);
|
||||
}
|
||||
|
||||
@@ -13,4 +13,6 @@ void haskell_init(void);
|
||||
|
||||
void haskell_init_nse(void);
|
||||
|
||||
void haskell_init_se(void);
|
||||
|
||||
#endif /* hs_init_h */
|
||||
|
||||
@@ -154,9 +154,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ е потвърдено";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ сървъри";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ качено";
|
||||
|
||||
@@ -644,7 +641,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "блокиран %@";
|
||||
|
||||
/* blocked chat item */
|
||||
/* marked deleted chat item preview text */
|
||||
"blocked by admin" = "блокиран от админ";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -4297,7 +4294,7 @@
|
||||
"You can make it visible to your SimpleX contacts via Settings." = "Можете да го направите видим за вашите контакти в SimpleX чрез Настройки.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Вече можете да изпращате съобщения до %@";
|
||||
"You can now chat with %@" = "Вече можете да изпращате съобщения до %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "Можете да зададете визуализация на известията на заключен екран през настройките.";
|
||||
|
||||
@@ -130,9 +130,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ je ověřený";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ servery";
|
||||
|
||||
/* notification title */
|
||||
"%@ wants to connect!" = "%@ se chce připojit!";
|
||||
|
||||
@@ -3439,7 +3436,7 @@
|
||||
"You can hide or mute a user profile - swipe it to the right." = "Profil uživatele můžete skrýt nebo ztlumit - přejeďte prstem doprava.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Nyní můžete posílat zprávy %@";
|
||||
"You can now chat with %@" = "Nyní můžete posílat zprávy %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "Náhled oznámení na zamykací obrazovce můžete změnit v nastavení.";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
"CFBundleName" = "SimpleX";
|
||||
|
||||
/* Privacy - Camera Usage Description */
|
||||
"NSCameraUsageDescription" = "SimpleX benötigt Zugriff auf die Kamera, um QR Codes für die Verbindung mit anderen Nutzern zu scannen und Videoanrufe durchzuführen.";
|
||||
"NSCameraUsageDescription" = "SimpleX benötigt Zugriff auf die Kamera, um QR Codes für die Verbindung mit anderen Benutzern zu scannen und Videoanrufe durchzuführen.";
|
||||
|
||||
/* Privacy - Face ID Usage Description */
|
||||
"NSFaceIDUsageDescription" = "Face ID wird von SimpleX für die lokale Authentifizierung genutzt";
|
||||
|
||||
@@ -154,9 +154,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ está verificado";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "Servidores %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ subido";
|
||||
|
||||
@@ -650,7 +647,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "ha bloqueado a %@";
|
||||
|
||||
/* blocked chat item */
|
||||
/* marked deleted chat item preview text */
|
||||
"blocked by admin" = "bloqueado por administrador";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -4417,7 +4414,7 @@
|
||||
"You can make it visible to your SimpleX contacts via Settings." = "Puedes hacerlo visible para tus contactos de SimpleX en Configuración.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Ya puedes enviar mensajes a %@";
|
||||
"You can now chat with %@" = "Ya puedes enviar mensajes a %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "Puedes configurar las notificaciones de la pantalla de bloqueo desde Configuración.";
|
||||
|
||||
@@ -121,9 +121,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ on vahvistettu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ palvelimet";
|
||||
|
||||
/* notification title */
|
||||
"%@ wants to connect!" = "%@ haluaa muodostaa yhteyden!";
|
||||
|
||||
@@ -3397,7 +3394,7 @@
|
||||
"You can hide or mute a user profile - swipe it to the right." = "Voit piilottaa tai mykistää käyttäjäprofiilin pyyhkäisemällä sitä oikealle.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Voit nyt lähettää viestejä %@:lle";
|
||||
"You can now chat with %@" = "Voit nyt lähettää viestejä %@:lle";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "Voit määrittää lukitusnäytön ilmoituksen esikatselun asetuksista.";
|
||||
|
||||
@@ -154,9 +154,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ est vérifié·e";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "Serveurs %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ envoyé";
|
||||
|
||||
@@ -650,7 +647,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "%@ bloqué";
|
||||
|
||||
/* blocked chat item */
|
||||
/* marked deleted chat item preview text */
|
||||
"blocked by admin" = "bloqué par l'administrateur";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -4417,7 +4414,7 @@
|
||||
"You can make it visible to your SimpleX contacts via Settings." = "Vous pouvez le rendre visible à vos contacts SimpleX via Paramètres.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Vous pouvez maintenant envoyer des messages à %@";
|
||||
"You can now chat with %@" = "Vous pouvez maintenant envoyer des messages à %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "Vous pouvez configurer l'aperçu des notifications sur l'écran de verrouillage via les paramètres.";
|
||||
|
||||
@@ -154,9 +154,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ ellenőrizve";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ kiszolgáló";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ feltöltve";
|
||||
|
||||
@@ -337,6 +334,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "gombra fent, majd válassza ki:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent" = "Kiemelés";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Elfogadás";
|
||||
@@ -353,6 +353,12 @@
|
||||
/* call status */
|
||||
"accepted call" = "elfogadott hívás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Acknowledged" = "Nyugtázva";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Acknowledgement errors" = "Nyugtázott hibák";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." = "Cím hozzáadása a profilhoz, hogy az ismerősei megoszthassák másokkal. A profilfrissítés elküldésre kerül az ismerősei számára.";
|
||||
|
||||
@@ -377,6 +383,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Add welcome message" = "Üdvözlő üzenet hozzáadása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Additional accent" = "További kiemelés";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Additional accent 2" = "További kiemelés 2";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Additional secondary" = "További másodlagos";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Address" = "Cím";
|
||||
|
||||
@@ -398,6 +413,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Advanced network settings" = "Speciális hálózati beállítások";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Advanced settings" = "Haladó beállítások";
|
||||
|
||||
/* chat item text */
|
||||
"agreeing encryption for %@…" = "titkosítás jóváhagyása %@ számára…";
|
||||
|
||||
@@ -413,6 +431,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"All data is erased when it is entered." = "A jelkód megadása után minden adat törlésre kerül.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"All data is private to your device." = "Minden adat biztonságban van a készülékén.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"All group members will remain connected." = "Minden csoporttag kapcsolódva marad.";
|
||||
|
||||
@@ -428,6 +449,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"All new messages from %@ will be hidden!" = "Minden új üzenet elrejtésre kerül tőle: %@!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"All profiles" = "Minden profil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"All your contacts will remain connected." = "Minden ismerős kapcsolódva marad.";
|
||||
|
||||
@@ -554,6 +578,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Apply" = "Alkalmaz";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Apply to" = "Alkalmazás erre";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Archive and upload" = "Archiválás és feltöltés";
|
||||
|
||||
@@ -563,6 +590,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Attach" = "Csatolás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"attempts" = "próbálkozások";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Audio & video calls" = "Hang- és videóhívások";
|
||||
|
||||
@@ -605,6 +635,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Back" = "Vissza";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Background" = "Háttér";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Bad desktop address" = "Hibás számítógép cím";
|
||||
|
||||
@@ -626,6 +659,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Better messages" = "Jobb üzenetek";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Black" = "Fekete";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Block" = "Blokkolás";
|
||||
|
||||
@@ -650,7 +686,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "letiltotta őt: %@";
|
||||
|
||||
/* blocked chat item */
|
||||
/* marked deleted chat item preview text */
|
||||
"blocked by admin" = "letiltva az admin által";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -716,6 +752,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Cannot access keychain to save database password" = "Nem lehet hozzáférni a kulcstartóhoz az adatbázis jelszavának mentéséhez";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Cannot forward message" = "Nem lehet továbbítani az üzenetet";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Cannot receive file" = "Nem lehet fogadni a fájlt";
|
||||
|
||||
@@ -774,6 +813,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat archive" = "Csevegési archívum";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat colors" = "Csevegés színei";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat console" = "Csevegési konzol";
|
||||
|
||||
@@ -801,6 +843,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "Csevegési beállítások";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat theme" = "Csevegés témája";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chats" = "Csevegések";
|
||||
|
||||
@@ -819,6 +864,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Choose from library" = "Választás a könyvtárból";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chunks deleted" = "Törölt fájltöredékek";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chunks downloaded" = "Letöltött fájltöredékek";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chunks uploaded" = "Feltöltött fájltöredékek";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Clear" = "Kiürítés";
|
||||
|
||||
@@ -834,6 +888,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Clear verification" = "Hitelesítés törlése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Color mode" = "Színmód";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "színes";
|
||||
|
||||
@@ -846,6 +903,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"complete" = "befejezett";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Completed" = "Elkészült";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Configure ICE servers" = "ICE kiszolgálók beállítása";
|
||||
|
||||
@@ -915,18 +975,27 @@
|
||||
/* No comment provided by engineer. */
|
||||
"connected" = "kapcsolódva";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connected" = "Kapcsolódva";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connected desktop" = "Csatlakoztatott számítógép";
|
||||
|
||||
/* rcv group event chat item */
|
||||
"connected directly" = "közvetlenül kapcsolódva";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connected servers" = "Kapcsolódott kiszolgálók";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connected to desktop" = "Kapcsolódva a számítógéphez";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"connecting" = "kapcsolódás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connecting" = "Kapcsolódás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"connecting (accepted)" = "kapcsolódás (elfogadva)";
|
||||
|
||||
@@ -975,9 +1044,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Connection timeout" = "Kapcsolat időtúllépés";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connection with desktop stopped" = "A kapcsolat a számítógéppel megszakadt";
|
||||
|
||||
/* connection information */
|
||||
"connection:%@" = "kapcsolat: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connections" = "Kapcsolatok";
|
||||
|
||||
/* profile update event chat item */
|
||||
"contact %@ changed to %@" = "%1$@ megváltoztatta a nevét erre: %2$@";
|
||||
|
||||
@@ -1020,6 +1095,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Másolás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Copy error" = "Másolási hiba";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Core version: v%@" = "Alapverziószám: v%@";
|
||||
|
||||
@@ -1065,6 +1143,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Create your profile" = "Saját profil létrehozása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Created" = "Létrehozva";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Created at" = "Létrehozva ekkor:";
|
||||
|
||||
@@ -1089,6 +1170,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Current passphrase…" = "Jelenlegi jelmondat…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Current profile" = "Jelenlegi profil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Currently maximum supported file size is %@." = "Jelenleg a maximális támogatott fájlméret %@.";
|
||||
|
||||
@@ -1098,9 +1182,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Custom time" = "Személyreszabott idő";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customize theme" = "Téma személyre szabása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Dark" = "Sötét";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Dark mode colors" = "Sötét mód színei";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Database downgrade" = "Visszatérés a korábbi adatbázis verzióra";
|
||||
|
||||
@@ -1170,6 +1260,9 @@
|
||||
/* message decrypt error item */
|
||||
"Decryption error" = "Titkosítás visszafejtési hiba";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"decryption errors" = "visszafejtési hibák";
|
||||
|
||||
/* pref value */
|
||||
"default (%@)" = "alapértelmezett (%@)";
|
||||
|
||||
@@ -1296,6 +1389,9 @@
|
||||
/* deleted chat item */
|
||||
"deleted" = "törölve";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Deleted" = "Törölve";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Deleted at" = "Törölve ekkor:";
|
||||
|
||||
@@ -1308,6 +1404,9 @@
|
||||
/* rcv group event chat item */
|
||||
"deleted group" = "törölt csoport";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Deletion errors" = "Törlési hibák";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delivery" = "Kézbesítés";
|
||||
|
||||
@@ -1332,6 +1431,12 @@
|
||||
/* snd error text */
|
||||
"Destination server error: %@" = "Célkiszolgáló hiba: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Detailed statistics" = "Részletes statisztikák";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Details" = "Részletek";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Develop" = "Fejlesztés";
|
||||
|
||||
@@ -1434,12 +1539,21 @@
|
||||
/* chat item action */
|
||||
"Download" = "Letöltés";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Download errors" = "Letöltési hibák";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Download failed" = "Sikertelen letöltés";
|
||||
|
||||
/* server test step */
|
||||
"Download file" = "Fájl letöltése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Downloaded" = "Letöltve";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Downloaded files" = "Letöltött fájlok";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Downloading archive" = "Archívum letöltése";
|
||||
|
||||
@@ -1452,6 +1566,9 @@
|
||||
/* integrity error chat item */
|
||||
"duplicate message" = "duplikált üzenet";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"duplicates" = "duplikációk";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Duration" = "Időtartam";
|
||||
|
||||
@@ -1710,6 +1827,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error exporting chat database" = "Hiba a csevegési adatbázis exportálásakor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error exporting theme: %@" = "Hiba a téma exportálásakor: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error importing chat database" = "Hiba a csevegési adatbázis importálásakor";
|
||||
|
||||
@@ -1725,9 +1845,18 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error receiving file" = "Hiba a fájl fogadásakor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error reconnecting server" = "Hiba a kiszolgálóhoz való újrakapcsolódáskor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error reconnecting servers" = "Hiba a kiszolgálókhoz való újrakapcsolódáskor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error removing member" = "Hiba a tag eltávolításakor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error resetting statistics" = "Hiba a statisztikák visszaállításakor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error saving %@ servers" = "Hiba történt a %@ kiszolgálók mentése közben";
|
||||
|
||||
@@ -1807,6 +1936,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: URL is invalid" = "Hiba: az URL érvénytelen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Errors" = "Hibák";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Even when disabled in the conversation." = "Akkor is, ha le van tiltva a beszélgetésben.";
|
||||
|
||||
@@ -1819,12 +1951,18 @@
|
||||
/* chat item action */
|
||||
"Expand" = "Kibontás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"expired" = "lejárt";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Export database" = "Adatbázis exportálása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Export error:" = "Exportálási hiba:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Export theme" = "Téma exportálása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Exported database archive." = "Exportált adatbázis-archívum.";
|
||||
|
||||
@@ -1846,6 +1984,21 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Favorite" = "Kedvenc";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"File error" = "Fájlhiba";
|
||||
|
||||
/* file error text */
|
||||
"File not found - most likely file was deleted or cancelled." = "A fájl nem található - valószínűleg a fájlt törölték vagy visszavonták.";
|
||||
|
||||
/* file error text */
|
||||
"File server error: %@" = "Fájlkiszolgáló hiba: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"File status" = "Fájlállapot";
|
||||
|
||||
/* copied message info */
|
||||
"File status: %@" = "Fájlállapot: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"File will be deleted from servers." = "A fájl törölve lesz a kiszolgálóról.";
|
||||
|
||||
@@ -1960,6 +2113,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"GIFs and stickers" = "GIF-ek és matricák";
|
||||
|
||||
/* message preview */
|
||||
"Good afternoon!" = "Jó napot!";
|
||||
|
||||
/* message preview */
|
||||
"Good morning!" = "Jó reggelt!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Group" = "Csoport";
|
||||
|
||||
@@ -2137,6 +2296,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Import failed" = "Sikertelen importálás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Import theme" = "Téma importálása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Importing archive" = "Archívum importálása";
|
||||
|
||||
@@ -2158,6 +2320,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"In-call sounds" = "Bejövő hívás csengőhangja";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"inactive" = "inaktív";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Incognito" = "Inkognitó";
|
||||
|
||||
@@ -2221,6 +2386,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Interface" = "Felület";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Interface colors" = "Kezelőfelület színei";
|
||||
|
||||
/* invalid chat data */
|
||||
"invalid chat" = "érvénytelen csevegés";
|
||||
|
||||
@@ -2473,6 +2641,9 @@
|
||||
/* rcv group event chat item */
|
||||
"member connected" = "kapcsolódott";
|
||||
|
||||
/* item status text */
|
||||
"Member inactive" = "Inaktív tag";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Member role will be changed to \"%@\". All group members will be notified." = "A tag szerepköre meg fog változni erre: „%@”. A csoport minden tagja értesítést kap róla.";
|
||||
|
||||
@@ -2482,6 +2653,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Member will be removed from group - this cannot be undone!" = "A tag eltávolítása a csoportból - ez a művelet nem vonható vissza!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Menus" = "Menük";
|
||||
|
||||
/* item status text */
|
||||
"Message delivery error" = "Üzenetkézbesítési hiba";
|
||||
|
||||
@@ -2494,6 +2668,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Üzenetvázlat";
|
||||
|
||||
/* item status text */
|
||||
"Message forwarded" = "Továbbított üzenet";
|
||||
|
||||
/* item status description */
|
||||
"Message may be delivered later if member becomes active." = "Az üzenet később is kézbesíthető, ha a tag aktívvá válik.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Üzenet-várakoztatási információ";
|
||||
|
||||
@@ -2518,6 +2698,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message source remains private." = "Az üzenet forrása titokban marad.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message status" = "Üzenetállapot";
|
||||
|
||||
/* copied message info */
|
||||
"Message status: %@" = "Üzenetállapot: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message text" = "Üzenet szövege";
|
||||
|
||||
@@ -2533,6 +2719,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Messages from %@ will be shown!" = "A(z) %@ által írt üzenetek megjelennek!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Messages received" = "Fogadott üzenetek";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Messages sent" = "Elküldött üzenetek";
|
||||
|
||||
/* 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." = "Az üzeneteket, fájlokat és hívásokat **végpontok közötti titkosítással**, sérülés utáni titkosság-védelemmel és -helyreállítással, továbbá visszautasítással védi.";
|
||||
|
||||
@@ -2698,6 +2890,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"No device token!" = "Nincs eszköztoken!";
|
||||
|
||||
/* item status description */
|
||||
"No direct connection yet, message is forwarded by admin." = "Még nincs közvetlen kapcsolat, az üzenetet az admin továbbítja.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"no e2e encryption" = "nincs e2e titkosítás";
|
||||
|
||||
@@ -2710,6 +2905,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"No history" = "Nincsenek előzmények";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No info, try to reload" = "Nincs információ, próbálja meg újratölteni";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No network connection" = "Nincs hálózati kapcsolat";
|
||||
|
||||
@@ -2835,6 +3033,9 @@
|
||||
/* authentication reason */
|
||||
"Open migration to another device" = "Átköltöztetés megkezdése egy másik eszközre";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Open server settings" = "Kiszolgáló beállításainak megnyitása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Open Settings" = "Beállítások megnyitása";
|
||||
|
||||
@@ -2859,9 +3060,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Or show this code" = "Vagy mutassa meg ezt a kódot";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"other" = "egyéb";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Other" = "További";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"other errors" = "egyéb hibák";
|
||||
|
||||
/* member role */
|
||||
"owner" = "tulajdonos";
|
||||
|
||||
@@ -2904,6 +3111,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"peer-to-peer" = "ponttól-pontig";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Pending" = "Függő";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"People can connect to you only via the links you share." = "Az emberek csak az ön által megosztott hivatkozáson keresztül kapcsolódhatnak.";
|
||||
|
||||
@@ -2925,6 +3135,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Please ask your contact to enable sending voice messages." = "Ismerős felkérése, hogy engedélyezze a hangüzenetek küldését.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection.\nPlease share any other issues with the developers." = "Ellenőrizze, hogy a mobil és az asztali számítógép ugyanahhoz a helyi hálózathoz csatlakozik-e, valamint az asztali számítógép tűzfalában engedélyezve van-e a kapcsolat.\nMinden további problémát osszon meg a fejlesztőkkel.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Please check that you used the correct link or ask your contact to send you another one." = "Ellenőrizze, hogy a megfelelő hivatkozást használta-e, vagy kérje meg ismerősét, hogy küldjön egy másikat.";
|
||||
|
||||
@@ -2982,6 +3195,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Preview" = "Előnézet";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Previously connected servers" = "Korábban kapcsolódott kiszolgálók";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Privacy & security" = "Adatvédelem és biztonság";
|
||||
|
||||
@@ -3021,6 +3237,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Profile password" = "Profiljelszó";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Profile theme" = "Profiltéma";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Profile update will be sent to your contacts." = "A profilfrissítés elküldésre került az ismerősök számára.";
|
||||
|
||||
@@ -3069,6 +3288,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Protocol timeout per KB" = "Protokoll időkorlát KB-onként";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Proxied" = "Proxyzott";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Proxied servers" = "Proxyzott kiszolgálók";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Push notifications" = "Push értesítések";
|
||||
|
||||
@@ -3111,6 +3336,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Receipts are disabled" = "Üzenet kézbesítési jelentés letiltva";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Receive errors" = "Üzenetfogadási hibák";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"received answer…" = "fogadott válasz…";
|
||||
|
||||
@@ -3129,6 +3357,15 @@
|
||||
/* message info title */
|
||||
"Received message" = "Fogadott üzenet";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Received messages" = "Fogadott üzenetek";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Received reply" = "Fogadott válasz";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Received total" = "Összes fogadott";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Receiving address will be changed to a different server. Address change will complete after sender comes online." = "A fogadó cím egy másik kiszolgálóra változik. A címváltoztatás a feladó online állapotba kerülése után fejeződik be.";
|
||||
|
||||
@@ -3147,9 +3384,24 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Recipients see updates as you type them." = "A címzettek a beírás közben látják a frissítéseket.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect" = "Újrakapcsolás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect all connected servers to force message delivery. It uses additional traffic." = "Újrakapcsolódás az összes kiszolgálóhoz az üzenetek kézbesítésének kikényszerítéséhez. Ez további forgalmat használ.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect all servers" = "Újrakapcsolódás minden kiszolgálóhoz";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect all servers?" = "Újrakapcsolódás minden kiszolgálóhoz?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect server to force message delivery. It uses additional traffic." = "A kiszolgálóhoz való újrakapcsolódás az üzenet kézbesítésének kikényszerítéséhez. Ez további adatforgalmat használ.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect server?" = "Újrakapcsolódás a kiszolgálóhoz?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect servers?" = "Újrakapcsolódás a kiszolgálókhoz?";
|
||||
|
||||
@@ -3183,6 +3435,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Remove" = "Eltávolítás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove image" = "Kép eltávolítása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove member" = "Eltávolítás";
|
||||
|
||||
@@ -3240,12 +3495,24 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Reset" = "Alaphelyzetbe állítás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset all statistics" = "Minden statisztika visszaállítása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset all statistics?" = "Minden statisztika visszaállítása?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset colors" = "Színek alaphelyzetbe állítása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset to app theme" = "Alkalmazás témájának visszaállítása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset to defaults" = "Alaphelyzetbe állítás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset to user theme" = "Felhasználó által létrehozott téma visszaállítása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Restart the app to create a new chat profile" = "Új csevegési profil létrehozásához indítsa újra az alkalmazást";
|
||||
|
||||
@@ -3360,6 +3627,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Saved WebRTC ICE servers will be removed" = "A mentett WebRTC ICE kiszolgálók eltávolításra kerülnek";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Scale" = "Méretezés";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Scan / Paste link" = "Hivatkozás beolvasása / beillesztése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Scan code" = "Beolvasás";
|
||||
|
||||
@@ -3387,6 +3660,9 @@
|
||||
/* network option */
|
||||
"sec" = "mp";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Secondary" = "Másodlagos";
|
||||
|
||||
/* time unit */
|
||||
"seconds" = "másodperc";
|
||||
|
||||
@@ -3396,6 +3672,9 @@
|
||||
/* server test step */
|
||||
"Secure queue" = "Biztonságos várólista";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Secured" = "Biztosítva";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Security assessment" = "Biztonsági kiértékelés";
|
||||
|
||||
@@ -3408,6 +3687,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Select" = "Választás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Selected chat preferences prohibit this message." = "A kiválasztott csevegési beállítások tiltják ezt az üzenetet.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Self-destruct" = "Önmegsemmisítés";
|
||||
|
||||
@@ -3441,6 +3723,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Send disappearing message" = "Eltűnő üzenet küldése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Send errors" = "Üzenetküldési hibák";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Send link previews" = "Hivatkozás előnézetek küldése";
|
||||
|
||||
@@ -3507,15 +3792,33 @@
|
||||
/* copied message info */
|
||||
"Sent at: %@" = "Elküldve ekkor: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent directly" = "Közvetlenül küldött";
|
||||
|
||||
/* notification */
|
||||
"Sent file event" = "Elküldött fájl esemény";
|
||||
|
||||
/* message info title */
|
||||
"Sent message" = "Elküldött üzenet";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent messages" = "Elküldött üzenetek";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent messages will be deleted after set time." = "Az elküldött üzenetek törlésre kerülnek a beállított idő után.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent reply" = "Elküldött válasz";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent total" = "Összes elküldött";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent via proxy" = "Proxyn keresztül küldve";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server address" = "Kiszolgáló címe";
|
||||
|
||||
/* srv error text. */
|
||||
"Server address is incompatible with network settings." = "A kiszolgáló címe nem kompatibilis a hálózati beállításokkal.";
|
||||
|
||||
@@ -3531,12 +3834,21 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Server test failed!" = "Sikertelen kiszolgáló-teszt!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server type" = "Kiszolgáló típusa";
|
||||
|
||||
/* srv error text */
|
||||
"Server version is incompatible with network settings." = "A kiszolgáló verziója nem kompatibilis a hálózati beállításokkal.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Servers" = "Kiszolgálók";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Servers info" = "információk a kiszolgálókról";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Servers statistics will be reset - this cannot be undone!" = "A kiszolgálók statisztikái visszaállnak - ez nem vonható vissza!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Session code" = "Munkamenet kód";
|
||||
|
||||
@@ -3546,6 +3858,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Set contact name…" = "Ismerős nevének beállítása…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Set default theme" = "Alapértelmezett téma beállítása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Set group preferences" = "Csoportbeállítások megadása";
|
||||
|
||||
@@ -3624,6 +3939,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Show:" = "Megjelenítés:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX" = "SimpleX";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX address" = "SimpleX cím";
|
||||
|
||||
@@ -3669,6 +3987,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Simplified incognito mode" = "Egyszerűsített inkognító mód";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Size" = "Méret";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Skip" = "Kihagyás";
|
||||
|
||||
@@ -3678,6 +3999,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Small groups (max 20)" = "Kis csoportok (max. 20 tag)";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SMP server" = "SMP-kiszolgáló";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SMP servers" = "SMP kiszolgálók";
|
||||
|
||||
@@ -3702,9 +4026,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Start migration" = "Átköltöztetés indítása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Starting from %@." = "Kezdve ettől %@.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"starting…" = "indítás…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Statistics" = "Statisztikák";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Stop" = "Megállítás";
|
||||
|
||||
@@ -3747,6 +4077,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Submit" = "Elküldés";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Subscribed" = "Feliratkozva";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Subscription errors" = "Feliratkozási hibák";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Subscriptions ignored" = "Elutasított feliratkozások";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Support SimpleX Chat" = "Támogassa a SimpleX Chatet";
|
||||
|
||||
@@ -3795,6 +4134,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"TCP_KEEPINTVL" = "TCP_KEEPINTVL";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Temporary file error" = "Ideiglenes fájlhiba";
|
||||
|
||||
/* server test failure */
|
||||
"Test failed at step %@." = "A teszt sikertelen volt a(z) %@ lépésnél.";
|
||||
|
||||
@@ -3876,6 +4218,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "A beillesztett szöveg nem egy SimpleX hivatkozás.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Themes" = "Témák";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Ezek a beállítások a jelenlegi **%@** profiljára vonatkoznak.";
|
||||
|
||||
@@ -3918,9 +4263,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"This is your own SimpleX address!" = "Ez az ön SimpleX címe!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"This link was used with another mobile device, please create a new link on the desktop." = "Ezt a hivatkozást egy másik mobilleszközön már használták, hozzon létre egy új hivatkozást az asztali számítógépén.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"This setting applies to messages in your current chat profile **%@**." = "Ez a beállítás a jelenlegi **%@** profiljában lévő üzenetekre érvényes.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Title" = "Cím";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To ask any questions and to receive updates:" = "Bármilyen kérdés feltevéséhez és a frissítésekért:";
|
||||
|
||||
@@ -3960,9 +4311,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Toggle incognito when connecting." = "Inkognitó mód kapcsolódáskor.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Total" = "Összesen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Transport isolation" = "Kapcsolat izolációs mód";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Transport sessions" = "Munkamenetek átvitele";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Trying to connect to the server used to receive messages from this contact (error: %@)." = "Kapcsolódási kísérlet ahhoz a kiszolgálóhoz, amely az adott ismerőstől érkező üzenetek fogadására szolgál (hiba: %@).";
|
||||
|
||||
@@ -4098,12 +4455,21 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Upgrade and open chat" = "A csevegés frissítése és megnyitása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Upload errors" = "Feltöltési hibák";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Upload failed" = "Sikertelen feltöltés";
|
||||
|
||||
/* server test step */
|
||||
"Upload file" = "Fájl feltöltése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Uploaded" = "Feltöltve";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Uploaded files" = "Feltöltött fájlok";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Uploading archive" = "Archívum feltöltése";
|
||||
|
||||
@@ -4149,6 +4515,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Felhasználói profil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "Felhasználó kiválasztása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Using .onion hosts requires compatible VPN provider." = "A .onion kiszolgálók használatához kompatibilis VPN szolgáltatóra van szükség.";
|
||||
|
||||
@@ -4257,6 +4626,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Waiting for video" = "Videóra várakozás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Wallpaper accent" = "Háttérkép kiemelés";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Wallpaper background" = "Háttérkép háttérszíne";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"wants to connect to you!" = "kapcsolatba akar lépni önnel!";
|
||||
|
||||
@@ -4329,9 +4704,15 @@
|
||||
/* snd error text */
|
||||
"Wrong key or unknown connection - most likely this connection is deleted." = "Rossz kulcs vagy ismeretlen kapcsolat - valószínűleg ez a kapcsolat törlődött.";
|
||||
|
||||
/* file error text */
|
||||
"Wrong key or unknown file chunk address - most likely file is deleted." = "Hibás kulcs vagy ismeretlen fájltöredék cím - valószínűleg a fájl törlődött.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Wrong passphrase!" = "Téves jelmondat!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"XFTP server" = "XFTP-kiszolgáló";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"XFTP servers" = "XFTP kiszolgálók";
|
||||
|
||||
@@ -4389,6 +4770,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"You are invited to group" = "Meghívást kapott a csoportba";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You are not connected to these servers. Private routing is used to deliver messages to them." = "Ön nem kapcsolódik ezekhez a kiszolgálókhoz. A privát útválasztás az üzenetek kézbesítésére szolgál.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"you are observer" = "megfigyelő szerep";
|
||||
|
||||
@@ -4417,7 +4801,7 @@
|
||||
"You can make it visible to your SimpleX contacts via Settings." = "Láthatóvá teheti SimpleX ismerősök számára a Beállításokban.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Mostantól küldhet üzeneteket %@ számára";
|
||||
"You can now chat with %@" = "Mostantól küldhet üzeneteket %@ számára";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "A beállításokon keresztül beállíthatja a lezárási képernyő értesítési előnézetét.";
|
||||
|
||||
@@ -154,9 +154,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ è verificato/a";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "Server %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ caricati";
|
||||
|
||||
@@ -337,6 +334,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "sopra, quindi scegli:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent" = "Principale";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Accetta";
|
||||
@@ -353,6 +353,12 @@
|
||||
/* call status */
|
||||
"accepted call" = "chiamata accettata";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Acknowledged" = "Riconosciuto";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Acknowledgement errors" = "Errori di riconoscimento";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." = "Aggiungi l'indirizzo al tuo profilo, in modo che i tuoi contatti possano condividerlo con altre persone. L'aggiornamento del profilo verrà inviato ai tuoi contatti.";
|
||||
|
||||
@@ -377,6 +383,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Add welcome message" = "Aggiungi messaggio di benvenuto";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Additional accent" = "Principale aggiuntivo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Additional accent 2" = "Principale aggiuntivo 2";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Additional secondary" = "Secondario aggiuntivo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Address" = "Indirizzo";
|
||||
|
||||
@@ -398,6 +413,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Advanced network settings" = "Impostazioni di rete avanzate";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Advanced settings" = "Impostazioni avanzate";
|
||||
|
||||
/* chat item text */
|
||||
"agreeing encryption for %@…" = "concordando la crittografia per %@…";
|
||||
|
||||
@@ -413,6 +431,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"All data is erased when it is entered." = "Tutti i dati vengono cancellati quando inserito.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"All data is private to your device." = "Tutti i dati sono privati, nel tuo dispositivo.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"All group members will remain connected." = "Tutti i membri del gruppo resteranno connessi.";
|
||||
|
||||
@@ -428,6 +449,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"All new messages from %@ will be hidden!" = "Tutti i nuovi messaggi da %@ verrranno nascosti!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"All profiles" = "Tutti gli profili";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"All your contacts will remain connected." = "Tutti i tuoi contatti resteranno connessi.";
|
||||
|
||||
@@ -554,6 +578,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Apply" = "Applica";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Apply to" = "Applica a";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Archive and upload" = "Archivia e carica";
|
||||
|
||||
@@ -563,6 +590,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Attach" = "Allega";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"attempts" = "tentativi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Audio & video calls" = "Chiamate audio e video";
|
||||
|
||||
@@ -605,6 +635,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Back" = "Indietro";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Background" = "Sfondo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Bad desktop address" = "Indirizzo desktop errato";
|
||||
|
||||
@@ -626,6 +659,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Better messages" = "Messaggi migliorati";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Black" = "Nero";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Block" = "Blocca";
|
||||
|
||||
@@ -650,7 +686,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "ha bloccato %@";
|
||||
|
||||
/* blocked chat item */
|
||||
/* marked deleted chat item preview text */
|
||||
"blocked by admin" = "bloccato dall'amministratore";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -716,6 +752,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Cannot access keychain to save database password" = "Impossibile accedere al portachiavi per salvare la password del database";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Cannot forward message" = "Impossibile inoltrare il messaggio";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Cannot receive file" = "Impossibile ricevere il file";
|
||||
|
||||
@@ -774,6 +813,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat archive" = "Archivio chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat colors" = "Colori della chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat console" = "Console della chat";
|
||||
|
||||
@@ -801,6 +843,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "Preferenze della chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat theme" = "Tema della chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chats" = "Chat";
|
||||
|
||||
@@ -819,6 +864,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Choose from library" = "Scegli dalla libreria";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chunks deleted" = "Blocchi eliminati";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chunks downloaded" = "Blocchi scaricati";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chunks uploaded" = "Blocchi inviati";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Clear" = "Svuota";
|
||||
|
||||
@@ -834,6 +888,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Clear verification" = "Annulla la verifica";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Color mode" = "Modalità di colore";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "colorato";
|
||||
|
||||
@@ -846,6 +903,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"complete" = "completo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Completed" = "Completato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Configure ICE servers" = "Configura server ICE";
|
||||
|
||||
@@ -915,18 +975,27 @@
|
||||
/* No comment provided by engineer. */
|
||||
"connected" = "connesso/a";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connected" = "Connesso";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connected desktop" = "Desktop connesso";
|
||||
|
||||
/* rcv group event chat item */
|
||||
"connected directly" = "si è connesso/a direttamente";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connected servers" = "Server connessi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connected to desktop" = "Connesso al desktop";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"connecting" = "in connessione";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connecting" = "In connessione";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"connecting (accepted)" = "in connessione (accettato)";
|
||||
|
||||
@@ -975,9 +1044,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Connection timeout" = "Connessione scaduta";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connection with desktop stopped" = "Connessione con il desktop fermata";
|
||||
|
||||
/* connection information */
|
||||
"connection:%@" = "connessione:% @";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connections" = "Connessioni";
|
||||
|
||||
/* profile update event chat item */
|
||||
"contact %@ changed to %@" = "contatto %1$@ cambiato in %2$@";
|
||||
|
||||
@@ -1020,6 +1095,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Copia";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Copy error" = "Copia errore";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Core version: v%@" = "Versione core: v%@";
|
||||
|
||||
@@ -1065,6 +1143,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Create your profile" = "Crea il tuo profilo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Created" = "Creato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Created at" = "Creato il";
|
||||
|
||||
@@ -1089,6 +1170,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Current passphrase…" = "Password attuale…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Current profile" = "Profilo attuale";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Currently maximum supported file size is %@." = "Attualmente la dimensione massima supportata è di %@.";
|
||||
|
||||
@@ -1098,9 +1182,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Custom time" = "Tempo personalizzato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customize theme" = "Personalizza il tema";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Dark" = "Scuro";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Dark mode colors" = "Colori modalità scura";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Database downgrade" = "Downgrade del database";
|
||||
|
||||
@@ -1170,6 +1260,9 @@
|
||||
/* message decrypt error item */
|
||||
"Decryption error" = "Errore di decifrazione";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"decryption errors" = "errori di decifrazione";
|
||||
|
||||
/* pref value */
|
||||
"default (%@)" = "predefinito (%@)";
|
||||
|
||||
@@ -1296,6 +1389,9 @@
|
||||
/* deleted chat item */
|
||||
"deleted" = "eliminato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Deleted" = "Eliminato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Deleted at" = "Eliminato il";
|
||||
|
||||
@@ -1308,6 +1404,9 @@
|
||||
/* rcv group event chat item */
|
||||
"deleted group" = "gruppo eliminato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Deletion errors" = "Errori di eliminazione";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delivery" = "Consegna";
|
||||
|
||||
@@ -1332,6 +1431,12 @@
|
||||
/* snd error text */
|
||||
"Destination server error: %@" = "Errore del server di destinazione: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Detailed statistics" = "Statistiche dettagliate";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Details" = "Dettagli";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Develop" = "Sviluppa";
|
||||
|
||||
@@ -1434,12 +1539,21 @@
|
||||
/* chat item action */
|
||||
"Download" = "Scarica";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Download errors" = "Errori di scaricamento";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Download failed" = "Scaricamento fallito";
|
||||
|
||||
/* server test step */
|
||||
"Download file" = "Scarica file";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Downloaded" = "Scaricato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Downloaded files" = "File scaricati";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Downloading archive" = "Scaricamento archivio";
|
||||
|
||||
@@ -1452,6 +1566,9 @@
|
||||
/* integrity error chat item */
|
||||
"duplicate message" = "messaggio duplicato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"duplicates" = "doppi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Duration" = "Durata";
|
||||
|
||||
@@ -1710,6 +1827,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error exporting chat database" = "Errore nell'esportazione del database della chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error exporting theme: %@" = "Errore di esportazione del tema: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error importing chat database" = "Errore nell'importazione del database della chat";
|
||||
|
||||
@@ -1725,9 +1845,18 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error receiving file" = "Errore nella ricezione del file";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error reconnecting server" = "Errore di riconnessione al server";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error reconnecting servers" = "Errore di riconnessione ai server";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error removing member" = "Errore nella rimozione del membro";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error resetting statistics" = "Errore di azzeramento statistiche";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error saving %@ servers" = "Errore nel salvataggio dei server %@";
|
||||
|
||||
@@ -1807,6 +1936,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: URL is invalid" = "Errore: l'URL non è valido";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Errors" = "Errori";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Even when disabled in the conversation." = "Anche quando disattivato nella conversazione.";
|
||||
|
||||
@@ -1819,12 +1951,18 @@
|
||||
/* chat item action */
|
||||
"Expand" = "Espandi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"expired" = "scaduto";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Export database" = "Esporta database";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Export error:" = "Errore di esportazione:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Export theme" = "Esporta tema";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Exported database archive." = "Archivio database esportato.";
|
||||
|
||||
@@ -1846,6 +1984,21 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Favorite" = "Preferito";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"File error" = "Errore del file";
|
||||
|
||||
/* file error text */
|
||||
"File not found - most likely file was deleted or cancelled." = "File non trovato - probabilmente è stato eliminato o annullato.";
|
||||
|
||||
/* file error text */
|
||||
"File server error: %@" = "Errore del server dei file: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"File status" = "Stato del file";
|
||||
|
||||
/* copied message info */
|
||||
"File status: %@" = "Stato del file: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"File will be deleted from servers." = "Il file verrà eliminato dai server.";
|
||||
|
||||
@@ -1960,6 +2113,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"GIFs and stickers" = "GIF e adesivi";
|
||||
|
||||
/* message preview */
|
||||
"Good afternoon!" = "Buon pomeriggio!";
|
||||
|
||||
/* message preview */
|
||||
"Good morning!" = "Buongiorno!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Group" = "Gruppo";
|
||||
|
||||
@@ -2137,6 +2296,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Import failed" = "Importazione fallita";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Import theme" = "Importa tema";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Importing archive" = "Importazione archivio";
|
||||
|
||||
@@ -2158,6 +2320,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"In-call sounds" = "Suoni nelle chiamate";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"inactive" = "inattivo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Incognito" = "Incognito";
|
||||
|
||||
@@ -2221,6 +2386,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Interface" = "Interfaccia";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Interface colors" = "Colori dell'interfaccia";
|
||||
|
||||
/* invalid chat data */
|
||||
"invalid chat" = "chat non valida";
|
||||
|
||||
@@ -2473,6 +2641,9 @@
|
||||
/* rcv group event chat item */
|
||||
"member connected" = "si è connesso/a";
|
||||
|
||||
/* item status text */
|
||||
"Member inactive" = "Membro inattivo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Member role will be changed to \"%@\". All group members will be notified." = "Il ruolo del membro verrà cambiato in \"%@\". Tutti i membri del gruppo verranno avvisati.";
|
||||
|
||||
@@ -2482,6 +2653,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Member will be removed from group - this cannot be undone!" = "Il membro verrà rimosso dal gruppo, non è reversibile!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Menus" = "Menu";
|
||||
|
||||
/* item status text */
|
||||
"Message delivery error" = "Errore di recapito del messaggio";
|
||||
|
||||
@@ -2494,6 +2668,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Bozza dei messaggi";
|
||||
|
||||
/* item status text */
|
||||
"Message forwarded" = "Messaggio inoltrato";
|
||||
|
||||
/* item status description */
|
||||
"Message may be delivered later if member becomes active." = "Il messaggio può essere consegnato più tardi se il membro diventa attivo.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Info coda messaggi";
|
||||
|
||||
@@ -2518,6 +2698,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message source remains private." = "La fonte del messaggio resta privata.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message status" = "Stato del messaggio";
|
||||
|
||||
/* copied message info */
|
||||
"Message status: %@" = "Stato del messaggio: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message text" = "Testo del messaggio";
|
||||
|
||||
@@ -2533,6 +2719,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Messages from %@ will be shown!" = "I messaggi da %@ verranno mostrati!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Messages received" = "Messaggi ricevuti";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Messages sent" = "Messaggi inviati";
|
||||
|
||||
/* 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." = "I messaggi, i file e le chiamate sono protetti da **crittografia end-to-end** con perfect forward secrecy, ripudio e recupero da intrusione.";
|
||||
|
||||
@@ -2698,6 +2890,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"No device token!" = "Nessun token del dispositivo!";
|
||||
|
||||
/* item status description */
|
||||
"No direct connection yet, message is forwarded by admin." = "Ancora nessuna connessione diretta, il messaggio viene inoltrato dall'amministratore.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"no e2e encryption" = "nessuna crittografia e2e";
|
||||
|
||||
@@ -2710,6 +2905,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"No history" = "Nessuna cronologia";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No info, try to reload" = "Nessuna informazione, prova a ricaricare";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No network connection" = "Nessuna connessione di rete";
|
||||
|
||||
@@ -2835,6 +3033,9 @@
|
||||
/* authentication reason */
|
||||
"Open migration to another device" = "Apri migrazione ad un altro dispositivo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Open server settings" = "Apri impostazioni server";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Open Settings" = "Apri le impostazioni";
|
||||
|
||||
@@ -2859,9 +3060,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Or show this code" = "O mostra questo codice";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"other" = "altro";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Other" = "Altro";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"other errors" = "altri errori";
|
||||
|
||||
/* member role */
|
||||
"owner" = "proprietario";
|
||||
|
||||
@@ -2904,6 +3111,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"peer-to-peer" = "peer-to-peer";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Pending" = "In attesa";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"People can connect to you only via the links you share." = "Le persone possono connettersi a te solo tramite i link che condividi.";
|
||||
|
||||
@@ -2925,6 +3135,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Please ask your contact to enable sending voice messages." = "Chiedi al tuo contatto di attivare l'invio dei messaggi vocali.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection.\nPlease share any other issues with the developers." = "Controlla che mobile e desktop siano collegati alla stessa rete locale e che il firewall del desktop consenta la connessione.\nSi prega di condividere qualsiasi altro problema con gli sviluppatori.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Please check that you used the correct link or ask your contact to send you another one." = "Controlla di aver usato il link giusto o chiedi al tuo contatto di inviartene un altro.";
|
||||
|
||||
@@ -2982,6 +3195,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Preview" = "Anteprima";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Previously connected servers" = "Server precedentemente connessi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Privacy & security" = "Privacy e sicurezza";
|
||||
|
||||
@@ -3021,6 +3237,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Profile password" = "Password del profilo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Profile theme" = "Tema del profilo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Profile update will be sent to your contacts." = "L'aggiornamento del profilo verrà inviato ai tuoi contatti.";
|
||||
|
||||
@@ -3069,6 +3288,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Protocol timeout per KB" = "Scadenza del protocollo per KB";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Proxied" = "Via proxy";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Proxied servers" = "Server via proxy";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Push notifications" = "Notifiche push";
|
||||
|
||||
@@ -3111,6 +3336,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Receipts are disabled" = "Le ricevute sono disattivate";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Receive errors" = "Errori di ricezione";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"received answer…" = "risposta ricevuta…";
|
||||
|
||||
@@ -3129,6 +3357,15 @@
|
||||
/* message info title */
|
||||
"Received message" = "Messaggio ricevuto";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Received messages" = "Messaggi ricevuti";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Received reply" = "Risposta ricevuta";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Received total" = "Totale ricevuto";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Receiving address will be changed to a different server. Address change will complete after sender comes online." = "L'indirizzo di ricezione verrà cambiato in un server diverso. La modifica dell'indirizzo verrà completata dopo che il mittente sarà in linea.";
|
||||
|
||||
@@ -3147,9 +3384,24 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Recipients see updates as you type them." = "I destinatari vedono gli aggiornamenti mentre li digiti.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect" = "Riconnetti";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect all connected servers to force message delivery. It uses additional traffic." = "Riconnetti tutti i server connessi per imporre il recapito dei messaggi. Utilizza traffico aggiuntivo.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect all servers" = "Riconnetti tutti i server";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect all servers?" = "Riconnettere tutti i server?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect server to force message delivery. It uses additional traffic." = "Riconnetti il server per forzare la consegna dei messaggi. Usa traffico aggiuntivo.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect server?" = "Riconnettere il server?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reconnect servers?" = "Riconnettere i server?";
|
||||
|
||||
@@ -3183,6 +3435,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Remove" = "Rimuovi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove image" = "Rimuovi immagine";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove member" = "Rimuovi membro";
|
||||
|
||||
@@ -3240,12 +3495,24 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Reset" = "Ripristina";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset all statistics" = "Azzera tutte le statistiche";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset all statistics?" = "Azzerare tutte le statistiche?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset colors" = "Ripristina i colori";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset to app theme" = "Ripristina al tema dell'app";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset to defaults" = "Ripristina i predefiniti";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Reset to user theme" = "Ripristina al tema dell'utente";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Restart the app to create a new chat profile" = "Riavvia l'app per creare un nuovo profilo di chat";
|
||||
|
||||
@@ -3360,6 +3627,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Saved WebRTC ICE servers will be removed" = "I server WebRTC ICE salvati verranno rimossi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Scale" = "Scala";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Scan / Paste link" = "Scansiona / Incolla link";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Scan code" = "Scansiona codice";
|
||||
|
||||
@@ -3387,6 +3660,9 @@
|
||||
/* network option */
|
||||
"sec" = "sec";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Secondary" = "Secondario";
|
||||
|
||||
/* time unit */
|
||||
"seconds" = "secondi";
|
||||
|
||||
@@ -3396,6 +3672,9 @@
|
||||
/* server test step */
|
||||
"Secure queue" = "Coda sicura";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Secured" = "Protetto";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Security assessment" = "Valutazione della sicurezza";
|
||||
|
||||
@@ -3408,6 +3687,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Select" = "Seleziona";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Selected chat preferences prohibit this message." = "Le preferenze della chat selezionata vietano questo messaggio.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Self-destruct" = "Autodistruzione";
|
||||
|
||||
@@ -3441,6 +3723,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Send disappearing message" = "Invia messaggio a tempo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Send errors" = "Errori di invio";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Send link previews" = "Invia anteprime dei link";
|
||||
|
||||
@@ -3507,15 +3792,33 @@
|
||||
/* copied message info */
|
||||
"Sent at: %@" = "Inviato il: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent directly" = "Inviato direttamente";
|
||||
|
||||
/* notification */
|
||||
"Sent file event" = "Evento file inviato";
|
||||
|
||||
/* message info title */
|
||||
"Sent message" = "Messaggio inviato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent messages" = "Messaggi inviati";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent messages will be deleted after set time." = "I messaggi inviati verranno eliminati dopo il tempo impostato.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent reply" = "Risposta inviata";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent total" = "Totale inviato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sent via proxy" = "Inviato via proxy";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server address" = "Indirizzo server";
|
||||
|
||||
/* srv error text. */
|
||||
"Server address is incompatible with network settings." = "L'indirizzo del server non è compatibile con le impostazioni di rete.";
|
||||
|
||||
@@ -3531,12 +3834,21 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Server test failed!" = "Test del server fallito!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server type" = "Tipo server";
|
||||
|
||||
/* srv error text */
|
||||
"Server version is incompatible with network settings." = "La versione del server non è compatibile con le impostazioni di rete.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Servers" = "Server";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Servers info" = "Info dei server";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Servers statistics will be reset - this cannot be undone!" = "Le statistiche dei server verranno azzerate - è irreversibile!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Session code" = "Codice di sessione";
|
||||
|
||||
@@ -3546,6 +3858,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Set contact name…" = "Imposta nome del contatto…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Set default theme" = "Imposta tema predefinito";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Set group preferences" = "Imposta le preferenze del gruppo";
|
||||
|
||||
@@ -3624,6 +3939,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Show:" = "Mostra:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX" = "SimpleX";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX address" = "Indirizzo SimpleX";
|
||||
|
||||
@@ -3669,6 +3987,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Simplified incognito mode" = "Modalità incognito semplificata";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Size" = "Dimensione";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Skip" = "Salta";
|
||||
|
||||
@@ -3678,6 +3999,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Small groups (max 20)" = "Piccoli gruppi (max 20)";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SMP server" = "Server SMP";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SMP servers" = "Server SMP";
|
||||
|
||||
@@ -3702,9 +4026,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Start migration" = "Avvia la migrazione";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Starting from %@." = "Inizio da %@.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"starting…" = "avvio…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Statistics" = "Statistiche";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Stop" = "Ferma";
|
||||
|
||||
@@ -3747,6 +4077,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Submit" = "Invia";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Subscribed" = "Iscritto";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Subscription errors" = "Errori di iscrizione";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Subscriptions ignored" = "Iscrizioni ignorate";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Support SimpleX Chat" = "Supporta SimpleX Chat";
|
||||
|
||||
@@ -3795,6 +4134,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"TCP_KEEPINTVL" = "TCP_KEEPINTVL";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Temporary file error" = "Errore del file temporaneo";
|
||||
|
||||
/* server test failure */
|
||||
"Test failed at step %@." = "Test fallito al passo %@.";
|
||||
|
||||
@@ -3876,6 +4218,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Il testo che hai incollato non è un link SimpleX.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Themes" = "Temi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Queste impostazioni sono per il tuo profilo attuale **%@**.";
|
||||
|
||||
@@ -3918,9 +4263,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"This is your own SimpleX address!" = "Questo è il tuo indirizzo SimpleX!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"This link was used with another mobile device, please create a new link on the desktop." = "Questo link è stato usato con un altro dispositivo mobile, creane uno nuovo sul desktop.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"This setting applies to messages in your current chat profile **%@**." = "Questa impostazione si applica ai messaggi del profilo di chat attuale **%@**.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Title" = "Titoli";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To ask any questions and to receive updates:" = "Per porre domande e ricevere aggiornamenti:";
|
||||
|
||||
@@ -3960,9 +4311,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Toggle incognito when connecting." = "Attiva/disattiva l'incognito quando ti colleghi.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Total" = "Totale";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Transport isolation" = "Isolamento del trasporto";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Transport sessions" = "Sessioni di trasporto";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Trying to connect to the server used to receive messages from this contact (error: %@)." = "Tentativo di connessione al server usato per ricevere messaggi da questo contatto (errore: %@).";
|
||||
|
||||
@@ -4098,12 +4455,21 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Upgrade and open chat" = "Aggiorna e apri chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Upload errors" = "Errori di invio";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Upload failed" = "Invio fallito";
|
||||
|
||||
/* server test step */
|
||||
"Upload file" = "Invia file";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Uploaded" = "Inviato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Uploaded files" = "File inviati";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Uploading archive" = "Invio dell'archivio";
|
||||
|
||||
@@ -4149,6 +4515,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Profilo utente";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "Selezione utente";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Using .onion hosts requires compatible VPN provider." = "L'uso di host .onion richiede un fornitore di VPN compatibile.";
|
||||
|
||||
@@ -4257,6 +4626,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Waiting for video" = "In attesa del video";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Wallpaper accent" = "Tinta dello sfondo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Wallpaper background" = "Retro dello sfondo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"wants to connect to you!" = "vuole connettersi con te!";
|
||||
|
||||
@@ -4329,9 +4704,15 @@
|
||||
/* snd error text */
|
||||
"Wrong key or unknown connection - most likely this connection is deleted." = "Chiave sbagliata o connessione sconosciuta - molto probabilmente questa connessione è stata eliminata.";
|
||||
|
||||
/* file error text */
|
||||
"Wrong key or unknown file chunk address - most likely file is deleted." = "Chiave sbagliata o indirizzo sconosciuto per frammento del file - probabilmente il file è stato eliminato.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Wrong passphrase!" = "Password sbagliata!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"XFTP server" = "Server XFTP";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"XFTP servers" = "Server XFTP";
|
||||
|
||||
@@ -4389,6 +4770,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"You are invited to group" = "Sei stato/a invitato/a al gruppo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You are not connected to these servers. Private routing is used to deliver messages to them." = "Non sei connesso/a a questi server. L'instradamento privato è usato per consegnare loro i messaggi.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"you are observer" = "sei un osservatore";
|
||||
|
||||
@@ -4417,7 +4801,7 @@
|
||||
"You can make it visible to your SimpleX contacts via Settings." = "Puoi renderlo visibile ai tuoi contatti SimpleX nelle impostazioni.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Ora puoi inviare messaggi a %@";
|
||||
"You can now chat with %@" = "Ora puoi inviare messaggi a %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "Puoi impostare l'anteprima della notifica nella schermata di blocco tramite le impostazioni.";
|
||||
|
||||
@@ -148,9 +148,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ は検証されています";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ サーバー";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ アップロード済";
|
||||
|
||||
@@ -3451,7 +3448,7 @@
|
||||
"You can hide or mute a user profile - swipe it to the right." = "ユーザープロファイルを右にスワイプすると、非表示またはミュートにすることができます。";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "%@ にメッセージを送信できるようになりました";
|
||||
"You can now chat with %@" = "%@ にメッセージを送信できるようになりました";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "設定からロック画面の通知プレビューを設定できます。";
|
||||
|
||||
@@ -154,9 +154,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ is geverifieerd";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ servers";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ geüpload";
|
||||
|
||||
@@ -650,7 +647,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "geblokkeerd %@";
|
||||
|
||||
/* blocked chat item */
|
||||
/* marked deleted chat item preview text */
|
||||
"blocked by admin" = "geblokkeerd door beheerder";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -4417,7 +4414,7 @@
|
||||
"You can make it visible to your SimpleX contacts via Settings." = "Je kunt het via Instellingen zichtbaar maken voor je SimpleX contacten.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Je kunt nu berichten sturen naar %@";
|
||||
"You can now chat with %@" = "Je kunt nu berichten sturen naar %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "U kunt een voorbeeld van een melding op het vergrendeld scherm instellen via instellingen.";
|
||||
|
||||
@@ -154,9 +154,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ jest zweryfikowany";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ serwery";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ wgrane";
|
||||
|
||||
@@ -650,7 +647,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "zablokowany %@";
|
||||
|
||||
/* blocked chat item */
|
||||
/* marked deleted chat item preview text */
|
||||
"blocked by admin" = "zablokowany przez admina";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -4417,7 +4414,7 @@
|
||||
"You can make it visible to your SimpleX contacts via Settings." = "Możesz ustawić go jako widoczny dla swoich kontaktów SimpleX w Ustawieniach.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Możesz teraz wysyłać wiadomości do %@";
|
||||
"You can now chat with %@" = "Możesz teraz wysyłać wiadomości do %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "Podgląd powiadomień na ekranie blokady można ustawić w ustawieniach.";
|
||||
|
||||
@@ -154,9 +154,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ подтверждён";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ серверы";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ загружено";
|
||||
|
||||
@@ -650,7 +647,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "%@ заблокирован";
|
||||
|
||||
/* blocked chat item */
|
||||
/* marked deleted chat item preview text */
|
||||
"blocked by admin" = "заблокировано администратором";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -4408,7 +4405,7 @@
|
||||
"You can make it visible to your SimpleX contacts via Settings." = "Вы можете сделать его видимым для ваших контактов в SimpleX через Настройки.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Вы теперь можете отправлять сообщения %@";
|
||||
"You can now chat with %@" = "Вы теперь можете общаться с %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "Вы можете установить просмотр уведомлений на экране блокировки в настройках.";
|
||||
|
||||
@@ -109,9 +109,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ ได้รับการตรวจสอบแล้ว";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ เซิร์ฟเวอร์";
|
||||
|
||||
/* notification title */
|
||||
"%@ wants to connect!" = "%@ อยากเชื่อมต่อ!";
|
||||
|
||||
@@ -3304,7 +3301,7 @@
|
||||
"You can hide or mute a user profile - swipe it to the right." = "คุณสามารถซ่อนหรือปิดเสียงโปรไฟล์ผู้ใช้ - ปัดไปทางขวา";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "ตอนนี้คุณสามารถส่งข้อความถึง %@";
|
||||
"You can now chat with %@" = "ตอนนี้คุณสามารถส่งข้อความถึง %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "คุณสามารถตั้งค่าแสดงตัวอย่างการแจ้งเตือนบนหน้าจอล็อคผ่านการตั้งค่า";
|
||||
|
||||
@@ -154,9 +154,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ onaylandı";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ sunucuları";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ yüklendi";
|
||||
|
||||
@@ -650,7 +647,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "engellendi %@";
|
||||
|
||||
/* blocked chat item */
|
||||
/* marked deleted chat item preview text */
|
||||
"blocked by admin" = "yönetici tarafından engellendi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -4417,7 +4414,7 @@
|
||||
"You can make it visible to your SimpleX contacts via Settings." = "Ayarlardan SimpleX kişilerinize görünür yapabilirsiniz.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Artık %@ adresine mesaj gönderebilirsin";
|
||||
"You can now chat with %@" = "Artık %@ adresine mesaj gönderebilirsin";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "Kilit ekranı bildirim önizlemesini ayarlar üzerinden ayarlayabilirsiniz.";
|
||||
|
||||
@@ -154,9 +154,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ перевірено";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ сервери";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ завантажено";
|
||||
|
||||
@@ -650,7 +647,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "заблоковано %@";
|
||||
|
||||
/* blocked chat item */
|
||||
/* marked deleted chat item preview text */
|
||||
"blocked by admin" = "заблоковано адміністратором";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -4417,7 +4414,7 @@
|
||||
"You can make it visible to your SimpleX contacts via Settings." = "Ви можете зробити його видимим для ваших контактів у SimpleX за допомогою налаштувань.";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "Тепер ви можете надсилати повідомлення на адресу %@";
|
||||
"You can now chat with %@" = "Тепер ви можете надсилати повідомлення на адресу %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "Ви можете налаштувати попередній перегляд сповіщень на екрані блокування за допомогою налаштувань.";
|
||||
|
||||
@@ -133,9 +133,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ 已认证";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ 服务器";
|
||||
|
||||
/* notification title */
|
||||
"%@ wants to connect!" = "%@ 要连接!";
|
||||
|
||||
@@ -602,7 +599,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "已封禁 %@";
|
||||
|
||||
/* blocked chat item */
|
||||
/* marked deleted chat item preview text */
|
||||
"blocked by admin" = "由管理员封禁";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -4114,7 +4111,7 @@
|
||||
"You can make it visible to your SimpleX contacts via Settings." = "你可以通过设置让它对你的 SimpleX 联系人可见。";
|
||||
|
||||
/* notification body */
|
||||
"You can now send messages to %@" = "您现在可以给 %@ 发送消息";
|
||||
"You can now chat with %@" = "您现在可以给 %@ 发送消息";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can set lock screen notification preview via settings." = "您可以通过设置来设置锁屏通知预览。";
|
||||
|
||||
+2
@@ -28,3 +28,5 @@ actual fun Modifier.desktopOnExternalDrag(
|
||||
actual fun Modifier.onRightClick(action: () -> Unit): Modifier = this
|
||||
|
||||
actual fun Modifier.desktopPointerHoverIconHand(): Modifier = this
|
||||
|
||||
actual fun Modifier.desktopOnHovered(action: (Boolean) -> Unit): Modifier = Modifier
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user