mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
Merge branch 'master' into ep/donate-page
This commit is contained in:
@@ -73,6 +73,8 @@ final class ChatModel: ObservableObject {
|
||||
var chatItemStatuses: Dictionary<Int64, CIStatus> = [:]
|
||||
@Published var chatToTop: String?
|
||||
@Published var groupMembers: [GMember] = []
|
||||
@Published var groupMembersIndexes: Dictionary<Int64, Int> = [:] // groupMemberId to index in groupMembers list
|
||||
@Published var membersLoaded = false
|
||||
// items in the terminal view
|
||||
@Published var showingTerminal = false
|
||||
@Published var terminalItems: [TerminalItem] = []
|
||||
@@ -180,8 +182,30 @@ final class ChatModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
func populateGroupMembersIndexes() {
|
||||
groupMembersIndexes.removeAll()
|
||||
for (i, member) in groupMembers.enumerated() {
|
||||
groupMembersIndexes[member.groupMemberId] = i
|
||||
}
|
||||
}
|
||||
|
||||
func getGroupMember(_ groupMemberId: Int64) -> GMember? {
|
||||
groupMembers.first { $0.groupMemberId == groupMemberId }
|
||||
if let i = groupMembersIndexes[groupMemberId] {
|
||||
return groupMembers[i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadGroupMembers(_ groupInfo: GroupInfo, updateView: @escaping () -> Void = {}) async {
|
||||
let groupMembers = await apiListMembers(groupInfo.groupId)
|
||||
await MainActor.run {
|
||||
if chatId == groupInfo.id {
|
||||
self.groupMembers = groupMembers.map { GMember.init($0) }
|
||||
self.populateGroupMembersIndexes()
|
||||
self.membersLoaded = true
|
||||
updateView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func getChatIndex(_ id: String) -> Int? {
|
||||
@@ -330,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
|
||||
}
|
||||
@@ -379,8 +406,8 @@ final class ChatModel: ObservableObject {
|
||||
}
|
||||
|
||||
func removeChatItem(_ cInfo: ChatInfo, _ cItem: ChatItem) {
|
||||
if cItem.isRcvNew {
|
||||
decreaseUnreadCounter(cInfo)
|
||||
if cItem.isRcvNew, let chatIndex = getChatIndex(cInfo.id) {
|
||||
decreaseUnreadCounter(chatIndex)
|
||||
}
|
||||
// update previews
|
||||
if let chat = getChat(cInfo.id) {
|
||||
@@ -396,6 +423,7 @@ final class ChatModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
VoiceItemState.stopVoiceInChatView(cInfo, cItem)
|
||||
}
|
||||
|
||||
func nextChatItemData<T>(_ chatItemId: Int64, previous: Bool, map: @escaping (ChatItem) -> T?) -> T? {
|
||||
@@ -525,13 +553,18 @@ final class ChatModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
func markChatItemRead(_ cInfo: ChatInfo, _ cItem: ChatItem) {
|
||||
if chatId == cInfo.id, let i = getChatItemIndex(cItem) {
|
||||
if reversedChatItems[i].isRcvNew {
|
||||
// update current chat
|
||||
markChatItemRead_(i)
|
||||
// update preview
|
||||
decreaseUnreadCounter(cInfo)
|
||||
func markChatItemRead(_ cInfo: ChatInfo, _ cItem: ChatItem) async {
|
||||
if chatId == cInfo.id,
|
||||
let itemIndex = getChatItemIndex(cItem),
|
||||
let chatIndex = getChatIndex(cInfo.id),
|
||||
reversedChatItems[itemIndex].isRcvNew {
|
||||
await MainActor.run {
|
||||
withTransaction(Transaction()) {
|
||||
// update current chat
|
||||
markChatItemRead_(itemIndex)
|
||||
// update preview
|
||||
decreaseUnreadCounter(chatIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -547,11 +580,9 @@ final class ChatModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
func decreaseUnreadCounter(_ cInfo: ChatInfo) {
|
||||
if let i = getChatIndex(cInfo.id) {
|
||||
chats[i].chatStats.unreadCount = chats[i].chatStats.unreadCount - 1
|
||||
decreaseUnreadCounter(user: currentUser!)
|
||||
}
|
||||
func decreaseUnreadCounter(_ chatIndex: Int) {
|
||||
chats[chatIndex].chatStats.unreadCount = chats[chatIndex].chatStats.unreadCount - 1
|
||||
decreaseUnreadCounter(user: currentUser!)
|
||||
}
|
||||
|
||||
func increaseUnreadCounter(user: any UserLike) {
|
||||
@@ -667,14 +698,17 @@ final class ChatModel: ObservableObject {
|
||||
}
|
||||
// update current chat
|
||||
if chatId == groupInfo.id {
|
||||
if let i = groupMembers.firstIndex(where: { $0.groupMemberId == member.groupMemberId }) {
|
||||
if let i = groupMembersIndexes[member.groupMemberId] {
|
||||
withAnimation(.default) {
|
||||
self.groupMembers[i].wrapped = member
|
||||
self.groupMembers[i].created = Date.now
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
withAnimation { groupMembers.append(GMember(member)) }
|
||||
withAnimation {
|
||||
groupMembers.append(GMember(member))
|
||||
groupMembersIndexes[member.groupMemberId] = groupMembers.count - 1
|
||||
}
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -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
|
||||
@@ -397,7 +397,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 +405,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 +699,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 +732,7 @@ private func connectionErrorAlert(_ r: ChatResponse) -> Alert {
|
||||
} else {
|
||||
return mkAlert(
|
||||
title: "Connection error",
|
||||
message: "Error: \(String(describing: r))"
|
||||
message: "Error: \(responseError(r))"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -898,7 +898,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 +909,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 +935,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 +945,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 +1025,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,27 +1091,77 @@ func deleteRemoteCtrl(_ rcId: Int64) async throws {
|
||||
try await sendCommandOkResp(.deleteRemoteCtrl(remoteCtrlId: rcId))
|
||||
}
|
||||
|
||||
func networkErrorAlert(_ r: ChatResponse) -> Alert? {
|
||||
struct ErrorAlert {
|
||||
var title: LocalizedStringKey
|
||||
var message: LocalizedStringKey
|
||||
}
|
||||
|
||||
func getNetworkErrorAlert(_ r: ChatResponse) -> ErrorAlert? {
|
||||
switch r {
|
||||
case let .chatCmdError(_, .errorAgent(.BROKER(addr, .TIMEOUT))):
|
||||
return mkAlert(
|
||||
title: "Connection timeout",
|
||||
message: "Please check your network connection with \(serverHostname(addr)) and try again."
|
||||
)
|
||||
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 mkAlert(
|
||||
title: "Connection error",
|
||||
message: "Please check your network connection with \(serverHostname(addr)) and try again."
|
||||
)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
func networkErrorAlert(_ r: ChatResponse) -> Alert? {
|
||||
if let alert = getNetworkErrorAlert(r) {
|
||||
return mkAlert(title: alert.title, message: alert.message)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1207,7 +1257,7 @@ func apiMarkChatItemRead(_ cInfo: ChatInfo, _ cItem: ChatItem) async {
|
||||
do {
|
||||
logger.debug("apiMarkChatItemRead: \(cItem.id)")
|
||||
try await apiChatRead(type: cInfo.chatType, id: cInfo.apiId, itemRange: (cItem.id, cItem.id))
|
||||
await MainActor.run { ChatModel.shared.markChatItemRead(cInfo, cItem) }
|
||||
await ChatModel.shared.markChatItemRead(cInfo, cItem)
|
||||
} catch {
|
||||
logger.error("apiMarkChatItemRead apiChatRead error: \(responseError(error))")
|
||||
}
|
||||
@@ -1248,7 +1298,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
|
||||
}
|
||||
@@ -1354,6 +1404,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)
|
||||
@@ -1617,6 +1675,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)
|
||||
|
||||
@@ -102,8 +102,7 @@ extension ThemeWallpaper {
|
||||
public func importFromString() -> ThemeWallpaper {
|
||||
if preset == nil, let image {
|
||||
// Need to save image from string and to save its path
|
||||
if let data = Data(base64Encoded: dropImagePrefix(image)),
|
||||
let parsed = UIImage(data: data),
|
||||
if let parsed = UIImage(base64Encoded: image),
|
||||
let filename = saveWallpaperFile(image: parsed) {
|
||||
var copy = self
|
||||
copy.image = nil
|
||||
|
||||
@@ -28,15 +28,17 @@ struct ChatInfoToolbar: View {
|
||||
color: Color(uiColor: .tertiaryLabel)
|
||||
)
|
||||
.padding(.trailing, 4)
|
||||
VStack {
|
||||
let t = Text(cInfo.displayName).font(.headline)
|
||||
(cInfo.contact?.verified == true ? contactVerifiedShield + t : t)
|
||||
.lineLimit(1)
|
||||
if cInfo.fullName != "" && cInfo.displayName != cInfo.fullName {
|
||||
Text(cInfo.fullName).font(.subheadline)
|
||||
.lineLimit(1)
|
||||
let t = Text(cInfo.displayName).font(.headline)
|
||||
(cInfo.contact?.verified == true ? contactVerifiedShield + t : t)
|
||||
.lineLimit(1)
|
||||
.if (cInfo.fullName != "" && cInfo.displayName != cInfo.fullName) { v in
|
||||
VStack(spacing: 0) {
|
||||
v
|
||||
Text(cInfo.fullName).font(.subheadline)
|
||||
.lineLimit(1)
|
||||
.padding(.top, -2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.foregroundColor(theme.colors.onBackground)
|
||||
.frame(width: 220)
|
||||
|
||||
@@ -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 smallView: Bool = false
|
||||
|
||||
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 smallView {
|
||||
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 {
|
||||
@@ -199,17 +205,17 @@ struct CIFileView: View {
|
||||
Image(systemName: icon)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 30, height: 30)
|
||||
.frame(width: smallView ? 36 : 30, height: smallView ? 36 : 30)
|
||||
.foregroundColor(color)
|
||||
if let innerIcon = innerIcon,
|
||||
let innerIconSize = innerIconSize {
|
||||
let innerIconSize = innerIconSize, (!smallView || 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, smallView ? 15 : 12)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,14 +12,15 @@ 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) {
|
||||
if let data = Data(base64Encoded: dropImagePrefix(linkPreview.image)),
|
||||
let uiImage = UIImage(data: data) {
|
||||
if let uiImage = UIImage(base64Encoded: linkPreview.image) {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.modifier(PrivacyBlur(blurred: $blurred))
|
||||
}
|
||||
VStack(alignment: .leading, spacing: 6) {
|
||||
Text(linkPreview.title)
|
||||
|
||||
@@ -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 smallView: Bool = false
|
||||
@State private var seek: (TimeInterval) -> Void = { _ in }
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
if chatItem.chatDir.sent {
|
||||
if smallView {
|
||||
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 {
|
||||
@@ -55,6 +66,7 @@ struct CIVoiceView: View {
|
||||
|
||||
private func player() -> some View {
|
||||
VoiceMessagePlayer(
|
||||
chat: chat,
|
||||
chatItem: chatItem,
|
||||
recordingFile: recordingFile,
|
||||
recordingTime: TimeInterval(duration),
|
||||
@@ -63,7 +75,8 @@ struct CIVoiceView: View {
|
||||
audioPlayer: $audioPlayer,
|
||||
playbackState: $playbackState,
|
||||
playbackTime: $playbackTime,
|
||||
allowMenu: $allowMenu
|
||||
allowMenu: $allowMenu,
|
||||
sizeMultiplier: smallView ? voiceMessageSizeBasedOnSquareSize(36) / 56 : 1
|
||||
)
|
||||
}
|
||||
|
||||
@@ -119,6 +132,7 @@ struct VoiceMessagePlayerTime: View {
|
||||
}
|
||||
|
||||
struct VoiceMessagePlayer: View {
|
||||
@ObservedObject var chat: Chat
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
var chatItem: ChatItem
|
||||
@@ -130,7 +144,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 +206,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 +322,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 +389,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 +503,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
@@ -415,7 +415,7 @@ struct ChatItemInfoView: View {
|
||||
}
|
||||
|
||||
@ViewBuilder private func memberDeliveryStatusesView(_ memberDeliveryStatuses: [MemberDeliveryStatus]) -> some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
LazyVStack(alignment: .leading, spacing: 12) {
|
||||
let mss = membersStatuses(memberDeliveryStatuses)
|
||||
if !mss.isEmpty {
|
||||
ForEach(mss, id: \.0.groupMemberId) { memberStatus in
|
||||
@@ -428,7 +428,7 @@ struct ChatItemInfoView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func membersStatuses(_ memberDeliveryStatuses: [MemberDeliveryStatus]) -> [(GroupMember, CIStatus, Bool?)] {
|
||||
private func membersStatuses(_ memberDeliveryStatuses: [MemberDeliveryStatus]) -> [(GroupMember, GroupSndStatus, Bool?)] {
|
||||
memberDeliveryStatuses.compactMap({ mds in
|
||||
if let mem = chatModel.getGroupMember(mds.groupMemberId) {
|
||||
return (mem.wrapped, mds.memberDeliveryStatus, mds.sentViaProxy)
|
||||
@@ -438,7 +438,7 @@ struct ChatItemInfoView: View {
|
||||
})
|
||||
}
|
||||
|
||||
private func memberDeliveryStatusView(_ member: GroupMember, _ status: CIStatus, _ sentViaProxy: Bool?) -> some View {
|
||||
private func memberDeliveryStatusView(_ member: GroupMember, _ status: GroupSndStatus, _ sentViaProxy: Bool?) -> some View {
|
||||
HStack{
|
||||
ProfileImage(imageStr: member.image, size: 30)
|
||||
.padding(.trailing, 2)
|
||||
@@ -450,23 +450,19 @@ struct ChatItemInfoView: View {
|
||||
.foregroundColor(theme.colors.secondary).opacity(0.67)
|
||||
}
|
||||
let v = Group {
|
||||
if let (icon, statusColor) = status.statusIcon(theme.colors.secondary, theme.colors.primary) {
|
||||
switch status {
|
||||
case .sndRcvd:
|
||||
ZStack(alignment: .trailing) {
|
||||
Image(systemName: icon)
|
||||
.foregroundColor(statusColor.opacity(0.67))
|
||||
.padding(.trailing, 6)
|
||||
Image(systemName: icon)
|
||||
.foregroundColor(statusColor.opacity(0.67))
|
||||
}
|
||||
default:
|
||||
let (icon, statusColor) = status.statusIcon(theme.colors.secondary, theme.colors.primary)
|
||||
switch status {
|
||||
case .rcvd:
|
||||
ZStack(alignment: .trailing) {
|
||||
Image(systemName: icon)
|
||||
.foregroundColor(statusColor)
|
||||
.foregroundColor(statusColor.opacity(0.67))
|
||||
.padding(.trailing, 6)
|
||||
Image(systemName: icon)
|
||||
.foregroundColor(statusColor.opacity(0.67))
|
||||
}
|
||||
} else {
|
||||
Image(systemName: "ellipsis")
|
||||
.foregroundColor(Color.secondary)
|
||||
default:
|
||||
Image(systemName: icon)
|
||||
.foregroundColor(statusColor)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
@@ -68,9 +60,7 @@ struct ChatItemView: View {
|
||||
default: nil
|
||||
}
|
||||
}
|
||||
.map { dropImagePrefix($0) }
|
||||
.flatMap { Data(base64Encoded: $0) }
|
||||
.flatMap { UIImage(data: $0) }
|
||||
.flatMap { UIImage(base64Encoded: $0) }
|
||||
let adjustedMaxWidth = {
|
||||
if let preview, preview.size.width <= preview.size.height {
|
||||
maxWidth * 0.75
|
||||
@@ -86,10 +76,7 @@ struct ChatItemView: View {
|
||||
maxWidth: maxWidth,
|
||||
imgWidth: adjustedMaxWidth,
|
||||
videoWidth: adjustedMaxWidth,
|
||||
allowMenu: $allowMenu,
|
||||
audioPlayer: $audioPlayer,
|
||||
playbackState: $playbackState,
|
||||
playbackTime: $playbackTime
|
||||
allowMenu: $allowMenu
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ struct ChatView: View {
|
||||
@State private var searchText: String = ""
|
||||
@FocusState private var searchFocussed
|
||||
// opening GroupMemberInfoView on member icon
|
||||
@State private var membersLoaded = false
|
||||
@State private var selectedMember: GMember? = nil
|
||||
// opening GroupLinkView on link button (incognito)
|
||||
@State private var showGroupLinkSheet: Bool = false
|
||||
@@ -46,9 +45,14 @@ struct ChatView: View {
|
||||
|
||||
var body: some View {
|
||||
if #available(iOS 16.0, *) {
|
||||
viewBody
|
||||
let v = viewBody
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
.keyboardPadding()
|
||||
if (searchMode) {
|
||||
v.toolbarBackground(.thinMaterial, for: .navigationBar)
|
||||
} else {
|
||||
v.toolbarBackground(.visible, for: .navigationBar)
|
||||
}
|
||||
} else {
|
||||
viewBody
|
||||
}
|
||||
@@ -82,7 +86,6 @@ struct ChatView: View {
|
||||
)
|
||||
.disabled(!cInfo.sendMsgEnabled)
|
||||
}
|
||||
.padding(.top, 1)
|
||||
.navigationTitle(cInfo.chatViewName)
|
||||
.background(theme.colors.background)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
@@ -93,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
|
||||
@@ -114,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) {
|
||||
@@ -121,7 +126,8 @@ struct ChatView: View {
|
||||
chatModel.chatItemStatuses = [:]
|
||||
chatModel.reversedChatItems = []
|
||||
chatModel.groupMembers = []
|
||||
membersLoaded = false
|
||||
chatModel.groupMembersIndexes.removeAll()
|
||||
chatModel.membersLoaded = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,7 +169,7 @@ struct ChatView: View {
|
||||
}
|
||||
} else if case let .group(groupInfo) = cInfo {
|
||||
Button {
|
||||
Task { await loadGroupMembers(groupInfo) { showChatInfoSheet = true } }
|
||||
Task { await chatModel.loadGroupMembers(groupInfo) { showChatInfoSheet = true } }
|
||||
} label: {
|
||||
ChatInfoToolbar(chat: chat)
|
||||
.tint(theme.colors.primary)
|
||||
@@ -249,18 +255,7 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func loadGroupMembers(_ groupInfo: GroupInfo, updateView: @escaping () -> Void = {}) async {
|
||||
let groupMembers = await apiListMembers(groupInfo.groupId)
|
||||
await MainActor.run {
|
||||
if chatModel.chatId == groupInfo.id {
|
||||
chatModel.groupMembers = groupMembers.map { GMember.init($0) }
|
||||
membersLoaded = true
|
||||
updateView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func initChatView() {
|
||||
let cInfo = chat.chatInfo
|
||||
// This check prevents the call to apiContactInfo after the app is suspended, and the database is closed.
|
||||
@@ -321,8 +316,9 @@ struct ChatView: View {
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.padding(.vertical, 8)
|
||||
.background(.thinMaterial)
|
||||
}
|
||||
|
||||
|
||||
private func voiceWithoutFrame(_ ci: ChatItem) -> Bool {
|
||||
ci.content.msgContent?.isVoice == true && ci.content.text.count == 0 && ci.quotedItem == nil && ci.meta.itemForwarded == nil
|
||||
}
|
||||
@@ -384,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…")
|
||||
@@ -475,9 +471,7 @@ struct ChatView: View {
|
||||
.foregroundColor(theme.colors.primary)
|
||||
}
|
||||
.onTapGesture {
|
||||
if let latestUnreadItem = filtered(chatModel.reversedChatItems).last(where: { $0.isRcvNew }) {
|
||||
scrollModel.scrollToItem(id: latestUnreadItem.id)
|
||||
}
|
||||
scrollModel.scrollToBottom()
|
||||
}
|
||||
} else if !counts.isNearBottom {
|
||||
circleButton {
|
||||
@@ -532,7 +526,7 @@ struct ChatView: View {
|
||||
private func addMembersButton() -> some View {
|
||||
Button {
|
||||
if case let .group(gInfo) = chat.chatInfo {
|
||||
Task { await loadGroupMembers(gInfo) { showAddMembersSheet = true } }
|
||||
Task { await chatModel.loadGroupMembers(gInfo) { showAddMembersSheet = true } }
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "person.crop.circle.badge.plus")
|
||||
@@ -597,16 +591,19 @@ 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,
|
||||
chatItem: ci,
|
||||
maxWidth: maxWidth,
|
||||
itemWidth: maxWidth,
|
||||
composeState: $composeState,
|
||||
selectedMember: $selectedMember,
|
||||
revealedChatItem: $revealedChatItem,
|
||||
chatView: self
|
||||
revealedChatItem: $revealedChatItem
|
||||
)
|
||||
}
|
||||
|
||||
@@ -614,13 +611,11 @@ struct ChatView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@ObservedObject var chat: Chat
|
||||
var chatItem: ChatItem
|
||||
var maxWidth: CGFloat
|
||||
@State var itemWidth: CGFloat
|
||||
let chatItem: ChatItem
|
||||
let maxWidth: CGFloat
|
||||
@Binding var composeState: ComposeState
|
||||
@Binding var selectedMember: GMember?
|
||||
@Binding var revealedChatItem: ChatItem?
|
||||
var chatView: ChatView
|
||||
|
||||
@State private var deletingItem: ChatItem? = nil
|
||||
@State private var showDeleteMessage = false
|
||||
@@ -632,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 {
|
||||
@@ -688,7 +679,12 @@ struct ChatView: View {
|
||||
if prevItem == nil || showMemberImage(member, prevItem) || prevMember != nil {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
if ci.content.showMemberName {
|
||||
Text(memberNames(member, prevMember, memCount))
|
||||
let t = if memCount == 1 && member.memberRole > .member {
|
||||
Text(member.memberRole.text + " ").fontWeight(.semibold) + Text(member.displayName)
|
||||
} else {
|
||||
Text(memberNames(member, prevMember, memCount))
|
||||
}
|
||||
t
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
.lineLimit(2)
|
||||
@@ -698,11 +694,11 @@ struct ChatView: View {
|
||||
HStack(alignment: .top, spacing: 8) {
|
||||
ProfileImage(imageStr: member.memberProfile.image, size: memberImageSize, backgroundColor: theme.colors.background)
|
||||
.onTapGesture {
|
||||
if chatView.membersLoaded {
|
||||
if m.membersLoaded {
|
||||
selectedMember = m.getGroupMember(member.groupMemberId)
|
||||
} else {
|
||||
Task {
|
||||
await chatView.loadGroupMembers(groupInfo) {
|
||||
await m.loadGroupMembers(groupInfo) {
|
||||
selectedMember = m.getGroupMember(member.groupMemberId)
|
||||
}
|
||||
}
|
||||
@@ -714,19 +710,19 @@ struct ChatView: View {
|
||||
chatItemWithMenu(ci, range, maxWidth)
|
||||
}
|
||||
}
|
||||
.padding(.top, 5)
|
||||
.padding(.bottom, 5)
|
||||
.padding(.trailing)
|
||||
.padding(.leading, 12)
|
||||
} else {
|
||||
chatItemWithMenu(ci, range, maxWidth)
|
||||
.padding(.top, 5)
|
||||
.padding(.bottom, 5)
|
||||
.padding(.trailing)
|
||||
.padding(.leading, memberImageSize + 8 + 12)
|
||||
}
|
||||
} else {
|
||||
chatItemWithMenu(ci, range, maxWidth)
|
||||
.padding(.horizontal)
|
||||
.padding(.top, 5)
|
||||
.padding(.bottom, 5)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -749,10 +745,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) }
|
||||
@@ -779,14 +772,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
|
||||
}) {
|
||||
@@ -1097,7 +1082,7 @@ struct ChatView: View {
|
||||
chatItemInfo = ciInfo
|
||||
}
|
||||
if case let .group(gInfo) = chat.chatInfo {
|
||||
await chatView.loadGroupMembers(gInfo)
|
||||
await m.loadGroupMembers(gInfo)
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("apiGetChatItemInfo error: \(responseError(error))")
|
||||
|
||||
@@ -32,9 +32,8 @@ struct ComposeFileView: View {
|
||||
}
|
||||
.padding(.vertical, 1)
|
||||
.padding(.trailing, 12)
|
||||
.frame(height: 50)
|
||||
.frame(height: 54)
|
||||
.background(theme.appColors.sentMessage)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, 8)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,7 @@ struct ComposeImageView: View {
|
||||
var body: some View {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
let imgs: [UIImage] = images.compactMap { image in
|
||||
if let data = Data(base64Encoded: dropImagePrefix(image)) {
|
||||
return UIImage(data: data)
|
||||
}
|
||||
return nil
|
||||
UIImage(base64Encoded: image)
|
||||
}
|
||||
if imgs.count == 0 {
|
||||
ProgressView()
|
||||
@@ -49,8 +46,8 @@ struct ComposeImageView: View {
|
||||
.padding(.vertical, 1)
|
||||
.padding(.trailing, 12)
|
||||
.background(theme.appColors.sentMessage)
|
||||
.frame(minHeight: 54)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, 8)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,14 +63,13 @@ struct ComposeLinkView: View {
|
||||
.padding(.vertical, 1)
|
||||
.padding(.trailing, 12)
|
||||
.background(theme.appColors.sentMessage)
|
||||
.frame(minHeight: 54)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, 8)
|
||||
}
|
||||
|
||||
private func linkPreviewView(_ linkPreview: LinkPreview) -> some View {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
if let data = Data(base64Encoded: dropImagePrefix(linkPreview.image)),
|
||||
let uiImage = UIImage(data: data) {
|
||||
if let uiImage = UIImage(base64Encoded: linkPreview.image) {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
|
||||
@@ -284,8 +284,10 @@ struct ComposeView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
Divider()
|
||||
if chat.chatInfo.contact?.nextSendGrpInv ?? false {
|
||||
ContextInvitingContactMemberView()
|
||||
Divider()
|
||||
}
|
||||
// preference checks should match checks in forwarding list
|
||||
let simplexLinkProhibited = hasSimplexLink && !chat.groupFeatureEnabled(.simplexLinks)
|
||||
@@ -293,10 +295,13 @@ struct ComposeView: View {
|
||||
let voiceProhibited = composeState.voicePreview && !chat.chatInfo.featureEnabled(.voice)
|
||||
if simplexLinkProhibited {
|
||||
msgNotAllowedView("SimpleX links not allowed", icon: "link")
|
||||
Divider()
|
||||
} else if fileProhibited {
|
||||
msgNotAllowedView("Files and media not allowed", icon: "doc")
|
||||
Divider()
|
||||
} else if voiceProhibited {
|
||||
msgNotAllowedView("Voice messages not allowed", icon: "mic")
|
||||
Divider()
|
||||
}
|
||||
contextItemView()
|
||||
switch (composeState.editing, composeState.preview) {
|
||||
@@ -359,7 +364,6 @@ struct ComposeView: View {
|
||||
: theme.colors.primary
|
||||
)
|
||||
.padding(.trailing, 12)
|
||||
.background(theme.colors.background)
|
||||
.disabled(!chat.userCanSend)
|
||||
|
||||
if chat.userIsObserver {
|
||||
@@ -377,6 +381,7 @@ struct ComposeView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.background(.thinMaterial)
|
||||
.onChange(of: composeState.message) { msg in
|
||||
if composeState.linkPreviewAllowed {
|
||||
if msg.count > 0 {
|
||||
@@ -625,6 +630,7 @@ struct ComposeView: View {
|
||||
cancelPreview: cancelLinkPreview,
|
||||
cancelEnabled: !composeState.inProgress
|
||||
)
|
||||
Divider()
|
||||
case let .mediaPreviews(mediaPreviews: media):
|
||||
ComposeImageView(
|
||||
images: media.map { (img, _) in img },
|
||||
@@ -633,6 +639,7 @@ struct ComposeView: View {
|
||||
chosenMedia = []
|
||||
},
|
||||
cancelEnabled: !composeState.editing && !composeState.inProgress)
|
||||
Divider()
|
||||
case let .voicePreview(recordingFileName, _):
|
||||
ComposeVoiceView(
|
||||
recordingFileName: recordingFileName,
|
||||
@@ -645,6 +652,7 @@ struct ComposeView: View {
|
||||
cancelEnabled: !composeState.editing && !composeState.inProgress,
|
||||
stopPlayback: $stopPlayback
|
||||
)
|
||||
Divider()
|
||||
case let .filePreview(fileName, _):
|
||||
ComposeFileView(
|
||||
fileName: fileName,
|
||||
@@ -652,6 +660,7 @@ struct ComposeView: View {
|
||||
composeState = composeState.copy(preview: .noPreview)
|
||||
},
|
||||
cancelEnabled: !composeState.editing && !composeState.inProgress)
|
||||
Divider()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -661,10 +670,9 @@ struct ComposeView: View {
|
||||
Text(reason).italic()
|
||||
}
|
||||
.padding(12)
|
||||
.frame(minHeight: 50)
|
||||
.frame(minHeight: 54)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.background(Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
.padding(.top, 8)
|
||||
.background(.thinMaterial)
|
||||
}
|
||||
|
||||
@ViewBuilder private func contextItemView() -> some View {
|
||||
@@ -678,6 +686,7 @@ struct ComposeView: View {
|
||||
contextIcon: "arrowshape.turn.up.left",
|
||||
cancelContextItem: { composeState = composeState.copy(contextItem: .noContextItem) }
|
||||
)
|
||||
Divider()
|
||||
case let .editingItem(chatItem: editingItem):
|
||||
ContextItemView(
|
||||
chat: chat,
|
||||
@@ -685,6 +694,7 @@ struct ComposeView: View {
|
||||
contextIcon: "pencil",
|
||||
cancelContextItem: { clearState() }
|
||||
)
|
||||
Divider()
|
||||
case let .forwardingItem(chatItem: forwardedItem, _):
|
||||
ContextItemView(
|
||||
chat: chat,
|
||||
@@ -693,6 +703,7 @@ struct ComposeView: View {
|
||||
cancelContextItem: { composeState = composeState.copy(contextItem: .noContextItem) },
|
||||
showSender: false
|
||||
)
|
||||
Divider()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -849,6 +860,7 @@ struct ComposeView: View {
|
||||
func sendVideo(_ imageData: (String, UploadContent?), text: String = "", quoted: Int64? = nil, live: Bool = false, ttl: Int?) async -> ChatItem? {
|
||||
let (image, data) = imageData
|
||||
if case let .video(_, url, duration) = data, let savedFile = moveTempFileFromURL(url) {
|
||||
ChatModel.shared.filesToDelete.remove(url)
|
||||
return await send(.video(text: text, image: image, duration: duration), quoted: quoted, file: savedFile, live: live, ttl: ttl)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -51,8 +51,8 @@ struct ComposeVoiceView: View {
|
||||
.padding(.vertical, 1)
|
||||
.frame(height: ComposeVoiceView.previewHeight)
|
||||
.background(theme.appColors.sentMessage)
|
||||
.frame(minHeight: 54)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, 8)
|
||||
}
|
||||
|
||||
private func recordingMode() -> some View {
|
||||
|
||||
@@ -18,10 +18,9 @@ struct ContextInvitingContactMemberView: View {
|
||||
Text("Send direct message to connect")
|
||||
}
|
||||
.padding(12)
|
||||
.frame(minHeight: 50)
|
||||
.frame(minHeight: 54)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.background(theme.appColors.sentMessage)
|
||||
.padding(.top, 8)
|
||||
.background(.thinMaterial)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,9 @@ struct ContextItemView: View {
|
||||
.tint(theme.colors.primary)
|
||||
}
|
||||
.padding(12)
|
||||
.frame(minHeight: 50)
|
||||
.frame(minHeight: 54)
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(chatItemFrameColor(contextItem, theme))
|
||||
.padding(.top, 8)
|
||||
}
|
||||
|
||||
private func msgContentView(lines: Int) -> some View {
|
||||
|
||||
@@ -44,6 +44,7 @@ struct SendMessageView: View {
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
let composeShape = RoundedRectangle(cornerSize: CGSize(width: 20, height: 20))
|
||||
HStack(alignment: .bottom) {
|
||||
ZStack(alignment: .leading) {
|
||||
if case .voicePreview = composeState.preview {
|
||||
@@ -84,10 +85,9 @@ struct SendMessageView: View {
|
||||
}
|
||||
}
|
||||
.padding(.vertical, 1)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerSize: CGSize(width: 20, height: 20))
|
||||
.strokeBorder(.secondary, lineWidth: 0.3, antialiased: true)
|
||||
)
|
||||
.background(theme.colors.background)
|
||||
.clipShape(composeShape)
|
||||
.overlay(composeShape.strokeBorder(.secondary, lineWidth: 0.3, antialiased: true))
|
||||
}
|
||||
.onChange(of: composeState.message, perform: { text in updateFont(text) })
|
||||
.onChange(of: composeState.inProgress) { inProgress in
|
||||
|
||||
@@ -207,6 +207,7 @@ struct GroupChatInfoView: View {
|
||||
let groupMembers = await apiListMembers(groupInfo.groupId)
|
||||
await MainActor.run {
|
||||
chatModel.groupMembers = groupMembers.map { GMember.init($0) }
|
||||
chatModel.populateGroupMembersIndexes()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,8 +233,7 @@ struct GroupChatInfoView: View {
|
||||
let t = Text(member.chatViewName).foregroundColor(member.memberIncognito ? .indigo : theme.colors.onBackground)
|
||||
(member.verified ? memberVerifiedShield + t : t)
|
||||
.lineLimit(1)
|
||||
let s = Text(member.memberStatus.shortText)
|
||||
(user ? Text ("you: ") + s : s)
|
||||
(user ? Text ("you: ") + Text(member.memberStatus.shortText) : Text(memberConnStatus(member)))
|
||||
.lineLimit(1)
|
||||
.font(.caption)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
@@ -266,6 +266,16 @@ struct GroupChatInfoView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func memberConnStatus(_ member: GroupMember) -> LocalizedStringKey {
|
||||
if member.activeConn?.connDisabled ?? false {
|
||||
return "disabled"
|
||||
} else if member.activeConn?.connInactive ?? false {
|
||||
return "inactive"
|
||||
} else {
|
||||
return member.memberStatus.shortText
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func memberInfo(_ member: GroupMember) -> some View {
|
||||
if member.blocked {
|
||||
Text("blocked")
|
||||
|
||||
@@ -76,157 +76,153 @@ struct GroupMemberInfoView: View {
|
||||
|
||||
private func groupMemberInfoView() -> some View {
|
||||
ZStack {
|
||||
VStack {
|
||||
let member = groupMember.wrapped
|
||||
List {
|
||||
groupMemberInfoHeader(member)
|
||||
.listRowBackground(Color.clear)
|
||||
let member = groupMember.wrapped
|
||||
List {
|
||||
groupMemberInfoHeader(member)
|
||||
.listRowBackground(Color.clear)
|
||||
|
||||
if member.memberActive {
|
||||
Section {
|
||||
if let contactId = member.memberContactId, let chat = knownDirectChat(contactId) {
|
||||
knownDirectChatButton(chat)
|
||||
} else if groupInfo.fullGroupPreferences.directMessages.on(for: groupInfo.membership) {
|
||||
if let contactId = member.memberContactId {
|
||||
newDirectChatButton(contactId)
|
||||
} else if member.activeConn?.peerChatVRange.isCompatibleRange(CREATE_MEMBER_CONTACT_VRANGE) ?? false {
|
||||
createMemberContactButton()
|
||||
}
|
||||
}
|
||||
if let code = connectionCode { verifyCodeButton(code) }
|
||||
if let connStats = connectionStats,
|
||||
connStats.ratchetSyncAllowed {
|
||||
synchronizeConnectionButton()
|
||||
}
|
||||
// } else if developerTools {
|
||||
// synchronizeConnectionButtonForce()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
if let contactLink = member.contactLink {
|
||||
Section {
|
||||
SimpleXLinkQRCode(uri: contactLink)
|
||||
Button {
|
||||
showShareSheet(items: [simplexChatLink(contactLink)])
|
||||
} label: {
|
||||
Label("Share address", systemImage: "square.and.arrow.up")
|
||||
}
|
||||
if member.memberActive {
|
||||
Section {
|
||||
if let contactId = member.memberContactId, let chat = knownDirectChat(contactId) {
|
||||
knownDirectChatButton(chat)
|
||||
} else if groupInfo.fullGroupPreferences.directMessages.on(for: groupInfo.membership) {
|
||||
if let contactId = member.memberContactId {
|
||||
if knownDirectChat(contactId) == nil && !groupInfo.fullGroupPreferences.directMessages.on(for: groupInfo.membership) {
|
||||
connectViaAddressButton(contactLink)
|
||||
}
|
||||
} else {
|
||||
newDirectChatButton(contactId)
|
||||
} else if member.activeConn?.peerChatVRange.isCompatibleRange(CREATE_MEMBER_CONTACT_VRANGE) ?? false {
|
||||
createMemberContactButton()
|
||||
}
|
||||
}
|
||||
if let code = connectionCode { verifyCodeButton(code) }
|
||||
if let connStats = connectionStats,
|
||||
connStats.ratchetSyncAllowed {
|
||||
synchronizeConnectionButton()
|
||||
}
|
||||
// } else if developerTools {
|
||||
// synchronizeConnectionButtonForce()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
if let contactLink = member.contactLink {
|
||||
Section {
|
||||
SimpleXLinkQRCode(uri: contactLink)
|
||||
Button {
|
||||
showShareSheet(items: [simplexChatLink(contactLink)])
|
||||
} label: {
|
||||
Label("Share address", systemImage: "square.and.arrow.up")
|
||||
}
|
||||
if let contactId = member.memberContactId {
|
||||
if knownDirectChat(contactId) == nil && !groupInfo.fullGroupPreferences.directMessages.on(for: groupInfo.membership) {
|
||||
connectViaAddressButton(contactLink)
|
||||
}
|
||||
} header: {
|
||||
Text("Address")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
} footer: {
|
||||
Text("You can share this address with your contacts to let them connect with **\(member.displayName)**.")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
Section(header: Text("Member").foregroundColor(theme.colors.secondary)) {
|
||||
infoRow("Group", groupInfo.displayName)
|
||||
|
||||
if let roles = member.canChangeRoleTo(groupInfo: groupInfo) {
|
||||
Picker("Change role", selection: $newRole) {
|
||||
ForEach(roles) { role in
|
||||
Text(role.text)
|
||||
}
|
||||
}
|
||||
.frame(height: 36)
|
||||
} else {
|
||||
infoRow("Role", member.memberRole.text)
|
||||
connectViaAddressButton(contactLink)
|
||||
}
|
||||
} header: {
|
||||
Text("Address")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
} footer: {
|
||||
Text("You can share this address with your contacts to let them connect with **\(member.displayName)**.")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO invited by - need to get contact by contact id
|
||||
Section(header: Text("Member").foregroundColor(theme.colors.secondary)) {
|
||||
infoRow("Group", groupInfo.displayName)
|
||||
|
||||
if let roles = member.canChangeRoleTo(groupInfo: groupInfo) {
|
||||
Picker("Change role", selection: $newRole) {
|
||||
ForEach(roles) { role in
|
||||
Text(role.text)
|
||||
}
|
||||
}
|
||||
.frame(height: 36)
|
||||
} else {
|
||||
infoRow("Role", member.memberRole.text)
|
||||
}
|
||||
}
|
||||
|
||||
if let connStats = connectionStats {
|
||||
Section(header: Text("Servers").foregroundColor(theme.colors.secondary)) {
|
||||
// TODO network connection status
|
||||
Button("Change receiving address") {
|
||||
alert = .switchAddressAlert
|
||||
}
|
||||
.disabled(
|
||||
connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil }
|
||||
|| connStats.ratchetSyncSendProhibited
|
||||
)
|
||||
if connStats.rcvQueuesInfo.contains(where: { $0.rcvSwitchStatus != nil }) {
|
||||
Button("Abort changing address") {
|
||||
alert = .abortSwitchAddressAlert
|
||||
}
|
||||
.disabled(
|
||||
connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil && !$0.canAbortSwitch }
|
||||
|| connStats.ratchetSyncSendProhibited
|
||||
)
|
||||
}
|
||||
smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }, theme.colors.secondary)
|
||||
smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }, theme.colors.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
if groupInfo.membership.memberRole >= .admin {
|
||||
adminDestructiveSection(member)
|
||||
} else {
|
||||
nonAdminBlockSection(member)
|
||||
}
|
||||
|
||||
if developerTools {
|
||||
Section(header: Text("For console").foregroundColor(theme.colors.secondary)) {
|
||||
infoRow("Local name", member.localDisplayName)
|
||||
infoRow("Database ID", "\(member.groupMemberId)")
|
||||
if let conn = member.activeConn {
|
||||
let connLevelDesc = conn.connLevel == 0 ? NSLocalizedString("direct", comment: "connection level description") : String.localizedStringWithFormat(NSLocalizedString("indirect (%d)", comment: "connection level description"), conn.connLevel)
|
||||
infoRow("Connection", connLevelDesc)
|
||||
}
|
||||
}
|
||||
|
||||
if let connStats = connectionStats {
|
||||
Section(header: Text("Servers").foregroundColor(theme.colors.secondary)) {
|
||||
// TODO network connection status
|
||||
Button("Change receiving address") {
|
||||
alert = .switchAddressAlert
|
||||
}
|
||||
.disabled(
|
||||
connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil }
|
||||
|| connStats.ratchetSyncSendProhibited
|
||||
)
|
||||
if connStats.rcvQueuesInfo.contains(where: { $0.rcvSwitchStatus != nil }) {
|
||||
Button("Abort changing address") {
|
||||
alert = .abortSwitchAddressAlert
|
||||
}
|
||||
.disabled(
|
||||
connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil && !$0.canAbortSwitch }
|
||||
|| connStats.ratchetSyncSendProhibited
|
||||
)
|
||||
}
|
||||
smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }, theme.colors.secondary)
|
||||
smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }, theme.colors.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
if groupInfo.membership.memberRole >= .admin {
|
||||
adminDestructiveSection(member)
|
||||
} else {
|
||||
nonAdminBlockSection(member)
|
||||
}
|
||||
|
||||
if developerTools {
|
||||
Section(header: Text("For console").foregroundColor(theme.colors.secondary)) {
|
||||
infoRow("Local name", member.localDisplayName)
|
||||
infoRow("Database ID", "\(member.groupMemberId)")
|
||||
Button ("Debug delivery") {
|
||||
Task {
|
||||
do {
|
||||
let info = queueInfoText(try await apiGroupMemberQueueInfo(groupInfo.apiId, member.groupMemberId))
|
||||
await MainActor.run { alert = .queueInfo(info: info) }
|
||||
} catch let e {
|
||||
logger.error("apiContactQueueInfo error: \(responseError(e))")
|
||||
let a = getErrorAlert(e, "Error")
|
||||
await MainActor.run { alert = .error(title: a.title, error: a.message) }
|
||||
}
|
||||
Button ("Debug delivery") {
|
||||
Task {
|
||||
do {
|
||||
let info = queueInfoText(try await apiGroupMemberQueueInfo(groupInfo.apiId, member.groupMemberId))
|
||||
await MainActor.run { alert = .queueInfo(info: info) }
|
||||
} catch let e {
|
||||
logger.error("apiContactQueueInfo error: \(responseError(e))")
|
||||
let a = getErrorAlert(e, "Error")
|
||||
await MainActor.run { alert = .error(title: a.title, error: a.message) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
.onAppear {
|
||||
if #unavailable(iOS 16) {
|
||||
// this condition prevents re-setting picker
|
||||
if !justOpened { return }
|
||||
}
|
||||
justOpened = false
|
||||
DispatchQueue.main.async {
|
||||
newRole = member.memberRole
|
||||
do {
|
||||
let (_, stats) = try apiGroupMemberInfo(groupInfo.apiId, member.groupMemberId)
|
||||
let (mem, code) = member.memberActive ? try apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) : (member, nil)
|
||||
_ = chatModel.upsertGroupMember(groupInfo, mem)
|
||||
connectionStats = stats
|
||||
connectionCode = code
|
||||
} catch let error {
|
||||
logger.error("apiGroupMemberInfo or apiGetGroupMemberCode error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
.onAppear {
|
||||
if #unavailable(iOS 16) {
|
||||
// this condition prevents re-setting picker
|
||||
if !justOpened { return }
|
||||
}
|
||||
justOpened = false
|
||||
DispatchQueue.main.async {
|
||||
newRole = member.memberRole
|
||||
do {
|
||||
let (_, stats) = try apiGroupMemberInfo(groupInfo.apiId, member.groupMemberId)
|
||||
let (mem, code) = member.memberActive ? try apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) : (member, nil)
|
||||
_ = chatModel.upsertGroupMember(groupInfo, mem)
|
||||
connectionStats = stats
|
||||
connectionCode = code
|
||||
} catch let error {
|
||||
logger.error("apiGroupMemberInfo or apiGetGroupMemberCode error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
.onChange(of: newRole) { newRole in
|
||||
if newRole != member.memberRole {
|
||||
alert = .changeMemberRoleAlert(mem: member, role: newRole)
|
||||
}
|
||||
}
|
||||
.onChange(of: member.memberRole) { role in
|
||||
newRole = role
|
||||
}
|
||||
.onChange(of: newRole) { newRole in
|
||||
if newRole != member.memberRole {
|
||||
alert = .changeMemberRoleAlert(mem: member, role: newRole)
|
||||
}
|
||||
}
|
||||
.onChange(of: member.memberRole) { role in
|
||||
newRole = role
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
||||
.alert(item: $alert) { alertItem in
|
||||
switch(alertItem) {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -100,7 +100,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))
|
||||
@@ -114,7 +114,7 @@ struct ChatListNavLink: 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: [
|
||||
@@ -564,18 +564,11 @@ func joinGroup(_ groupId: Int64, _ onComplete: @escaping () async -> Void) {
|
||||
}
|
||||
}
|
||||
|
||||
struct ErrorAlert {
|
||||
var title: LocalizedStringKey
|
||||
var message: LocalizedStringKey
|
||||
}
|
||||
|
||||
func getErrorAlert(_ error: Error, _ title: LocalizedStringKey) -> ErrorAlert {
|
||||
switch error as? ChatResponse {
|
||||
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.")
|
||||
default:
|
||||
if let r = error as? ChatResponse,
|
||||
let alert = getNetworkErrorAlert(r) {
|
||||
return alert
|
||||
} else {
|
||||
return ErrorAlert(title: title, message: "Error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
@@ -267,31 +277,25 @@ struct ChatListView: View {
|
||||
|
||||
struct SubsStatusIndicator: View {
|
||||
@State private var subs: SMPServerSubs = SMPServerSubs.newSMPServerSubs
|
||||
@State private var sess: ServerSessions = ServerSessions.newServerSessions
|
||||
@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
|
||||
|
||||
// Constants for the intervals
|
||||
let initialInterval: TimeInterval = 1.0
|
||||
let regularInterval: TimeInterval = 3.0
|
||||
let initialPhaseDuration: TimeInterval = 10.0 // Duration for initial phase in seconds
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
showServersSummary = true
|
||||
} label: {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
startInitialTimer()
|
||||
startTimer()
|
||||
}
|
||||
.onDisappear {
|
||||
stopTimer()
|
||||
@@ -301,35 +305,24 @@ struct SubsStatusIndicator: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func startInitialTimer() {
|
||||
timer = Timer.scheduledTimer(withTimeInterval: initialInterval, repeats: true) { _ in
|
||||
getServersSummary()
|
||||
timerCounter += 1
|
||||
// Switch to the regular timer after the initial phase
|
||||
if timerCounter * Int(initialInterval) >= Int(initialPhaseDuration) {
|
||||
switchToRegularTimer()
|
||||
private func startTimer() {
|
||||
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
|
||||
if AppChatState.shared.value == .active {
|
||||
getSubsTotal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func switchToRegularTimer() {
|
||||
timer?.invalidate()
|
||||
timer = Timer.scheduledTimer(withTimeInterval: regularInterval, repeats: true) { _ in
|
||||
getServersSummary()
|
||||
}
|
||||
}
|
||||
|
||||
func stopTimer() {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
}
|
||||
|
||||
private func getServersSummary() {
|
||||
private func getSubsTotal() {
|
||||
do {
|
||||
let summ = try getAgentServersSummary()
|
||||
(subs, sess) = (summ.allUsersSMP.smpTotals.subs, summ.allUsersSMP.smpTotals.sessions)
|
||||
(subs, hasSess) = try getAgentSubsTotal()
|
||||
} catch let error {
|
||||
logger.error("getAgentServersSummary error: \(responseError(error))")
|
||||
logger.error("getSubsTotal error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ struct ChatPreviewView: View {
|
||||
@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
|
||||
|
||||
@@ -43,11 +45,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 +86,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 +169,47 @@ 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)
|
||||
.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(.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))
|
||||
} else {
|
||||
Color.clear.frame(width: 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +236,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 +260,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 +289,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(
|
||||
ZStack(alignment: .topTrailing) {
|
||||
Image(uiImage: UIImage(base64Encoded: preview.image) ?? UIImage(systemName: "arrow.up.right")!)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: 36, height: 36)
|
||||
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(
|
||||
CIImageView(chatItem: ci, preview: UIImage(base64Encoded: image), maxWidth: 36, smallView: true, showFullScreenImage: $showFullscreenGallery)
|
||||
.environmentObject(ReverseListScrollModel<ChatItem>())
|
||||
)
|
||||
case let .video(_,image, duration):
|
||||
smallContentPreview(
|
||||
CIVideoView(chatItem: ci, preview: UIImage(base64Encoded: image), duration: duration, maxWidth: 36, videoWidth: nil, smallView: true, showFullscreenPlayer: $showFullscreenGallery)
|
||||
.environmentObject(ReverseListScrollModel<ChatItem>())
|
||||
)
|
||||
case let .voice(_, duration):
|
||||
smallContentPreviewVoice(
|
||||
CIVoiceView(chat: chat, chatItem: ci, recordingFile: ci.file, duration: duration, allowMenu: Binding.constant(true), smallView: true)
|
||||
)
|
||||
case .file:
|
||||
smallContentPreviewFile(
|
||||
CIFileView(file: ci.file, edited: ci.meta.itemEdited, smallView: true)
|
||||
)
|
||||
default: EmptyView()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder private func groupInvitationPreviewText(_ groupInfo: GroupInfo) -> some View {
|
||||
groupInfo.membership.memberIncognito
|
||||
? chatPreviewInfoText("join as \(groupInfo.membership.memberProfile.displayName)")
|
||||
@@ -294,10 +406,50 @@ struct ChatPreviewView: View {
|
||||
}
|
||||
}
|
||||
|
||||
func smallContentPreview(_ view: some View) -> some View {
|
||||
ZStack {
|
||||
view
|
||||
.frame(width: 36, height: 36)
|
||||
}
|
||||
.cornerRadius(8)
|
||||
.overlay(RoundedRectangle(cornerSize: CGSize(width: 8, height: 8))
|
||||
.strokeBorder(.secondary, lineWidth: 0.3, antialiased: true))
|
||||
.padding([.top, .leading], 3)
|
||||
.offset(x: 6)
|
||||
}
|
||||
|
||||
func smallContentPreviewVoice(_ view: some View) -> some View {
|
||||
ZStack {
|
||||
view
|
||||
.frame(height: voiceMessageSizeBasedOnSquareSize(36))
|
||||
}
|
||||
.padding(.leading, 8)
|
||||
.padding(.top, 6)
|
||||
}
|
||||
|
||||
func smallContentPreviewFile(_ view: some View) -> some View {
|
||||
ZStack {
|
||||
view
|
||||
.frame(width: 36, height: 36)
|
||||
}
|
||||
.padding(.top, 2)
|
||||
.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 {
|
||||
|
||||
@@ -11,6 +11,7 @@ import SimpleXChat
|
||||
|
||||
struct ServersSummaryView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@State private var serversSummary: PresentedServersSummary? = nil
|
||||
@State private var selectedUserCategory: PresentedUserCategory = .allUsers
|
||||
@State private var selectedServerType: PresentedServerType = .smp
|
||||
@@ -58,11 +59,21 @@ struct ServersSummaryView: View {
|
||||
|
||||
private func startTimer() {
|
||||
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
|
||||
getServersSummary()
|
||||
if AppChatState.shared.value == .active {
|
||||
getServersSummary()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stopTimer() {
|
||||
private func getServersSummary() {
|
||||
do {
|
||||
serversSummary = try getAgentServersSummary()
|
||||
} catch let error {
|
||||
logger.error("getAgentServersSummary error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
|
||||
private func stopTimer() {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
}
|
||||
@@ -91,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)
|
||||
}
|
||||
@@ -183,19 +194,22 @@ struct ServersSummaryView: View {
|
||||
}
|
||||
} else {
|
||||
Text("No info, try to reload")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.background(theme.colors.background)
|
||||
}
|
||||
}
|
||||
|
||||
private func smpSubsSection(_ totals: SMPTotals) -> some View {
|
||||
Section {
|
||||
infoRow("Connections subscribed", numOrDash(totals.subs.ssActive))
|
||||
infoRow("Active connections", numOrDash(totals.subs.ssActive))
|
||||
infoRow("Total", numOrDash(totals.subs.total))
|
||||
Toggle("Show percentage", isOn: $showSubscriptionPercentage)
|
||||
} header: {
|
||||
HStack {
|
||||
Text("Message subscriptions")
|
||||
SubscriptionStatusIndicatorView(subs: totals.subs, sess: totals.sessions)
|
||||
Text("Message reception")
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -273,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")
|
||||
@@ -389,24 +403,16 @@ struct ServersSummaryView: View {
|
||||
Text("Reset all statistics")
|
||||
}
|
||||
}
|
||||
|
||||
private func getServersSummary() {
|
||||
do {
|
||||
serversSummary = try getAgentServersSummary()
|
||||
} catch let error {
|
||||
logger.error("getAgentServersSummary error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -420,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
|
||||
@@ -446,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
|
||||
@@ -497,16 +503,16 @@ struct SMPServerSummaryView: View {
|
||||
|
||||
private func smpSubsSection(_ subs: SMPServerSubs) -> some View {
|
||||
Section {
|
||||
infoRow("Connections subscribed", numOrDash(subs.ssActive))
|
||||
infoRow("Active connections", numOrDash(subs.ssActive))
|
||||
infoRow("Pending", numOrDash(subs.ssPending))
|
||||
infoRow("Total", numOrDash(subs.total))
|
||||
reconnectButton()
|
||||
} header: {
|
||||
HStack {
|
||||
Text("Message subscriptions")
|
||||
SubscriptionStatusIndicatorView(subs: subs, sess: summary.sessionsOrNew)
|
||||
Text("Message reception")
|
||||
SubscriptionStatusIndicatorView(subs: subs, hasSess: summary.sessionsOrNew.hasSess)
|
||||
if showSubscriptionPercentage {
|
||||
SubscriptionStatusPercentageView(subs: subs, sess: summary.sessionsOrNew)
|
||||
SubscriptionStatusPercentageView(subs: subs, hasSess: summary.sessionsOrNew.hasSess)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -611,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))
|
||||
@@ -620,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)).")
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -21,9 +21,7 @@ struct ProfileImage: View {
|
||||
@AppStorage(DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) private var radius = defaultProfileImageCorner
|
||||
|
||||
var body: some View {
|
||||
if let image = imageStr,
|
||||
let data = Data(base64Encoded: dropImagePrefix(image)),
|
||||
let uiImage = UIImage(data: data) {
|
||||
if let uiImage = UIImage(base64Encoded: imageStr) {
|
||||
clipProfileImage(Image(uiImage: uiImage), size: size, radius: radius)
|
||||
} else {
|
||||
let c = color.asAnotherColorFromSecondaryVariant(theme)
|
||||
|
||||
@@ -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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,6 +194,7 @@ struct AddGroupView: View {
|
||||
let groupMembers = await apiListMembers(gInfo.groupId)
|
||||
await MainActor.run {
|
||||
m.groupMembers = groupMembers.map { GMember.init($0) }
|
||||
m.populateGroupMembersIndexes()
|
||||
}
|
||||
}
|
||||
let c = Chat(chatInfo: .group(groupInfo: gInfo), chatItems: [])
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ struct ProtocolServerView: View {
|
||||
let serverProtocol: ServerProtocol
|
||||
@Binding var server: ServerCfg
|
||||
@State var serverToEdit: ServerCfg
|
||||
@State var serverEnabled: Bool
|
||||
@State private var showTestFailure = false
|
||||
@State private var testing = false
|
||||
@State private var testFailure: ProtocolTestFailure?
|
||||
@@ -113,10 +112,10 @@ struct ProtocolServerView: View {
|
||||
Spacer()
|
||||
showTestStatus(server: serverToEdit)
|
||||
}
|
||||
Toggle("Use for new connections", isOn: $serverEnabled)
|
||||
.onChange(of: serverEnabled) { enabled in
|
||||
serverToEdit.enabled = enabled ? .enabled : .disabled
|
||||
}
|
||||
let useForNewDisabled = serverToEdit.tested != true && !serverToEdit.preset
|
||||
Toggle("Use for new connections", isOn: $serverToEdit.enabled)
|
||||
.disabled(useForNewDisabled)
|
||||
.foregroundColor(useForNewDisabled ? theme.colors.secondary : theme.colors.onBackground)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,8 +184,7 @@ struct ProtocolServerView_Previews: PreviewProvider {
|
||||
ProtocolServerView(
|
||||
serverProtocol: .smp,
|
||||
server: Binding.constant(ServerCfg.sampleData.custom),
|
||||
serverToEdit: ServerCfg.sampleData.custom,
|
||||
serverEnabled: true
|
||||
serverToEdit: ServerCfg.sampleData.custom
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@ struct ProtocolServersView: View {
|
||||
@Environment(\.editMode) private var editMode
|
||||
let serverProtocol: ServerProtocol
|
||||
@State private var currServers: [ServerCfg] = []
|
||||
@State private var presetServers: [String] = []
|
||||
@State private var servers: [ServerCfg] = []
|
||||
@State private var presetServers: [ServerCfg] = []
|
||||
@State private var configuredServers: [ServerCfg] = []
|
||||
@State private var otherServers: [ServerCfg] = []
|
||||
@State private var selectedServer: String? = nil
|
||||
@State private var showAddServer = false
|
||||
@State private var showScanProtoServer = false
|
||||
@@ -53,31 +54,53 @@ struct ProtocolServersView: View {
|
||||
|
||||
private func protocolServersView() -> some View {
|
||||
List {
|
||||
Section {
|
||||
ForEach($servers) { srv in
|
||||
protocolServerView(srv)
|
||||
if !configuredServers.isEmpty {
|
||||
Section {
|
||||
ForEach($configuredServers) { srv in
|
||||
protocolServerView(srv)
|
||||
}
|
||||
.onMove { indexSet, offset in
|
||||
configuredServers.move(fromOffsets: indexSet, toOffset: offset)
|
||||
}
|
||||
.onDelete { indexSet in
|
||||
configuredServers.remove(atOffsets: indexSet)
|
||||
}
|
||||
} header: {
|
||||
Text("Configured \(proto) servers")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
} footer: {
|
||||
Text("The servers for new connections of your current chat profile **\(m.currentUser?.displayName ?? "")**.")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.lineLimit(10)
|
||||
}
|
||||
.onMove { indexSet, offset in
|
||||
servers.move(fromOffsets: indexSet, toOffset: offset)
|
||||
}
|
||||
|
||||
if !otherServers.isEmpty {
|
||||
Section {
|
||||
ForEach($otherServers) { srv in
|
||||
protocolServerView(srv)
|
||||
}
|
||||
.onMove { indexSet, offset in
|
||||
otherServers.move(fromOffsets: indexSet, toOffset: offset)
|
||||
}
|
||||
.onDelete { indexSet in
|
||||
otherServers.remove(atOffsets: indexSet)
|
||||
}
|
||||
} header: {
|
||||
Text("Other \(proto) servers")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
}
|
||||
.onDelete { indexSet in
|
||||
servers.remove(atOffsets: indexSet)
|
||||
}
|
||||
Button("Add server…") {
|
||||
showAddServer = true
|
||||
}
|
||||
} header: {
|
||||
Text("\(proto) servers")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
} footer: {
|
||||
Text("The servers for new connections of your current chat profile **\(m.currentUser?.displayName ?? "")**.")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.lineLimit(10)
|
||||
}
|
||||
|
||||
Section {
|
||||
Button("Reset") { servers = currServers }
|
||||
.disabled(servers == currServers || testing)
|
||||
Button("Add server") {
|
||||
showAddServer = true
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
Button("Reset") { partitionServers(currServers) }
|
||||
.disabled(Set(allServers) == Set(currServers) || testing)
|
||||
Button("Test servers", action: testServers)
|
||||
.disabled(testing || allServersDisabled)
|
||||
Button("Save servers", action: saveServers)
|
||||
@@ -86,17 +109,17 @@ struct ProtocolServersView: View {
|
||||
}
|
||||
}
|
||||
.toolbar { EditButton() }
|
||||
.confirmationDialog("Add server…", isPresented: $showAddServer, titleVisibility: .hidden) {
|
||||
.confirmationDialog("Add server", isPresented: $showAddServer, titleVisibility: .hidden) {
|
||||
Button("Enter server manually") {
|
||||
servers.append(ServerCfg.empty)
|
||||
selectedServer = servers.last?.id
|
||||
otherServers.append(ServerCfg.empty)
|
||||
selectedServer = allServers.last?.id
|
||||
}
|
||||
Button("Scan server QR code") { showScanProtoServer = true }
|
||||
Button("Add preset servers", action: addAllPresets)
|
||||
.disabled(hasAllPresets())
|
||||
}
|
||||
.sheet(isPresented: $showScanProtoServer) {
|
||||
ScanProtocolServer(servers: $servers)
|
||||
ScanProtocolServer(servers: $otherServers)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
}
|
||||
.modifier(BackButton(disabled: Binding.constant(false)) {
|
||||
@@ -133,27 +156,39 @@ struct ProtocolServersView: View {
|
||||
}
|
||||
.onAppear {
|
||||
// this condition is needed to prevent re-setting the servers when exiting single server view
|
||||
if !justOpened { return }
|
||||
do {
|
||||
let r = try getUserProtoServers(serverProtocol)
|
||||
currServers = r.protoServers
|
||||
presetServers = r.presetServers
|
||||
servers = currServers
|
||||
} catch let error {
|
||||
alert = .error(
|
||||
title: "Error loading \(proto) servers",
|
||||
error: "Error: \(responseError(error))"
|
||||
)
|
||||
if justOpened {
|
||||
do {
|
||||
let r = try getUserProtoServers(serverProtocol)
|
||||
currServers = r.protoServers
|
||||
presetServers = r.presetServers
|
||||
partitionServers(currServers)
|
||||
} catch let error {
|
||||
alert = .error(
|
||||
title: "Error loading \(proto) servers",
|
||||
error: "Error: \(responseError(error))"
|
||||
)
|
||||
}
|
||||
justOpened = false
|
||||
} else {
|
||||
partitionServers(allServers)
|
||||
}
|
||||
justOpened = false
|
||||
}
|
||||
}
|
||||
|
||||
private func partitionServers(_ servers: [ServerCfg]) {
|
||||
configuredServers = servers.filter { $0.preset || $0.enabled }
|
||||
otherServers = servers.filter { !($0.preset || $0.enabled) }
|
||||
}
|
||||
|
||||
private var allServers: [ServerCfg] {
|
||||
configuredServers + otherServers
|
||||
}
|
||||
|
||||
private var saveDisabled: Bool {
|
||||
servers.isEmpty ||
|
||||
servers == currServers ||
|
||||
allServers.isEmpty ||
|
||||
Set(allServers) == Set(currServers) ||
|
||||
testing ||
|
||||
!servers.allSatisfy { srv in
|
||||
!allServers.allSatisfy { srv in
|
||||
if let address = parseServerAddress(srv.server) {
|
||||
return uniqueAddress(srv, address)
|
||||
}
|
||||
@@ -163,7 +198,7 @@ struct ProtocolServersView: View {
|
||||
}
|
||||
|
||||
private var allServersDisabled: Bool {
|
||||
servers.allSatisfy { $0.enabled != .enabled }
|
||||
allServers.allSatisfy { !$0.enabled }
|
||||
}
|
||||
|
||||
private func protocolServerView(_ server: Binding<ServerCfg>) -> some View {
|
||||
@@ -172,8 +207,7 @@ struct ProtocolServersView: View {
|
||||
ProtocolServerView(
|
||||
serverProtocol: serverProtocol,
|
||||
server: server,
|
||||
serverToEdit: srv,
|
||||
serverEnabled: srv.enabled == .enabled
|
||||
serverToEdit: srv
|
||||
)
|
||||
.navigationBarTitle(srv.preset ? "Preset server" : "Your server")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
@@ -187,7 +221,7 @@ struct ProtocolServersView: View {
|
||||
invalidServer()
|
||||
} else if !uniqueAddress(srv, address) {
|
||||
Image(systemName: "exclamationmark.circle").foregroundColor(.red)
|
||||
} else if srv.enabled != .enabled {
|
||||
} else if !srv.enabled {
|
||||
Image(systemName: "slash.circle").foregroundColor(theme.colors.secondary)
|
||||
} else {
|
||||
showTestStatus(server: srv)
|
||||
@@ -200,7 +234,7 @@ struct ProtocolServersView: View {
|
||||
.padding(.trailing, 4)
|
||||
|
||||
let v = Text(address?.hostnames.first ?? srv.server).lineLimit(1)
|
||||
if srv.enabled == .enabled {
|
||||
if srv.enabled {
|
||||
v
|
||||
} else {
|
||||
v.foregroundColor(theme.colors.secondary)
|
||||
@@ -227,7 +261,7 @@ struct ProtocolServersView: View {
|
||||
}
|
||||
|
||||
private func uniqueAddress(_ s: ServerCfg, _ address: ServerAddress) -> Bool {
|
||||
servers.allSatisfy { srv in
|
||||
allServers.allSatisfy { srv in
|
||||
address.hostnames.allSatisfy { host in
|
||||
srv.id == s.id || !srv.server.contains(host)
|
||||
}
|
||||
@@ -241,13 +275,13 @@ struct ProtocolServersView: View {
|
||||
private func addAllPresets() {
|
||||
for srv in presetServers {
|
||||
if !hasPreset(srv) {
|
||||
servers.append(ServerCfg(server: srv, preset: true, tested: nil, enabled: .enabled))
|
||||
configuredServers.append(srv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func hasPreset(_ srv: String) -> Bool {
|
||||
servers.contains(where: { $0.server == srv })
|
||||
private func hasPreset(_ srv: ServerCfg) -> Bool {
|
||||
allServers.contains(where: { $0.server == srv.server })
|
||||
}
|
||||
|
||||
private func testServers() {
|
||||
@@ -265,19 +299,31 @@ struct ProtocolServersView: View {
|
||||
}
|
||||
|
||||
private func resetTestStatus() {
|
||||
for i in 0..<servers.count {
|
||||
if servers[i].enabled == .enabled {
|
||||
servers[i].tested = nil
|
||||
for i in 0..<configuredServers.count {
|
||||
if configuredServers[i].enabled {
|
||||
configuredServers[i].tested = nil
|
||||
}
|
||||
}
|
||||
for i in 0..<otherServers.count {
|
||||
if otherServers[i].enabled {
|
||||
otherServers[i].tested = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func runServersTest() async -> [String: ProtocolTestFailure] {
|
||||
var fs: [String: ProtocolTestFailure] = [:]
|
||||
for i in 0..<servers.count {
|
||||
if servers[i].enabled == .enabled {
|
||||
if let f = await testServerConnection(server: $servers[i]) {
|
||||
fs[serverHostname(servers[i].server)] = f
|
||||
for i in 0..<configuredServers.count {
|
||||
if configuredServers[i].enabled {
|
||||
if let f = await testServerConnection(server: $configuredServers[i]) {
|
||||
fs[serverHostname(configuredServers[i].server)] = f
|
||||
}
|
||||
}
|
||||
}
|
||||
for i in 0..<otherServers.count {
|
||||
if otherServers[i].enabled {
|
||||
if let f = await testServerConnection(server: $otherServers[i]) {
|
||||
fs[serverHostname(otherServers[i].server)] = f
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,9 +333,9 @@ struct ProtocolServersView: View {
|
||||
func saveServers() {
|
||||
Task {
|
||||
do {
|
||||
try await setUserProtoServers(serverProtocol, servers: servers)
|
||||
try await setUserProtoServers(serverProtocol, servers: allServers)
|
||||
await MainActor.run {
|
||||
currServers = servers
|
||||
currServers = allServers
|
||||
editMode?.wrappedValue = .inactive
|
||||
}
|
||||
} catch let error {
|
||||
|
||||
@@ -40,7 +40,7 @@ struct ScanProtocolServer: View {
|
||||
switch resp {
|
||||
case let .success(r):
|
||||
if parseServerAddress(r.string) != nil {
|
||||
servers.append(ServerCfg(server: r.string, preset: false, tested: nil, enabled: .enabled))
|
||||
servers.append(ServerCfg(server: r.string, preset: false, tested: nil, enabled: false))
|
||||
dismiss()
|
||||
} else {
|
||||
showAddressError = true
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -367,8 +367,8 @@
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -127,11 +127,6 @@
|
||||
<target>%@ е потвърдено</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ сървъри</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<target>%@ качено</target>
|
||||
@@ -590,6 +585,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>Добавете адрес към вашия профил, така че вашите контакти да могат да го споделят с други хора. Актуализацията на профила ще бъде изпратена до вашите контакти.</target>
|
||||
@@ -610,16 +609,16 @@
|
||||
<target>Добави профил</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Добави сървър</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>Добави сървъри чрез сканиране на QR кодове.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Добави сървър…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>Добави към друго устройство</target>
|
||||
@@ -710,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">
|
||||
@@ -1351,6 +1350,10 @@
|
||||
<target>Конфигурирай ICE сървъри</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>Потвърди</target>
|
||||
@@ -1529,10 +1532,6 @@ This is your own one-time link!</source>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>Контактът позволява</target>
|
||||
@@ -1706,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">
|
||||
@@ -3857,6 +3856,10 @@ This is your link for group %@!</source>
|
||||
<target>Член</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>Ролята на члена ще бъде променена на "%@". Всички членове на групата ще бъдат уведомени.</target>
|
||||
@@ -3895,6 +3898,14 @@ This is your link for group %@!</source>
|
||||
<target>Чернова на съобщение</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3914,6 +3925,10 @@ This is your link for group %@!</source>
|
||||
<target>Реакциите на съобщения са забранени в тази група.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3935,10 +3950,6 @@ This is your link for group %@!</source>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>Текст на съобщението</target>
|
||||
@@ -4206,6 +4217,10 @@ This is your link for group %@!</source>
|
||||
<target>Няма токен за устройство!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>Няма филтрирани чатове</target>
|
||||
@@ -4453,6 +4468,10 @@ This is your link for group %@!</source>
|
||||
<target>Други</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>PING бройка</target>
|
||||
@@ -4619,6 +4638,10 @@ Error: %@</source>
|
||||
<target>Моля, съхранявайте паролата на сигурно място, НЯМА да можете да я промените, ако я загубите.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>Полски интерфейс</target>
|
||||
@@ -4685,6 +4708,10 @@ Error: %@</source>
|
||||
<source>Private routing</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>Профилни и сървърни връзки</target>
|
||||
@@ -5585,6 +5612,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server address is incompatible with network settings.</source>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>Сървърът изисква оторизация за създаване на опашки, проверете паролата</target>
|
||||
@@ -5608,6 +5639,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>Сървъри</target>
|
||||
@@ -5744,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>
|
||||
@@ -5967,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>
|
||||
@@ -7025,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>
|
||||
@@ -7433,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>
|
||||
@@ -7762,6 +7801,10 @@ SimpleX сървърите не могат да видят вашия профи
|
||||
<target>iOS Keychain ще се използва за сигурно съхраняване на паролата, след като рестартирате приложението или промените паролата - това ще позволи получаването на push известия.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>инкогнито чрез линк с адрес за контакт</target>
|
||||
|
||||
@@ -386,8 +386,8 @@
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -126,11 +126,6 @@
|
||||
<target>%@ je ověřený</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ servery</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -572,6 +567,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>Přidejte adresu do svého profilu, aby ji vaše kontakty mohly sdílet s dalšími lidmi. Aktualizace profilu bude zaslána vašim kontaktům.</target>
|
||||
@@ -591,16 +590,16 @@
|
||||
<target>Přidat profil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Přidat server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>Přidejte servery skenováním QR kódů.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Přidat server…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>Přidat do jiného zařízení</target>
|
||||
@@ -688,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">
|
||||
@@ -1305,6 +1304,10 @@
|
||||
<target>Konfigurace serverů ICE</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>Potvrdit</target>
|
||||
@@ -1467,10 +1470,6 @@ This is your own one-time link!</source>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>Kontakt povolil</target>
|
||||
@@ -1636,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">
|
||||
@@ -3714,6 +3713,10 @@ This is your link for group %@!</source>
|
||||
<target>Člen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>Role člena se změní na "%@". Všichni členové skupiny budou upozorněni.</target>
|
||||
@@ -3752,6 +3755,14 @@ This is your link for group %@!</source>
|
||||
<target>Návrh zprávy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3771,6 +3782,10 @@ This is your link for group %@!</source>
|
||||
<target>Reakce na zprávy jsou v této skupině zakázány.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3791,10 +3806,6 @@ This is your link for group %@!</source>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>Text zprávy</target>
|
||||
@@ -4047,6 +4058,10 @@ This is your link for group %@!</source>
|
||||
<target>Žádný token zařízení!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>Žádné filtrované chaty</target>
|
||||
@@ -4283,6 +4298,10 @@ This is your link for group %@!</source>
|
||||
<source>Other</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>Počet PING</target>
|
||||
@@ -4441,6 +4460,10 @@ Error: %@</source>
|
||||
<target>Heslo uložte bezpečně, v případě jeho ztráty jej NEBUDE možné změnit.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>Polské rozhraní</target>
|
||||
@@ -4506,6 +4529,10 @@ Error: %@</source>
|
||||
<source>Private routing</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>Profil a připojení k serveru</target>
|
||||
@@ -5383,6 +5410,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server address is incompatible with network settings.</source>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>Server vyžaduje autorizaci pro vytváření front, zkontrolujte heslo</target>
|
||||
@@ -5406,6 +5437,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>Servery</target>
|
||||
@@ -5537,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>
|
||||
@@ -5754,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>
|
||||
@@ -6758,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>
|
||||
@@ -7152,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>
|
||||
@@ -7477,6 +7516,10 @@ Servery SimpleX nevidí váš profil.</target>
|
||||
<target>Klíčenka pro iOS bude použita k bezpečnému uložení přístupové fráze po restartování aplikace nebo změně přístupové fráze – umožní příjem oznámení push.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>inkognito přes odkaz na kontaktní adresu</target>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -336,8 +336,8 @@ Available in v5.1</source>
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -127,11 +127,6 @@
|
||||
<target>%@ is verified</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ servers</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<target>%@ uploaded</target>
|
||||
@@ -593,6 +588,11 @@
|
||||
<target>Acknowledgement errors</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<target>Active connections</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</target>
|
||||
@@ -613,16 +613,16 @@
|
||||
<target>Add profile</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Add server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>Add servers by scanning QR codes.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Add server…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>Add to another device</target>
|
||||
@@ -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">
|
||||
@@ -1374,6 +1374,11 @@
|
||||
<target>Configure ICE servers</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<target>Configured %@ servers</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>Confirm</target>
|
||||
@@ -1558,11 +1563,6 @@ This is your own one-time link!</target>
|
||||
<target>Connections</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<target>Connections subscribed</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>Contact allows</target>
|
||||
@@ -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">
|
||||
@@ -3923,6 +3923,11 @@ This is your link for group %@!</target>
|
||||
<target>Member</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<target>Member inactive</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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>Member role will be changed to "%@". All group members will be notified.</target>
|
||||
@@ -3963,6 +3968,16 @@ This is your link for group %@!</target>
|
||||
<target>Message draft</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<target>Message forwarded</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>Message may be delivered later if member becomes active.</target>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Message queue info</target>
|
||||
@@ -3983,6 +3998,11 @@ This is your link for group %@!</target>
|
||||
<target>Message reactions are prohibited in this group.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<target>Message reception</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<target>Message routing fallback</target>
|
||||
@@ -4008,11 +4028,6 @@ This is your link for group %@!</target>
|
||||
<target>Message status: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<target>Message subscriptions</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>Message text</target>
|
||||
@@ -4283,6 +4298,11 @@ This is your link for group %@!</target>
|
||||
<target>No device token!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>No direct connection yet, message is forwarded by admin.</target>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>No filtered chats</target>
|
||||
@@ -4532,6 +4552,11 @@ This is your link for group %@!</target>
|
||||
<target>Other</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<target>Other %@ servers</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>PING count</target>
|
||||
@@ -4701,6 +4726,11 @@ Error: %@</target>
|
||||
<target>Please store passphrase securely, you will NOT be able to change it if you lose it.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<target>Please try later.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>Polish interface</target>
|
||||
@@ -4771,6 +4801,11 @@ Error: %@</target>
|
||||
<target>Private routing</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<target>Private routing error</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>Profile and server connections</target>
|
||||
@@ -5708,6 +5743,11 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>Server address is incompatible with network settings.</target>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<target>Server address is incompatible with network settings: %@.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>Server requires authorization to create queues, check password</target>
|
||||
@@ -5733,6 +5773,16 @@ 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>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>Servers</target>
|
||||
@@ -5873,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>
|
||||
@@ -6103,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>
|
||||
@@ -7186,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">
|
||||
@@ -7595,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>
|
||||
@@ -7927,6 +7977,11 @@ SimpleX servers cannot see your profile.</target>
|
||||
<target>iOS Keychain will be used to securely store passphrase after you restart the app or change passphrase - it will allow receiving push notifications.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<target>inactive</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>incognito via contact address link</target>
|
||||
|
||||
@@ -127,11 +127,6 @@
|
||||
<target>%@ está verificado</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>Servidores %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<target>%@ subido</target>
|
||||
@@ -590,6 +585,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>Añade la dirección a tu perfil para que tus contactos puedan compartirla con otros. La actualización del perfil se enviará a tus contactos.</target>
|
||||
@@ -610,16 +609,16 @@
|
||||
<target>Añadir perfil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Añadir servidor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>Añadir servidores mediante el escaneo de códigos QR.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Añadir servidor…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>Añadir a otro dispositivo</target>
|
||||
@@ -710,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">
|
||||
@@ -1354,6 +1353,10 @@
|
||||
<target>Configure servidores ICE</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>Confirmar</target>
|
||||
@@ -1507,7 +1510,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection error (AUTH)" xml:space="preserve">
|
||||
<source>Connection error (AUTH)</source>
|
||||
<target>Error conexión (Autenticación)</target>
|
||||
<target>Error de conexión (Autenticación)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection request sent!" xml:space="preserve">
|
||||
@@ -1522,7 +1525,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection timeout" xml:space="preserve">
|
||||
<source>Connection timeout</source>
|
||||
<target>Tiempo de conexión expirado</target>
|
||||
<target>Tiempo de conexión agotado</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection with desktop stopped" xml:space="preserve">
|
||||
@@ -1533,10 +1536,6 @@ This is your own one-time link!</source>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>El contacto permite</target>
|
||||
@@ -1710,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">
|
||||
@@ -1837,6 +1836,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Informe debug</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3333,7 +3333,7 @@ Error: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
|
||||
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
|
||||
<target>Si no puedes reunirte en persona, muestra el código QR por videollamada, o comparte el enlace.</target>
|
||||
<target>Si no puedes reunirte en persona, muestra el código QR por videollamada o comparte el enlace.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="If you enter this passcode when opening the app, all app data will be irreversibly removed!" xml:space="preserve">
|
||||
@@ -3869,6 +3869,10 @@ This is your link for group %@!</source>
|
||||
<target>Miembro</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>El rol del miembro cambiará a "%@" y se notificará al grupo.</target>
|
||||
@@ -3908,8 +3912,17 @@ This is your link for group %@!</source>
|
||||
<target>Borrador de mensaje</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Información cola de mensajes</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -3927,6 +3940,10 @@ This is your link for group %@!</source>
|
||||
<target>Las reacciones a los mensajes no están permitidas en este grupo.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<target>Enrutamiento de mensajes alternativo</target>
|
||||
@@ -3950,10 +3967,6 @@ This is your link for group %@!</source>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>Contacto y texto</target>
|
||||
@@ -4222,6 +4235,10 @@ This is your link for group %@!</source>
|
||||
<target>¡Sin dispositivo token!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>Sin chats filtrados</target>
|
||||
@@ -4307,7 +4324,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>Enlace único de invitación de un uso</target>
|
||||
<target>Enlace de invitación de un solo uso</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Onion hosts will be required for connection. Requires enabling VPN." xml:space="preserve">
|
||||
@@ -4451,7 +4468,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Or scan QR code" xml:space="preserve">
|
||||
<source>Or scan QR code</source>
|
||||
<target>O escanear código QR</target>
|
||||
<target>O escanea el código QR</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Or securely share this file link" xml:space="preserve">
|
||||
@@ -4461,7 +4478,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Or show this code" xml:space="preserve">
|
||||
<source>Or show this code</source>
|
||||
<target>O mostrar este código</target>
|
||||
<target>O muestra este código QR</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other" xml:space="preserve">
|
||||
@@ -4469,6 +4486,10 @@ This is your link for group %@!</source>
|
||||
<target>Otro</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>Contador PING</target>
|
||||
@@ -4531,7 +4552,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Paste the link you received" xml:space="preserve">
|
||||
<source>Paste the link you received</source>
|
||||
<target>Pegar el enlace recibido</target>
|
||||
<target>Pega el enlace recibido</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Pending" xml:space="preserve">
|
||||
@@ -4545,7 +4566,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Periodically" xml:space="preserve">
|
||||
<source>Periodically</source>
|
||||
<target>Periódico</target>
|
||||
<target>Periódicamente</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Permanent decryption error" xml:space="preserve">
|
||||
@@ -4635,6 +4656,10 @@ Error: %@</target>
|
||||
<target>Guarda la contraseña de forma segura, NO podrás cambiarla si la pierdes.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>Interfaz en polaco</target>
|
||||
@@ -4704,6 +4729,10 @@ Error: %@</target>
|
||||
<target>Enrutamiento privado</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>Datos del perfil y conexiones</target>
|
||||
@@ -4812,12 +4841,12 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Protocol timeout" xml:space="preserve">
|
||||
<source>Protocol timeout</source>
|
||||
<target>Tiempo de espera del protocolo</target>
|
||||
<target>Timeout protocolo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Protocol timeout per KB" xml:space="preserve">
|
||||
<source>Protocol timeout per KB</source>
|
||||
<target>Límite de espera del protocolo por KB</target>
|
||||
<target>Timeout protocolo por KB</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proxied" xml:space="preserve">
|
||||
@@ -4860,32 +4889,32 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
<target>Saber más</target>
|
||||
<target>Conoce más</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address)." xml:space="preserve">
|
||||
<source>Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address).</source>
|
||||
<target>Saber más en el [Manual del Usuario](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address).</target>
|
||||
<target>Conoce más en el [Manual del Usuario](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address).</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode)." xml:space="preserve">
|
||||
<source>Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode).</source>
|
||||
<target>Saber más en [Guía de Usuario](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode).</target>
|
||||
<target>Conoce más en la [Guía del Usuario](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode).</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends)." xml:space="preserve">
|
||||
<source>Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends).</source>
|
||||
<target>Saber más en el [Manual del Usuario](https://simplex.chat/docs/guide/readme.html#connect-to-friends).</target>
|
||||
<target>Conoce más en el [Manual del Usuario](https://simplex.chat/docs/guide/readme.html#connect-to-friends).</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more in our GitHub repository." xml:space="preserve">
|
||||
<source>Read more in our GitHub repository.</source>
|
||||
<target>Saber más en nuestro repositorio GitHub.</target>
|
||||
<target>Conoce más en nuestro repositorio GitHub.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme)." xml:space="preserve">
|
||||
<source>Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme).</source>
|
||||
<target>Saber más en nuestro [repositorio GitHub](https://github.com/simplex-chat/simplex-chat#readme).</target>
|
||||
<target>Conoce más en nuestro [repositorio GitHub](https://github.com/simplex-chat/simplex-chat#readme).</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Receipts are disabled" xml:space="preserve">
|
||||
@@ -5611,6 +5640,10 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
<target>La dirección del servidor es incompatible con la configuración de la red.</target>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>El servidor requiere autorización para crear colas, comprueba la contraseña</target>
|
||||
@@ -5635,6 +5668,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>Servidores</target>
|
||||
@@ -5739,7 +5780,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<target>Compartir este enlace de un uso</target>
|
||||
<target>Comparte este enlace de un solo uso</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share with contacts" xml:space="preserve">
|
||||
@@ -5772,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>
|
||||
@@ -5996,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>
|
||||
@@ -6021,7 +6062,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="TCP connection timeout" xml:space="preserve">
|
||||
<source>TCP connection timeout</source>
|
||||
<target>Tiempo de espera de la conexión TCP agotado</target>
|
||||
<target>Timeout de la conexión TCP</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TCP_KEEPCNT" xml:space="preserve">
|
||||
@@ -6071,7 +6112,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tap to paste link" xml:space="preserve">
|
||||
<source>Tap to paste link</source>
|
||||
<target>Pulsa para pegar enlace</target>
|
||||
<target>Pulsa para pegar el enlacePulsa para pegar enlace</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tap to scan" xml:space="preserve">
|
||||
@@ -6339,7 +6380,7 @@ Puede ocurrir por algún bug o cuando la conexión está comprometida.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="To protect your IP address, private routing uses your SMP servers to deliver messages." xml:space="preserve">
|
||||
<source>To protect your IP address, private routing uses your SMP servers to deliver messages.</source>
|
||||
<target>Para proteger tu dirección IP, el enrutamiento privado usa tus servidores SMP para enviar mensajes.</target>
|
||||
<target>Para proteger tu dirección IP, el enrutamiento privado usa tu lista de servidores SMP para enviar mensajes.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To protect your information, turn on SimpleX Lock. You will be prompted to complete authentication before this feature is enabled." xml:space="preserve">
|
||||
@@ -6500,9 +6541,8 @@ Se te pedirá que completes la autenticación antes de activar esta función.</t
|
||||
<trans-unit id="Unless your contact deleted the connection or this link was already used, it might be a bug - please report it. To connect, please ask your contact to create another connection link and check that you have a stable network connection." xml:space="preserve">
|
||||
<source>Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.
|
||||
To connect, please ask your contact to create another connection link and check that you have a stable network connection.</source>
|
||||
<target>A menos que tu contacto haya eliminado la conexión o
|
||||
que este enlace ya se haya usado, podría ser un error. Por favor, notifícalo.
|
||||
Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueba que tienes buena conexión de red.</target>
|
||||
<target>A menos que tu contacto haya eliminado la conexión o el enlace haya sido usado, podría ser un error. Por favor, notifícalo.
|
||||
Para conectarte pide a tu contacto que cree otro enlace y comprueba la conexión de red.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unlink" xml:space="preserve">
|
||||
@@ -6654,12 +6694,12 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb
|
||||
</trans-unit>
|
||||
<trans-unit id="Use private routing with unknown servers when IP address is not protected." xml:space="preserve">
|
||||
<source>Use private routing with unknown servers when IP address is not protected.</source>
|
||||
<target>Usar enrutamiento privado con servidores desconocidos cuando la dirección IP no está protegida.</target>
|
||||
<target>Usar enrutamiento privado con servidores desconocidos cuando tu dirección IP no está protegida.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Use private routing with unknown servers." xml:space="preserve">
|
||||
<source>Use private routing with unknown servers.</source>
|
||||
<target>Usar enrutamiento privado con servidores desconocidos.</target>
|
||||
<target>Usar enrutamiento privado con servidores de retransmisión desconocidos.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Use server" xml:space="preserve">
|
||||
@@ -7063,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>
|
||||
@@ -7202,7 +7242,7 @@ Repeat connection request?</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="You will be required to authenticate when you start or resume the app after 30 seconds in background." xml:space="preserve">
|
||||
<source>You will be required to authenticate when you start or resume the app after 30 seconds in background.</source>
|
||||
<target>Se te pedirá identificarte cuándo inicies o continues usando la aplicación tras 30 segundos en segundo plano.</target>
|
||||
<target>Se te pedirá autenticarte cuando inicies la aplicación o sigas usándola tras 30 segundos en segundo plano.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You will connect to all group members." xml:space="preserve">
|
||||
@@ -7335,8 +7375,8 @@ Puedes cancelarla y eliminar el contacto (e intentarlo más tarde con un enlace
|
||||
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
|
||||
<source>Your profile is stored on your device and shared only with your contacts.
|
||||
SimpleX servers cannot see your profile.</source>
|
||||
<target>Tu perfil se almacena en tu dispositivo y sólo se comparte con tus contactos.
|
||||
Los servidores de SimpleX no pueden ver tu perfil.</target>
|
||||
<target>Tu perfil es almacenado en tu dispositivo y solamente se comparte con tus contactos.
|
||||
Los servidores SimpleX no pueden ver tu perfil.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
|
||||
@@ -7471,7 +7511,7 @@ Los servidores de 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>
|
||||
@@ -7800,6 +7840,10 @@ Los servidores de SimpleX no pueden ver tu perfil.</target>
|
||||
<target>iOS Keychain se usará para almacenar la contraseña de forma segura después de reiniciar la aplicación o cambiar la contraseña. Esto permitirá recibir notificaciones automáticas.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>en modo incógnito mediante enlace de dirección del contacto</target>
|
||||
@@ -8084,6 +8128,9 @@ Los servidores de SimpleX no pueden ver tu perfil.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>información cola del servidor: %1$@
|
||||
|
||||
último mensaje recibido: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
@@ -8128,7 +8175,7 @@ last received msg: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="unknown relays" xml:space="preserve">
|
||||
<source>unknown relays</source>
|
||||
<target>servidor de retransmisión desconocido</target>
|
||||
<target>con servidores desconocidos</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="unknown status" xml:space="preserve">
|
||||
@@ -8138,7 +8185,7 @@ last received msg: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="unprotected" xml:space="preserve">
|
||||
<source>unprotected</source>
|
||||
<target>desprotegido</target>
|
||||
<target>con IP desprotegida</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="updated group profile" xml:space="preserve">
|
||||
|
||||
@@ -124,11 +124,6 @@
|
||||
<target>%@ on vahvistettu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ palvelimet</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -567,6 +562,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>Lisää osoite profiiliisi, jotta kontaktisi voivat jakaa sen muiden kanssa. Profiilipäivitys lähetetään kontakteillesi.</target>
|
||||
@@ -586,16 +585,16 @@
|
||||
<target>Lisää profiili</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Lisää palvelin</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>Lisää palvelimia skannaamalla QR-koodeja.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Lisää palvelin…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>Lisää toiseen laitteeseen</target>
|
||||
@@ -683,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">
|
||||
@@ -1298,6 +1297,10 @@
|
||||
<target>Määritä ICE-palvelimet</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>Vahvista</target>
|
||||
@@ -1460,10 +1463,6 @@ This is your own one-time link!</source>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>Kontakti sallii</target>
|
||||
@@ -1629,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">
|
||||
@@ -3704,6 +3703,10 @@ This is your link for group %@!</source>
|
||||
<target>Jäsen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>Jäsenen rooli muuttuu muotoon "%@". Kaikille ryhmän jäsenille ilmoitetaan asiasta.</target>
|
||||
@@ -3742,6 +3745,14 @@ This is your link for group %@!</source>
|
||||
<target>Viestiluonnos</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3761,6 +3772,10 @@ This is your link for group %@!</source>
|
||||
<target>Viestireaktiot ovat kiellettyjä tässä ryhmässä.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3781,10 +3796,6 @@ This is your link for group %@!</source>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>Viestin teksti</target>
|
||||
@@ -4036,6 +4047,10 @@ This is your link for group %@!</source>
|
||||
<target>Ei laitetunnusta!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>Ei suodatettuja keskusteluja</target>
|
||||
@@ -4271,6 +4286,10 @@ This is your link for group %@!</source>
|
||||
<source>Other</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>PING-määrä</target>
|
||||
@@ -4429,6 +4448,10 @@ Error: %@</source>
|
||||
<target>Säilytä tunnuslause turvallisesti, ET voi muuttaa sitä, jos kadotat sen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>Puolalainen käyttöliittymä</target>
|
||||
@@ -4494,6 +4517,10 @@ Error: %@</source>
|
||||
<source>Private routing</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>Profiili- ja palvelinyhteydet</target>
|
||||
@@ -5370,6 +5397,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server address is incompatible with network settings.</source>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>Palvelin vaatii valtuutuksen jonojen luomiseen, tarkista salasana</target>
|
||||
@@ -5393,6 +5424,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>Palvelimet</target>
|
||||
@@ -5524,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>
|
||||
@@ -5740,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>
|
||||
@@ -6743,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>
|
||||
@@ -7137,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>
|
||||
@@ -7462,6 +7501,10 @@ SimpleX-palvelimet eivät näe profiiliasi.</target>
|
||||
<target>iOS-Avainnippua käytetään tunnuslauseen turvalliseen tallentamiseen sen muuttamisen tai sovelluksen uudelleen käynnistämisen jälkeen - se mahdollistaa push-ilmoitusten vastaanottamisen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>incognito kontaktilinkin kautta</target>
|
||||
|
||||
@@ -127,11 +127,6 @@
|
||||
<target>%@ est vérifié·e</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>Serveurs %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<target>%@ envoyé</target>
|
||||
@@ -590,6 +585,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>Ajoutez une adresse à votre profil, afin que vos contacts puissent la partager avec d'autres personnes. La mise à jour du profil sera envoyée à vos contacts.</target>
|
||||
@@ -610,16 +609,16 @@
|
||||
<target>Ajouter un profil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Ajouter un serveur</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>Ajoutez des serveurs en scannant des codes QR.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Ajouter un serveur…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>Ajouter à un autre appareil</target>
|
||||
@@ -710,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">
|
||||
@@ -1354,6 +1353,10 @@
|
||||
<target>Configurer les serveurs ICE</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>Confirmer</target>
|
||||
@@ -1533,10 +1536,6 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>Votre contact autorise</target>
|
||||
@@ -1710,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">
|
||||
@@ -1837,6 +1836,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Livraison de débogage</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3869,6 +3869,10 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>Membre</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>Le rôle du membre sera changé pour "%@". Tous les membres du groupe en seront informés.</target>
|
||||
@@ -3908,8 +3912,17 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>Brouillon de message</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Informations sur la file d'attente des messages</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -3927,6 +3940,10 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>Les réactions aux messages sont interdites dans ce groupe.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<target>Rabattement du routage des messages</target>
|
||||
@@ -3950,10 +3967,6 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>Texte du message</target>
|
||||
@@ -4222,6 +4235,10 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>Pas de token d'appareil !</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>Aucune discussion filtrés</target>
|
||||
@@ -4469,6 +4486,10 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>Autres</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>Nombre de PING</target>
|
||||
@@ -4635,6 +4656,10 @@ Erreur : %@</target>
|
||||
<target>Veuillez conserver votre phrase secrète en lieu sûr, vous NE pourrez PAS la changer si vous la perdez.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>Interface en polonais</target>
|
||||
@@ -4704,6 +4729,10 @@ Erreur : %@</target>
|
||||
<target>Routage privé</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>Profil et connexions au serveur</target>
|
||||
@@ -5611,6 +5640,10 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>L'adresse du serveur est incompatible avec les paramètres du réseau.</target>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>Le serveur requiert une autorisation pour créer des files d'attente, vérifiez le mot de passe</target>
|
||||
@@ -5635,6 +5668,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>Serveurs</target>
|
||||
@@ -5772,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>
|
||||
@@ -5996,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>
|
||||
@@ -7062,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>
|
||||
@@ -7470,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>
|
||||
@@ -7799,6 +7840,10 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
|
||||
<target>La keychain d'iOS sera utilisée pour stocker en toute sécurité la phrase secrète après le redémarrage de l'app ou la modification de la phrase secrète - il permettra de recevoir les notifications push.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>mode incognito via le lien d'adresse du contact</target>
|
||||
@@ -8083,6 +8128,9 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>info sur la file d'attente du serveur : %1$@
|
||||
|
||||
dernier message reçu : %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -403,9 +403,9 @@ Available in v5.1</source>
|
||||
<target state="translated">הוספת שרתים על ידי סריקת קוד QR.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve" approved="no">
|
||||
<source>Add server…</source>
|
||||
<target state="translated">הוסף שרת…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve" approved="no">
|
||||
<source>Add server</source>
|
||||
<target state="translated">הוסף שרת</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve" approved="no">
|
||||
|
||||
@@ -300,8 +300,8 @@
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -367,8 +367,8 @@
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -127,11 +127,6 @@
|
||||
<target>%@ は検証されています</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ サーバー</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<target>%@ アップロード済</target>
|
||||
@@ -584,6 +579,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>プロフィールにアドレスを追加し、連絡先があなたのアドレスを他の人と共有できるようにします。プロフィールの更新は連絡先に送信されます。</target>
|
||||
@@ -603,16 +602,16 @@
|
||||
<target>プロフィールを追加</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>サーバを追加</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>QRコードでサーバを追加する。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>サーバを追加…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>別の端末に追加</target>
|
||||
@@ -700,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">
|
||||
@@ -1322,6 +1321,10 @@
|
||||
<target>ICEサーバを設定</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>確認</target>
|
||||
@@ -1484,10 +1487,6 @@ This is your own one-time link!</source>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>連絡先の許可</target>
|
||||
@@ -1653,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">
|
||||
@@ -3729,6 +3728,10 @@ This is your link for group %@!</source>
|
||||
<target>メンバー</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>メンバーの役割が "%@" に変更されます。 グループメンバー全員に通知されます。</target>
|
||||
@@ -3766,6 +3769,14 @@ This is your link for group %@!</source>
|
||||
<target>メッセージの下書き</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3785,6 +3796,10 @@ This is your link for group %@!</source>
|
||||
<target>このグループではメッセージへのリアクションは禁止されています。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3805,10 +3820,6 @@ This is your link for group %@!</source>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>メッセージ内容</target>
|
||||
@@ -4061,6 +4072,10 @@ This is your link for group %@!</source>
|
||||
<target>デバイストークンがありません!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>フィルタされたチャットはありません</target>
|
||||
@@ -4297,6 +4312,10 @@ This is your link for group %@!</source>
|
||||
<source>Other</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>PING回数</target>
|
||||
@@ -4455,6 +4474,10 @@ Error: %@</source>
|
||||
<target>パスフレーズを失くさないように保管してください。失くすと変更できなくなります。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>ポーランド語UI</target>
|
||||
@@ -4520,6 +4543,10 @@ Error: %@</source>
|
||||
<source>Private routing</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>プロフィールとサーバ接続</target>
|
||||
@@ -5388,6 +5415,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server address is incompatible with network settings.</source>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>キューを作成するにはサーバーの認証が必要です。パスワードを確認してください</target>
|
||||
@@ -5411,6 +5442,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>サーバ</target>
|
||||
@@ -5542,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>
|
||||
@@ -5759,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>
|
||||
@@ -6761,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>
|
||||
@@ -7155,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>
|
||||
@@ -7480,6 +7519,10 @@ SimpleX サーバーはあなたのプロファイルを参照できません。
|
||||
<target>iOS キーチェーンは、アプリを再起動するかパスフレーズを変更した後にパスフレーズを安全に保存するために使用され、プッシュ通知を受信できるようになります。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>連絡先リンク経由でシークレットモード</target>
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
<tool tool-id="com.apple.dt.xcode" tool-name="Xcode" tool-version="14.2" build-num="14C18"/>
|
||||
</header>
|
||||
<body>
|
||||
<trans-unit id=" " xml:space="preserve">
|
||||
<trans-unit id=" " xml:space="preserve" approved="no">
|
||||
<source>
|
||||
</source>
|
||||
<target state="translated">
|
||||
</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id=" " xml:space="preserve">
|
||||
@@ -300,8 +302,8 @@
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -484,53 +486,62 @@
|
||||
<source>Can't delete user profile!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't invite contact!" xml:space="preserve">
|
||||
<trans-unit id="Can't invite contact!" xml:space="preserve" approved="no">
|
||||
<source>Can't invite contact!</source>
|
||||
<target state="translated">주소를 초대할 수 없습니다.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't invite contacts!" xml:space="preserve">
|
||||
<source>Can't invite contacts!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cancel" xml:space="preserve">
|
||||
<trans-unit id="Cancel" xml:space="preserve" approved="no">
|
||||
<source>Cancel</source>
|
||||
<target state="translated">취소</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cannot access keychain to save database password" xml:space="preserve">
|
||||
<trans-unit id="Cannot access keychain to save database password" xml:space="preserve" approved="no">
|
||||
<source>Cannot access keychain to save database password</source>
|
||||
<target state="translated">데이터베이스 암호를 저장하는 키체인에 접근 할 수 없습니다</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cannot receive file" xml:space="preserve">
|
||||
<trans-unit id="Cannot receive file" xml:space="preserve" approved="no">
|
||||
<source>Cannot receive file</source>
|
||||
<target state="translated">파일을 받을 수 없습니다</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Change" xml:space="preserve">
|
||||
<trans-unit id="Change" xml:space="preserve" approved="no">
|
||||
<source>Change</source>
|
||||
<target state="translated">변경</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Change database passphrase?" xml:space="preserve">
|
||||
<source>Change database passphrase?</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Change member role?" xml:space="preserve">
|
||||
<trans-unit id="Change member role?" xml:space="preserve" approved="no">
|
||||
<source>Change member role?</source>
|
||||
<target state="translated">멤버 역할을 변경하시겠습니까?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Change receiving address" xml:space="preserve">
|
||||
<trans-unit id="Change receiving address" xml:space="preserve" approved="no">
|
||||
<source>Change receiving address</source>
|
||||
<target state="translated">수신 주소 변경</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Change receiving address?" xml:space="preserve" approved="no">
|
||||
<source>Change receiving address?</source>
|
||||
<target state="translated">修改接收地址?</target>
|
||||
<target state="translated">수신 주소를 변경하시겠습니까?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Change role" xml:space="preserve">
|
||||
<trans-unit id="Change role" xml:space="preserve" approved="no">
|
||||
<source>Change role</source>
|
||||
<target state="translated">역할 변경</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat archive" xml:space="preserve">
|
||||
<trans-unit id="Chat archive" xml:space="preserve" approved="no">
|
||||
<source>Chat archive</source>
|
||||
<target state="translated">채팅 기록 보관함</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat console" xml:space="preserve">
|
||||
@@ -545,8 +556,9 @@
|
||||
<source>Chat database deleted</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat database imported" xml:space="preserve">
|
||||
<trans-unit id="Chat database imported" xml:space="preserve" approved="no">
|
||||
<source>Chat database imported</source>
|
||||
<target state="translated">채팅 데이터베이스를 가져옴</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat is running" xml:space="preserve">
|
||||
@@ -2397,24 +2409,29 @@ We will be adding server redundancy to prevent lost messages.</source>
|
||||
<source>Send live message</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send notifications" xml:space="preserve">
|
||||
<trans-unit id="Send notifications" xml:space="preserve" approved="no">
|
||||
<source>Send notifications</source>
|
||||
<target state="translated">알림 전송</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send notifications:" xml:space="preserve">
|
||||
<trans-unit id="Send notifications:" xml:space="preserve" approved="no">
|
||||
<source>Send notifications:</source>
|
||||
<target state="translated">알림 전송:</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send questions and ideas" xml:space="preserve">
|
||||
<trans-unit id="Send questions and ideas" xml:space="preserve" approved="no">
|
||||
<source>Send questions and ideas</source>
|
||||
<target state="translated">질문이나 아이디어 보내기</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send them from gallery or custom keyboards." xml:space="preserve">
|
||||
<trans-unit id="Send them from gallery or custom keyboards." xml:space="preserve" approved="no">
|
||||
<source>Send them from gallery or custom keyboards.</source>
|
||||
<target state="needs-translation">갤러리 또는 사용자 정의 키보드에서 그들을 보내십시오.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
|
||||
<trans-unit id="Sender cancelled file transfer." xml:space="preserve" approved="no">
|
||||
<source>Sender cancelled file transfer.</source>
|
||||
<target state="translated">상대방이 파일 전송을 취소했습니다.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
|
||||
@@ -3755,6 +3772,26 @@ SimpleX servers cannot see your profile.</source>
|
||||
<source>\~strike~</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Change passcode" xml:space="preserve" approved="no">
|
||||
<source>Change passcode</source>
|
||||
<target state="translated">패스코드 변경</target>
|
||||
<note>authentication reason</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cellular" xml:space="preserve" approved="no">
|
||||
<source>Cellular</source>
|
||||
<target state="translated">셀룰러</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send messages directly when your or destination server does not support private routing." xml:space="preserve" approved="no">
|
||||
<source>Send messages directly when your or destination server does not support private routing.</source>
|
||||
<target state="needs-translation">이 서버 또는 도착 서버가 비밀 라우팅을 지원하지 않을 때 직통 메시지 보내기.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send up to 100 last messages to new members." xml:space="preserve" approved="no">
|
||||
<source>Send up to 100 last messages to new members.</source>
|
||||
<target state="translated">새로운 멤버에게 최대 100개의 마지막 메시지 보내기.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
<file original="en.lproj/SimpleX--iOS--InfoPlist.strings" source-language="en" target-language="ko" datatype="plaintext">
|
||||
@@ -3778,8 +3815,9 @@ SimpleX servers cannot see your profile.</source>
|
||||
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
|
||||
<note>Privacy - Microphone Usage Description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="NSPhotoLibraryAddUsageDescription" xml:space="preserve">
|
||||
<trans-unit id="NSPhotoLibraryAddUsageDescription" xml:space="preserve" approved="no">
|
||||
<source>SimpleX needs access to Photo Library for saving captured and received media</source>
|
||||
<target state="needs-translation">SimpleX는 캡처 및 수신 된 미디어를 저장하기 위해 사진 라이브러리에 접근이 필요합니다</target>
|
||||
<note>Privacy - Photo Library Additions Usage Description</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
@@ -3793,8 +3831,9 @@ SimpleX servers cannot see your profile.</source>
|
||||
<source>SimpleX NSE</source>
|
||||
<note>Bundle display name</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="CFBundleName" xml:space="preserve">
|
||||
<trans-unit id="CFBundleName" xml:space="preserve" approved="no">
|
||||
<source>SimpleX NSE</source>
|
||||
<target state="translated">SimpleX NSE</target>
|
||||
<note>Bundle name</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="NSHumanReadableCopyright" xml:space="preserve">
|
||||
|
||||
@@ -329,9 +329,9 @@
|
||||
<target state="translated">Pridėti serverius skenuojant QR kodus.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve" approved="no">
|
||||
<source>Add server…</source>
|
||||
<target state="translated">Pridėti serverį…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve" approved="no">
|
||||
<source>Add server</source>
|
||||
<target state="translated">Pridėti serverį</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -367,8 +367,8 @@
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -127,11 +127,6 @@
|
||||
<target>%@ is geverifieerd</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ servers</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<target>%@ geüpload</target>
|
||||
@@ -590,6 +585,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>Voeg een adres toe aan uw profiel, zodat uw contacten het met andere mensen kunnen delen. Profiel update wordt naar uw contacten verzonden.</target>
|
||||
@@ -610,16 +609,16 @@
|
||||
<target>Profiel toevoegen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Server toevoegen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>Servers toevoegen door QR-codes te scannen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Server toevoegen…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>Toevoegen aan een ander apparaat</target>
|
||||
@@ -710,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">
|
||||
@@ -1354,6 +1353,10 @@
|
||||
<target>ICE servers configureren</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>Bevestigen</target>
|
||||
@@ -1533,10 +1536,6 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>Contact maakt het mogelijk</target>
|
||||
@@ -1710,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">
|
||||
@@ -1837,6 +1836,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Foutopsporing bezorging</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3869,6 +3869,10 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Lid</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>De rol van lid wordt gewijzigd in "%@". Alle groepsleden worden op de hoogte gebracht.</target>
|
||||
@@ -3908,8 +3912,17 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Concept bericht</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Informatie over berichtenwachtrij</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -3927,6 +3940,10 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Reacties op berichten zijn verboden in deze groep.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<target>Terugval op berichtroutering</target>
|
||||
@@ -3950,10 +3967,6 @@ Dit is jouw link voor groep %@!</target>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>Bericht tekst</target>
|
||||
@@ -4222,6 +4235,10 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Geen apparaattoken!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>Geen gefilterde gesprekken</target>
|
||||
@@ -4469,6 +4486,10 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Ander</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>PING count</target>
|
||||
@@ -4635,6 +4656,10 @@ Fout: %@</target>
|
||||
<target>Bewaar het wachtwoord veilig, u kunt deze NIET wijzigen als u het kwijtraakt.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>Poolse interface</target>
|
||||
@@ -4704,6 +4729,10 @@ Fout: %@</target>
|
||||
<target>Privéroutering</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>Profiel- en serververbindingen</target>
|
||||
@@ -5611,6 +5640,10 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<target>Serveradres is niet compatibel met netwerkinstellingen.</target>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>Server vereist autorisatie om wachtrijen te maken, controleer wachtwoord</target>
|
||||
@@ -5635,6 +5668,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>Servers</target>
|
||||
@@ -5772,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>
|
||||
@@ -5996,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>
|
||||
@@ -7062,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>
|
||||
@@ -7470,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>
|
||||
@@ -7799,6 +7840,10 @@ SimpleX servers kunnen uw profiel niet zien.</target>
|
||||
<target>iOS-keychain wordt gebruikt om het wachtwoord veilig op te slaan nadat u de app opnieuw hebt opgestart of het wachtwoord hebt gewijzigd, hiermee kunt u push meldingen ontvangen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>incognito via contact adres link</target>
|
||||
@@ -8083,6 +8128,9 @@ SimpleX servers kunnen uw profiel niet zien.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>informatie over serverwachtrij: %1$@
|
||||
|
||||
laatst ontvangen bericht: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -127,11 +127,6 @@
|
||||
<target>%@ jest zweryfikowany</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ serwery</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<target>%@ wgrane</target>
|
||||
@@ -590,6 +585,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>Dodaj adres do swojego profilu, aby Twoje kontakty mogły go udostępnić innym osobom. Aktualizacja profilu zostanie wysłana do Twoich kontaktów.</target>
|
||||
@@ -610,16 +609,16 @@
|
||||
<target>Dodaj profil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Dodaj serwer</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>Dodaj serwery, skanując kody QR.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Dodaj serwer…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>Dodaj do innego urządzenia</target>
|
||||
@@ -710,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">
|
||||
@@ -1354,6 +1353,10 @@
|
||||
<target>Skonfiguruj serwery ICE</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>Potwierdź</target>
|
||||
@@ -1533,10 +1536,6 @@ To jest twój jednorazowy link!</target>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>Kontakt pozwala</target>
|
||||
@@ -1710,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">
|
||||
@@ -1837,6 +1836,7 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Dostarczenie debugowania</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3869,6 +3869,10 @@ To jest twój link do grupy %@!</target>
|
||||
<target>Członek</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>Rola członka grupy zostanie zmieniona na "%@". Wszyscy członkowie grupy zostaną powiadomieni.</target>
|
||||
@@ -3908,8 +3912,17 @@ To jest twój link do grupy %@!</target>
|
||||
<target>Wersja robocza wiadomości</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Informacje kolejki wiadomości</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -3927,6 +3940,10 @@ To jest twój link do grupy %@!</target>
|
||||
<target>Reakcje wiadomości są zabronione w tej grupie.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<target>Rezerwowe trasowania wiadomości</target>
|
||||
@@ -3950,10 +3967,6 @@ To jest twój link do grupy %@!</target>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>Tekst wiadomości</target>
|
||||
@@ -4222,6 +4235,10 @@ To jest twój link do grupy %@!</target>
|
||||
<target>Brak tokenu urządzenia!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>Brak filtrowanych czatów</target>
|
||||
@@ -4469,6 +4486,10 @@ To jest twój link do grupy %@!</target>
|
||||
<target>Inne</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>Liczba PINGÓW</target>
|
||||
@@ -4635,6 +4656,10 @@ Błąd: %@</target>
|
||||
<target>Przechowuj kod dostępu w bezpieczny sposób, w przypadku jego utraty NIE będzie można go zmienić.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>Polski interfejs</target>
|
||||
@@ -4704,6 +4729,10 @@ Błąd: %@</target>
|
||||
<target>Prywatne trasowanie</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>Profil i połączenia z serwerem</target>
|
||||
@@ -5611,6 +5640,10 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
<target>Adres serwera jest niekompatybilny z ustawieniami sieciowymi.</target>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>Serwer wymaga autoryzacji do tworzenia kolejek, sprawdź hasło</target>
|
||||
@@ -5635,6 +5668,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>Serwery</target>
|
||||
@@ -5772,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>
|
||||
@@ -5996,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>
|
||||
@@ -7062,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>
|
||||
@@ -7470,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>
|
||||
@@ -7799,6 +7840,10 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
|
||||
<target>iOS Keychain będzie używany do bezpiecznego przechowywania hasła po ponownym uruchomieniu aplikacji lub zmianie hasła - pozwoli to na otrzymywanie powiadomień push.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>incognito poprzez link adresu kontaktowego</target>
|
||||
@@ -8083,6 +8128,9 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>Informacje kolejki serwera: %1$@
|
||||
|
||||
ostatnia otrzymana wiadomość: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -374,9 +374,9 @@
|
||||
<target state="translated">Adicione servidores escaneando o QR code.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve" approved="no">
|
||||
<source>Add server…</source>
|
||||
<target state="translated">Adicionar servidor…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve" approved="no">
|
||||
<source>Add server</source>
|
||||
<target state="translated">Adicionar servidor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve" approved="no">
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
<tool tool-id="com.apple.dt.xcode" tool-name="Xcode" tool-version="14.2" build-num="14C18"/>
|
||||
</header>
|
||||
<body>
|
||||
<trans-unit id=" " xml:space="preserve">
|
||||
<trans-unit id=" " xml:space="preserve" approved="no">
|
||||
<source>
|
||||
</source>
|
||||
<target state="needs-translation">
|
||||
</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id=" Available in v5.1" xml:space="preserve">
|
||||
@@ -50,16 +52,19 @@ Available in v5.1</source>
|
||||
<target state="translated">#secreto#</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@" xml:space="preserve">
|
||||
<trans-unit id="%@" xml:space="preserve" approved="no">
|
||||
<source>%@</source>
|
||||
<target state="needs-translation">%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ %@" xml:space="preserve">
|
||||
<trans-unit id="%@ %@" xml:space="preserve" approved="no">
|
||||
<source>%@ %@</source>
|
||||
<target state="needs-translation">%@ %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ / %@" xml:space="preserve">
|
||||
<trans-unit id="%@ / %@" xml:space="preserve" approved="no">
|
||||
<source>%@ / %@</source>
|
||||
<target state="needs-translation">%@ / %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ is connected!" xml:space="preserve" approved="no">
|
||||
@@ -117,12 +122,14 @@ Available in v5.1</source>
|
||||
<target state="translated">%d mensagem(s) ignorada(s)</target>
|
||||
<note>integrity error chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld" xml:space="preserve">
|
||||
<trans-unit id="%lld" xml:space="preserve" approved="no">
|
||||
<source>%lld</source>
|
||||
<target state="needs-translation">%lld</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld %@" xml:space="preserve">
|
||||
<trans-unit id="%lld %@" xml:space="preserve" approved="no">
|
||||
<source>%lld %@</source>
|
||||
<target state="needs-translation">%lld %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld contact(s) selected" xml:space="preserve" approved="no">
|
||||
@@ -155,24 +162,29 @@ Available in v5.1</source>
|
||||
<target state="translated">%lld segundos</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lldd" xml:space="preserve">
|
||||
<trans-unit id="%lldd" xml:space="preserve" approved="no">
|
||||
<source>%lldd</source>
|
||||
<target state="needs-translation">%lldd</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lldh" xml:space="preserve">
|
||||
<trans-unit id="%lldh" xml:space="preserve" approved="no">
|
||||
<source>%lldh</source>
|
||||
<target state="needs-translation">%lldh</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lldk" xml:space="preserve">
|
||||
<trans-unit id="%lldk" xml:space="preserve" approved="no">
|
||||
<source>%lldk</source>
|
||||
<target state="needs-translation">%lldk</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lldm" xml:space="preserve">
|
||||
<trans-unit id="%lldm" xml:space="preserve" approved="no">
|
||||
<source>%lldm</source>
|
||||
<target state="needs-translation">%lldm</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lldmth" xml:space="preserve">
|
||||
<trans-unit id="%lldmth" xml:space="preserve" approved="no">
|
||||
<source>%lldmth</source>
|
||||
<target state="needs-translation">%lldmth</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%llds" xml:space="preserve">
|
||||
@@ -193,8 +205,9 @@ Available in v5.1</source>
|
||||
<target state="translated">%u mensagens ignoradas.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="(" xml:space="preserve">
|
||||
<trans-unit id="(" xml:space="preserve" approved="no">
|
||||
<source>(</source>
|
||||
<target state="needs-translation">(</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id=")" xml:space="preserve">
|
||||
@@ -359,8 +372,8 @@ Available in v5.1</source>
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -4540,6 +4553,31 @@ SimpleX servers cannot see your profile.</source>
|
||||
<target state="translated">Confirmar envio</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ downloaded" xml:space="preserve" approved="no">
|
||||
<source>%@ downloaded</source>
|
||||
<target state="translated">%@ baixado</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="# %@" xml:space="preserve" approved="no">
|
||||
<source># %@</source>
|
||||
<target state="needs-translation"># %@</target>
|
||||
<note>copied message info title, # <title></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@:" xml:space="preserve" approved="no">
|
||||
<source>%@:</source>
|
||||
<target state="needs-translation">%@:</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ (current)" xml:space="preserve" approved="no">
|
||||
<source>%@ (current)</source>
|
||||
<target state="translated">%@(atual)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ (current):" xml:space="preserve" approved="no">
|
||||
<source>%@ (current):</source>
|
||||
<target state="translated">%@ (atual):</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
<file original="en.lproj/SimpleX--iOS--InfoPlist.strings" source-language="en" target-language="pt" datatype="plaintext">
|
||||
|
||||
@@ -127,11 +127,6 @@
|
||||
<target>%@ подтверждён</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ серверы</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<target>%@ загружено</target>
|
||||
@@ -590,6 +585,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>Добавьте адрес в свой профиль, чтобы Ваши контакты могли поделиться им. Профиль будет отправлен Вашим контактам.</target>
|
||||
@@ -610,16 +609,16 @@
|
||||
<target>Добавить профиль</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Добавить сервер</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>Добавить серверы через QR код.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Добавить сервер…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>Добавить на другое устройство</target>
|
||||
@@ -710,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">
|
||||
@@ -1354,6 +1353,10 @@
|
||||
<target>Настройка ICE серверов</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>Подтвердить</target>
|
||||
@@ -1533,10 +1536,6 @@ This is your own one-time link!</source>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>Контакт разрешает</target>
|
||||
@@ -1710,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">
|
||||
@@ -3869,6 +3868,10 @@ This is your link for group %@!</source>
|
||||
<target>Член группы</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>Роль члена группы будет изменена на "%@". Все члены группы получат сообщение.</target>
|
||||
@@ -3908,6 +3911,14 @@ This is your link for group %@!</source>
|
||||
<target>Черновик сообщения</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3927,6 +3938,10 @@ This is your link for group %@!</source>
|
||||
<target>Реакции на сообщения запрещены в этой группе.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<target>Прямая доставка сообщений</target>
|
||||
@@ -3950,10 +3965,6 @@ This is your link for group %@!</source>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>Текст сообщения</target>
|
||||
@@ -4222,6 +4233,10 @@ This is your link for group %@!</source>
|
||||
<target>Отсутствует токен устройства!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>Нет отфильтрованных разговоров</target>
|
||||
@@ -4469,6 +4484,10 @@ This is your link for group %@!</source>
|
||||
<target>Другaя сеть</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>Количество PING</target>
|
||||
@@ -4635,6 +4654,10 @@ Error: %@</source>
|
||||
<target>Пожалуйста, надежно сохраните пароль, Вы НЕ сможете его поменять, если потеряете.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>Польский интерфейс</target>
|
||||
@@ -4704,6 +4727,10 @@ Error: %@</source>
|
||||
<target>Конфиденциальная доставка</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>Профиль и соединения на сервере</target>
|
||||
@@ -5611,6 +5638,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Адрес сервера несовместим с настройками сети.</target>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>Сервер требует авторизации для создания очередей, проверьте пароль</target>
|
||||
@@ -5635,6 +5666,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>Серверы</target>
|
||||
@@ -5772,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>
|
||||
@@ -5996,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>
|
||||
@@ -7062,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">
|
||||
@@ -7470,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>
|
||||
@@ -7799,6 +7838,10 @@ SimpleX серверы не могут получить доступ к Ваше
|
||||
<target>Пароль базы данных будет безопасно сохранен в iOS Keychain после запуска чата или изменения пароля - это позволит получать мгновенные уведомления.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>инкогнито через ссылку-контакт</target>
|
||||
|
||||
@@ -120,11 +120,6 @@
|
||||
<target>%@ ได้รับการตรวจสอบแล้ว</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ เซิร์ฟเวอร์</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -559,6 +554,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>เพิ่มที่อยู่ลงในโปรไฟล์ของคุณ เพื่อให้ผู้ติดต่อของคุณสามารถแชร์กับผู้อื่นได้ การอัปเดตโปรไฟล์จะถูกส่งไปยังผู้ติดต่อของคุณ</target>
|
||||
@@ -578,16 +577,16 @@
|
||||
<target>เพิ่มโปรไฟล์</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>เพิ่มเซิร์ฟเวอร์</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>เพิ่มเซิร์ฟเวอร์โดยการสแกนรหัสคิวอาร์โค้ด</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>เพิ่มเซิร์ฟเวอร์…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>เพิ่มเข้าไปในอุปกรณ์อื่น</target>
|
||||
@@ -675,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">
|
||||
@@ -1290,6 +1289,10 @@
|
||||
<target>กำหนดค่าเซิร์ฟเวอร์ ICE</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>ยืนยัน</target>
|
||||
@@ -1450,10 +1453,6 @@ This is your own one-time link!</source>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>ผู้ติดต่ออนุญาต</target>
|
||||
@@ -1618,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">
|
||||
@@ -3687,6 +3686,10 @@ This is your link for group %@!</source>
|
||||
<target>สมาชิก</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>บทบาทของสมาชิกจะถูกเปลี่ยนเป็น "%@" สมาชิกกลุ่มทั้งหมดจะได้รับแจ้ง</target>
|
||||
@@ -3725,6 +3728,14 @@ This is your link for group %@!</source>
|
||||
<target>ร่างข้อความ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3744,6 +3755,10 @@ This is your link for group %@!</source>
|
||||
<target>ปฏิกิริยาบนข้อความเป็นสิ่งต้องห้ามในกลุ่มนี้</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3764,10 +3779,6 @@ This is your link for group %@!</source>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>ข้อความ</target>
|
||||
@@ -4017,6 +4028,10 @@ This is your link for group %@!</source>
|
||||
<target>ไม่มีโทเค็นอุปกรณ์!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>ไม่มีการกรองการแชท</target>
|
||||
@@ -4252,6 +4267,10 @@ This is your link for group %@!</source>
|
||||
<source>Other</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>จํานวน PING</target>
|
||||
@@ -4410,6 +4429,10 @@ Error: %@</source>
|
||||
<target>โปรดจัดเก็บรหัสผ่านอย่างปลอดภัย คุณจะไม่สามารถเปลี่ยนรหัสผ่านได้หากคุณทำรหัสผ่านหาย</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>อินเตอร์เฟซภาษาโปแลนด์</target>
|
||||
@@ -4475,6 +4498,10 @@ Error: %@</source>
|
||||
<source>Private routing</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>การเชื่อมต่อโปรไฟล์และเซิร์ฟเวอร์</target>
|
||||
@@ -5347,6 +5374,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server address is incompatible with network settings.</source>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>เซิร์ฟเวอร์ต้องการการอนุญาตในการสร้างคิว โปรดตรวจสอบรหัสผ่าน</target>
|
||||
@@ -5370,6 +5401,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>เซิร์ฟเวอร์</target>
|
||||
@@ -5500,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>
|
||||
@@ -5715,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>
|
||||
@@ -6715,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>
|
||||
@@ -7107,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>
|
||||
@@ -7430,6 +7469,10 @@ SimpleX servers cannot see your profile.</source>
|
||||
<target>iOS Keychain จะใช้เพื่อจัดเก็บรหัสผ่านอย่างปลอดภัยหลังจากที่คุณรีสตาร์ทแอปหรือเปลี่ยนรหัสผ่าน ซึ่งจะช่วยให้รับการแจ้งเตือนแบบทันทีได้</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>ไม่ระบุตัวตนผ่านลิงค์ที่อยู่ติดต่อ</target>
|
||||
|
||||
@@ -127,11 +127,6 @@
|
||||
<target>%@ onaylandı</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ sunucuları</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<target>%@ yüklendi</target>
|
||||
@@ -590,6 +585,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>Kişilerinizin başkalarıyla paylaşabilmesi için profilinize adres ekleyin. Profil güncellemesi kişilerinize gönderilecek.</target>
|
||||
@@ -610,16 +609,16 @@
|
||||
<target>Profil ekle</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Sunucu ekle</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>Karekod taratarak sunucuları ekleyin.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Sunucu ekle…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>Başka bir cihaza ekle</target>
|
||||
@@ -710,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">
|
||||
@@ -1354,6 +1353,10 @@
|
||||
<target>ICE sunucularını ayarla</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>Onayla</target>
|
||||
@@ -1533,10 +1536,6 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>Kişi izin veriyor</target>
|
||||
@@ -1710,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">
|
||||
@@ -1837,6 +1836,7 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Hata ayıklama teslimatı</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3869,6 +3869,10 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<target>Kişi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>Üye rolü "%@" olarak değiştirilecektir. Ve tüm grup üyeleri bilgilendirilecektir.</target>
|
||||
@@ -3908,8 +3912,17 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<target>Mesaj taslağı</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Mesaj kuyruğu bilgisi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -3927,6 +3940,10 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<target>Mesaj tepkileri bu grupta yasaklandı.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<target>Mesaj yönlendirme yedeklemesi</target>
|
||||
@@ -3950,10 +3967,6 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>Mesaj yazısı</target>
|
||||
@@ -4222,6 +4235,10 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<target>Cihaz tokeni yok!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>Filtrelenmiş sohbetler yok</target>
|
||||
@@ -4469,6 +4486,10 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<target>Diğer</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>PING sayısı</target>
|
||||
@@ -4635,6 +4656,10 @@ Hata: %@</target>
|
||||
<target>Lütfen parolayı güvenli bir şekilde saklayın, kaybederseniz parolayı DEĞİŞTİREMEZSİNİZ.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>Lehçe arayüz</target>
|
||||
@@ -4704,6 +4729,10 @@ Hata: %@</target>
|
||||
<target>Gizli yönlendirme</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>Profil ve sunucu bağlantıları</target>
|
||||
@@ -5611,6 +5640,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Sunucu adresi ağ ayarlarıyla uyumlu değil.</target>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>Sunucunun sıra oluşturması için yetki gereklidir, şifreyi kontrol edin</target>
|
||||
@@ -5635,6 +5668,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>Sunucular</target>
|
||||
@@ -5772,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>
|
||||
@@ -5996,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>
|
||||
@@ -7062,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>
|
||||
@@ -7470,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>
|
||||
@@ -7799,6 +7840,10 @@ SimpleX sunucuları profilinizi göremez.</target>
|
||||
<target>iOS Anahtar Zinciri, uygulamayı yeniden başlattıktan veya parolayı değiştirdikten sonra parolayı güvenli bir şekilde saklamak için kullanılacaktır - anlık bildirimlerin alınmasına izin verecektir.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>kişi bağlantı linki aracılığıyla gizli</target>
|
||||
@@ -8083,6 +8128,9 @@ SimpleX sunucuları profilinizi göremez.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>sunucu kuyruk bilgisi: %1$@
|
||||
|
||||
son alınan msj: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -127,11 +127,6 @@
|
||||
<target>%@ перевірено</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ сервери</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<target>%@ завантажено</target>
|
||||
@@ -590,6 +585,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>Додайте адресу до свого профілю, щоб ваші контакти могли поділитися нею з іншими людьми. Повідомлення про оновлення профілю буде надіслано вашим контактам.</target>
|
||||
@@ -610,16 +609,16 @@
|
||||
<target>Додати профіль</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Додати сервер</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>Додайте сервери, відсканувавши QR-код.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Додати сервер…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>Додати до іншого пристрою</target>
|
||||
@@ -710,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">
|
||||
@@ -1354,6 +1353,10 @@
|
||||
<target>Налаштування серверів ICE</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>Підтвердити</target>
|
||||
@@ -1533,10 +1536,6 @@ This is your own one-time link!</source>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>Контакт дозволяє</target>
|
||||
@@ -1710,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">
|
||||
@@ -1837,6 +1836,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Доставка налагодження</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3869,6 +3869,10 @@ This is your link for group %@!</source>
|
||||
<target>Учасник</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>Роль учасника буде змінено на "%@". Всі учасники групи будуть повідомлені про це.</target>
|
||||
@@ -3908,8 +3912,17 @@ This is your link for group %@!</source>
|
||||
<target>Чернетка повідомлення</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Інформація про чергу повідомлень</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -3927,6 +3940,10 @@ This is your link for group %@!</source>
|
||||
<target>Реакції на повідомлення в цій групі заборонені.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<target>Запасний варіант маршрутизації повідомлень</target>
|
||||
@@ -3950,10 +3967,6 @@ This is your link for group %@!</source>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>Текст повідомлення</target>
|
||||
@@ -4222,6 +4235,10 @@ This is your link for group %@!</source>
|
||||
<target>Токен пристрою відсутній!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>Немає фільтрованих чатів</target>
|
||||
@@ -4469,6 +4486,10 @@ This is your link for group %@!</source>
|
||||
<target>Інше</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>Кількість PING</target>
|
||||
@@ -4635,6 +4656,10 @@ Error: %@</source>
|
||||
<target>Будь ласка, зберігайте пароль надійно, ви НЕ зможете змінити його, якщо втратите.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>Польський інтерфейс</target>
|
||||
@@ -4704,6 +4729,10 @@ Error: %@</source>
|
||||
<target>Приватна маршрутизація</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>З'єднання профілю та сервера</target>
|
||||
@@ -5611,6 +5640,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Адреса сервера несумісна з налаштуваннями мережі.</target>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>Сервер вимагає авторизації для створення черг, перевірте пароль</target>
|
||||
@@ -5635,6 +5668,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>Сервери</target>
|
||||
@@ -5772,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>
|
||||
@@ -5996,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>
|
||||
@@ -7062,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>
|
||||
@@ -7470,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>
|
||||
@@ -7799,6 +7840,10 @@ SimpleX servers cannot see your profile.</source>
|
||||
<target>Пароль бази даних буде безпечно збережено в iOS Keychain після запуску чату або зміни пароля - це дасть змогу отримувати миттєві повідомлення.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>інкогніто за посиланням на контактну адресу</target>
|
||||
@@ -8083,6 +8128,9 @@ SimpleX servers cannot see your profile.</source>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>інформація про чергу на сервері: %1$@
|
||||
|
||||
останнє отримане повідомлення: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -126,11 +126,6 @@
|
||||
<target>%@ 已认证</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ servers" xml:space="preserve">
|
||||
<source>%@ servers</source>
|
||||
<target>%@ 服务器</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve">
|
||||
<source>%@ uploaded</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -578,6 +573,10 @@
|
||||
<source>Acknowledgement errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve">
|
||||
<source>Active connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>将地址添加到您的个人资料,以便您的联系人可以与其他人共享。个人资料更新将发送给您的联系人。</target>
|
||||
@@ -598,16 +597,16 @@
|
||||
<target>添加个人资料</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>添加服务器</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add servers by scanning QR codes." xml:space="preserve">
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<target>扫描二维码来添加服务器。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>添加服务器…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
<source>Add to another device</source>
|
||||
<target>添加另一设备</target>
|
||||
@@ -697,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">
|
||||
@@ -1337,6 +1336,10 @@
|
||||
<target>配置 ICE 服务器</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configured %@ servers" xml:space="preserve">
|
||||
<source>Configured %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm" xml:space="preserve">
|
||||
<source>Confirm</source>
|
||||
<target>确认</target>
|
||||
@@ -1509,10 +1512,6 @@ This is your own one-time link!</source>
|
||||
<source>Connections</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connections subscribed" xml:space="preserve">
|
||||
<source>Connections subscribed</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact allows" xml:space="preserve">
|
||||
<source>Contact allows</source>
|
||||
<target>联系人允许</target>
|
||||
@@ -1684,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">
|
||||
@@ -3819,6 +3818,10 @@ This is your link for group %@!</source>
|
||||
<target>成员</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member inactive" xml:space="preserve">
|
||||
<source>Member inactive</source>
|
||||
<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">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>成员角色将更改为 "%@"。所有群成员将收到通知。</target>
|
||||
@@ -3857,6 +3860,14 @@ This is your link for group %@!</source>
|
||||
<target>消息草稿</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message forwarded" xml:space="preserve">
|
||||
<source>Message forwarded</source>
|
||||
<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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3876,6 +3887,10 @@ This is your link for group %@!</source>
|
||||
<target>该群组禁用了消息回应。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message routing fallback" xml:space="preserve">
|
||||
<source>Message routing fallback</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3897,10 +3912,6 @@ This is your link for group %@!</source>
|
||||
<source>Message status: %@</source>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message subscriptions" xml:space="preserve">
|
||||
<source>Message subscriptions</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message text" xml:space="preserve">
|
||||
<source>Message text</source>
|
||||
<target>消息正文</target>
|
||||
@@ -4165,6 +4176,10 @@ This is your link for group %@!</source>
|
||||
<target>无设备令牌!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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>
|
||||
<note>item status description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No filtered chats" xml:space="preserve">
|
||||
<source>No filtered chats</source>
|
||||
<target>无过滤聊天</target>
|
||||
@@ -4410,6 +4425,10 @@ This is your link for group %@!</source>
|
||||
<target>其他</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other %@ servers" xml:space="preserve">
|
||||
<source>Other %@ servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
<source>PING count</source>
|
||||
<target>PING 次数</target>
|
||||
@@ -4573,6 +4592,10 @@ Error: %@</source>
|
||||
<target>请安全地保存密码,如果您丢失了密码,您将无法更改它。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please try later." xml:space="preserve">
|
||||
<source>Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Polish interface" xml:space="preserve">
|
||||
<source>Polish interface</source>
|
||||
<target>波兰语界面</target>
|
||||
@@ -4639,6 +4662,10 @@ Error: %@</source>
|
||||
<source>Private routing</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private routing error" xml:space="preserve">
|
||||
<source>Private routing error</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>资料和服务器连接</target>
|
||||
@@ -5535,6 +5562,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Server address is incompatible with network settings.</source>
|
||||
<note>srv error text.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address is incompatible with network settings: %@." xml:space="preserve">
|
||||
<source>Server address is incompatible with network settings: %@.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to create queues, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to create queues, check password</source>
|
||||
<target>服务器需要授权才能创建队列,检查密码</target>
|
||||
@@ -5558,6 +5589,14 @@ 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>
|
||||
</trans-unit>
|
||||
<trans-unit id="Servers" xml:space="preserve">
|
||||
<source>Servers</source>
|
||||
<target>服务器</target>
|
||||
@@ -5694,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>
|
||||
@@ -5917,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>
|
||||
@@ -6965,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>
|
||||
@@ -7368,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>
|
||||
@@ -7696,6 +7735,10 @@ SimpleX 服务器无法看到您的资料。</target>
|
||||
<target>在您重启应用或改变密码后,iOS钥匙串将被用来安全地存储密码——它将允许接收推送通知。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="inactive" xml:space="preserve">
|
||||
<source>inactive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="incognito via contact address link" xml:space="preserve">
|
||||
<source>incognito via contact address link</source>
|
||||
<target>通过联系人地址链接隐身聊天</target>
|
||||
|
||||
@@ -358,9 +358,9 @@
|
||||
<target state="translated">使用二維碼掃描以新增伺服器。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve" approved="no">
|
||||
<source>Add server…</source>
|
||||
<target state="translated">新增伺服器…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve" approved="no">
|
||||
<source>Add server</source>
|
||||
<target state="translated">新增伺服器</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve" approved="no">
|
||||
|
||||
@@ -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")
|
||||
@@ -636,7 +634,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 +675,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 +724,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)
|
||||
|
||||
@@ -100,7 +100,6 @@
|
||||
5CB924D727A8563F00ACCCDD /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB924D627A8563F00ACCCDD /* SettingsView.swift */; };
|
||||
5CB924E127A867BA00ACCCDD /* UserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB924E027A867BA00ACCCDD /* UserProfile.swift */; };
|
||||
5CB9250D27A9432000ACCCDD /* ChatListNavLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB9250C27A9432000ACCCDD /* ChatListNavLink.swift */; };
|
||||
5CBD285A295711D700EC2CF4 /* ImageUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBD2859295711D700EC2CF4 /* ImageUtils.swift */; };
|
||||
5CBD285C29575B8E00EC2CF4 /* WhatsNewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBD285B29575B8E00EC2CF4 /* WhatsNewView.swift */; };
|
||||
5CBE6C12294487F7002D9531 /* VerifyCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBE6C11294487F7002D9531 /* VerifyCodeView.swift */; };
|
||||
5CBE6C142944CC12002D9531 /* ScanCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBE6C132944CC12002D9531 /* ScanCodeView.swift */; };
|
||||
@@ -171,6 +170,11 @@
|
||||
649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCDA12805D6EF00C3A862 /* CIImageView.swift */; };
|
||||
64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */; };
|
||||
64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */; };
|
||||
64BAC45E2C495205008D3995 /* libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64BAC4592C495205008D3995 /* libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU.a */; };
|
||||
64BAC45F2C495205008D3995 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64BAC45A2C495205008D3995 /* libffi.a */; };
|
||||
64BAC4602C495205008D3995 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64BAC45B2C495205008D3995 /* libgmpxx.a */; };
|
||||
64BAC4612C495205008D3995 /* libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64BAC45C2C495205008D3995 /* libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU-ghc9.6.3.a */; };
|
||||
64BAC4622C495205008D3995 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64BAC45D2C495205008D3995 /* libgmp.a */; };
|
||||
64C06EB52A0A4A7C00792D4D /* ChatItemInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */; };
|
||||
64C3B0212A0D359700E19930 /* CustomTimePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C3B0202A0D359700E19930 /* CustomTimePicker.swift */; };
|
||||
64D0C2C029F9688300B38D5F /* UserAddressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2BF29F9688300B38D5F /* UserAddressView.swift */; };
|
||||
@@ -195,6 +199,8 @@
|
||||
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 */; };
|
||||
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 */; };
|
||||
CEEA861D2C2ABCB50084E1EA /* ReverseList.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */; };
|
||||
D7197A1829AE89660055C05A /* WebRTC in Frameworks */ = {isa = PBXBuildFile; productRef = D7197A1729AE89660055C05A /* WebRTC */; };
|
||||
@@ -203,11 +209,7 @@
|
||||
D741547A29AF90B00022400A /* PushKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D741547929AF90B00022400A /* PushKit.framework */; };
|
||||
D77B92DC2952372200A5A1CC /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = D77B92DB2952372200A5A1CC /* SwiftyGif */; };
|
||||
D7F0E33929964E7E0068AF69 /* LZString in Frameworks */ = {isa = PBXBuildFile; productRef = D7F0E33829964E7E0068AF69 /* LZString */; };
|
||||
E52FF8DA2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D52C34676600BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a */; };
|
||||
E52FF8DB2C34676700BF81EB /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D62C34676600BF81EB /* libgmpxx.a */; };
|
||||
E52FF8DC2C34676700BF81EB /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D72C34676700BF81EB /* libffi.a */; };
|
||||
E52FF8DD2C34676700BF81EB /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D82C34676700BF81EB /* libgmp.a */; };
|
||||
E52FF8DE2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D92C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a */; };
|
||||
E50581062C3DDD9D009C3F71 /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = E50581052C3DDD9D009C3F71 /* Yams */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -478,6 +480,11 @@
|
||||
649BCDA12805D6EF00C3A862 /* CIImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIImageView.swift; sourceTree = "<group>"; };
|
||||
64AA1C6827EE10C800AC7277 /* ContextItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextItemView.swift; sourceTree = "<group>"; };
|
||||
64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletedItemView.swift; sourceTree = "<group>"; };
|
||||
64BAC4592C495205008D3995 /* libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU.a"; sourceTree = "<group>"; };
|
||||
64BAC45A2C495205008D3995 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
64BAC45B2C495205008D3995 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
64BAC45C2C495205008D3995 /* libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
64BAC45D2C495205008D3995 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemInfoView.swift; sourceTree = "<group>"; };
|
||||
64C3B0202A0D359700E19930 /* CustomTimePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTimePicker.swift; sourceTree = "<group>"; };
|
||||
64D0C2BF29F9688300B38D5F /* UserAddressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAddressView.swift; sourceTree = "<group>"; };
|
||||
@@ -508,11 +515,6 @@
|
||||
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; };
|
||||
E52FF8D52C34676600BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
E52FF8D62C34676600BF81EB /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
E52FF8D72C34676700BF81EB /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
E52FF8D82C34676700BF81EB /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
E52FF8D92C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -551,13 +553,15 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E52FF8DE2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a in Frameworks */,
|
||||
E52FF8DB2C34676700BF81EB /* libgmpxx.a in Frameworks */,
|
||||
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
|
||||
64BAC4622C495205008D3995 /* libgmp.a in Frameworks */,
|
||||
64BAC45F2C495205008D3995 /* libffi.a in Frameworks */,
|
||||
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
|
||||
E52FF8DC2C34676700BF81EB /* libffi.a in Frameworks */,
|
||||
E52FF8DD2C34676700BF81EB /* libgmp.a in Frameworks */,
|
||||
E52FF8DA2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a in Frameworks */,
|
||||
E50581062C3DDD9D009C3F71 /* Yams in Frameworks */,
|
||||
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
|
||||
64BAC4612C495205008D3995 /* libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU-ghc9.6.3.a in Frameworks */,
|
||||
64BAC45E2C495205008D3995 /* libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU.a in Frameworks */,
|
||||
64BAC4602C495205008D3995 /* libgmpxx.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -624,11 +628,11 @@
|
||||
5C764E5C279C70B7000C6508 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E52FF8D72C34676700BF81EB /* libffi.a */,
|
||||
E52FF8D82C34676700BF81EB /* libgmp.a */,
|
||||
E52FF8D62C34676600BF81EB /* libgmpxx.a */,
|
||||
E52FF8D52C34676600BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a */,
|
||||
E52FF8D92C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a */,
|
||||
64BAC45A2C495205008D3995 /* libffi.a */,
|
||||
64BAC45D2C495205008D3995 /* libgmp.a */,
|
||||
64BAC45B2C495205008D3995 /* libgmpxx.a */,
|
||||
64BAC45C2C495205008D3995 /* libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU-ghc9.6.3.a */,
|
||||
64BAC4592C495205008D3995 /* libHSsimplex-chat-6.0.0.1-J5MWx9pYOGnDBWRfMkQxFU.a */,
|
||||
);
|
||||
path = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@@ -656,7 +660,6 @@
|
||||
5CF937212B25034A00E1D781 /* NSESubscriber.swift */,
|
||||
5CB346E82869E8BA001FD2EF /* PushEnvironment.swift */,
|
||||
5C93293E2928E0FD0090FFF9 /* AudioRecPlay.swift */,
|
||||
5CBD2859295711D700EC2CF4 /* ImageUtils.swift */,
|
||||
8CC956ED2BC0041000412A11 /* NetworkObserver.swift */,
|
||||
);
|
||||
path = Model;
|
||||
@@ -856,6 +859,7 @@
|
||||
5C9FD96A27A56D4D0075386C /* JSON.swift */,
|
||||
5CDCAD7D2818941F00503DA2 /* API.swift */,
|
||||
5CDCAD80281A7E2700503DA2 /* Notifications.swift */,
|
||||
5CBD2859295711D700EC2CF4 /* ImageUtils.swift */,
|
||||
64DAE1502809D9F5000DA960 /* FileUtils.swift */,
|
||||
5C9D81182AA7A4F1001D49FD /* CryptoFile.swift */,
|
||||
5C00168028C4FE760094D739 /* KeyChain.swift */,
|
||||
@@ -1065,6 +1069,8 @@
|
||||
);
|
||||
name = SimpleXChat;
|
||||
packageProductDependencies = (
|
||||
E50581052C3DDD9D009C3F71 /* Yams */,
|
||||
CE38A29B2C3FCD72005ED185 /* SwiftyGif */,
|
||||
);
|
||||
productName = SimpleXChat;
|
||||
productReference = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */;
|
||||
@@ -1202,7 +1208,6 @@
|
||||
6432857C2925443C00FBE5C8 /* GroupPreferencesView.swift in Sources */,
|
||||
5C93293129239BED0090FFF9 /* ProtocolServerView.swift in Sources */,
|
||||
5C9CC7AD28C55D7800BEF955 /* DatabaseEncryptionView.swift in Sources */,
|
||||
5CBD285A295711D700EC2CF4 /* ImageUtils.swift in Sources */,
|
||||
8C74C3EC2C1B92A900039E77 /* Theme.swift in Sources */,
|
||||
6419EC562AB8BC8B004A607A /* ContextInvitingContactMemberView.swift in Sources */,
|
||||
5CE4407927ADB701007B033A /* EmojiItemView.swift in Sources */,
|
||||
@@ -1373,6 +1378,7 @@
|
||||
5CE2BA90284533A300EC33A6 /* JSON.swift in Sources */,
|
||||
5CE2BA8B284533A300EC33A6 /* ChatTypes.swift in Sources */,
|
||||
5CE2BA8F284533A300EC33A6 /* APITypes.swift in Sources */,
|
||||
CE38A29A2C3FCA54005ED185 /* ImageUtils.swift in Sources */,
|
||||
5C9D811A2AA8727A001D49FD /* CryptoFile.swift in Sources */,
|
||||
5CE2BA8C284533A300EC33A6 /* AppGroup.swift in Sources */,
|
||||
8C74C3E52C1B900600039E77 /* ThemeTypes.swift in Sources */,
|
||||
@@ -1612,7 +1618,7 @@
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 226;
|
||||
CURRENT_PROJECT_VERSION = 228;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -1637,7 +1643,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LLVM_LTO = YES_THIN;
|
||||
MARKETING_VERSION = 5.8.2;
|
||||
MARKETING_VERSION = 6.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
|
||||
PRODUCT_NAME = SimpleX;
|
||||
SDKROOT = iphoneos;
|
||||
@@ -1661,7 +1667,7 @@
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 226;
|
||||
CURRENT_PROJECT_VERSION = 228;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -1686,7 +1692,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LLVM_LTO = YES;
|
||||
MARKETING_VERSION = 5.8.2;
|
||||
MARKETING_VERSION = 6.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
|
||||
PRODUCT_NAME = SimpleX;
|
||||
SDKROOT = iphoneos;
|
||||
@@ -1747,7 +1753,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 226;
|
||||
CURRENT_PROJECT_VERSION = 228;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
@@ -1762,7 +1768,7 @@
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LLVM_LTO = YES;
|
||||
MARKETING_VERSION = 5.8.2;
|
||||
MARKETING_VERSION = 6.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -1784,7 +1790,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 226;
|
||||
CURRENT_PROJECT_VERSION = 228;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
ENABLE_CODE_COVERAGE = NO;
|
||||
@@ -1799,7 +1805,7 @@
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LLVM_LTO = YES;
|
||||
MARKETING_VERSION = 5.8.2;
|
||||
MARKETING_VERSION = 6.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -1821,7 +1827,7 @@
|
||||
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 226;
|
||||
CURRENT_PROJECT_VERSION = 228;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@@ -1847,7 +1853,7 @@
|
||||
"$(PROJECT_DIR)/Libraries/sim",
|
||||
);
|
||||
LLVM_LTO = YES;
|
||||
MARKETING_VERSION = 5.8.2;
|
||||
MARKETING_VERSION = 6.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SDKROOT = iphoneos;
|
||||
@@ -1872,7 +1878,7 @@
|
||||
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 226;
|
||||
CURRENT_PROJECT_VERSION = 228;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@@ -1898,7 +1904,7 @@
|
||||
"$(PROJECT_DIR)/Libraries/sim",
|
||||
);
|
||||
LLVM_LTO = YES;
|
||||
MARKETING_VERSION = 5.8.2;
|
||||
MARKETING_VERSION = 6.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SDKROOT = iphoneos;
|
||||
@@ -1971,8 +1977,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" */ = {
|
||||
@@ -1995,8 +2001,8 @@
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/kirualex/SwiftyGif";
|
||||
requirement = {
|
||||
branch = master;
|
||||
kind = branch;
|
||||
kind = revision;
|
||||
revision = 5e8619335d394901379c9add5c4c1c2f420b3800;
|
||||
};
|
||||
};
|
||||
D7F0E33729964E7D0068AF69 /* XCRemoteSwiftPackageReference "lzstring-swift" */ = {
|
||||
@@ -2020,6 +2026,11 @@
|
||||
package = 8C73C1162C21E17B00892670 /* XCRemoteSwiftPackageReference "Yams" */;
|
||||
productName = Yams;
|
||||
};
|
||||
CE38A29B2C3FCD72005ED185 /* SwiftyGif */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = D77B92DA2952372200A5A1CC /* XCRemoteSwiftPackageReference "SwiftyGif" */;
|
||||
productName = SwiftyGif;
|
||||
};
|
||||
D7197A1729AE89660055C05A /* WebRTC */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = D7197A1629AE89660055C05A /* XCRemoteSwiftPackageReference "WebRTC" */;
|
||||
@@ -2035,6 +2046,11 @@
|
||||
package = D7F0E33729964E7D0068AF69 /* XCRemoteSwiftPackageReference "lzstring-swift" */;
|
||||
productName = LZString;
|
||||
};
|
||||
E50581052C3DDD9D009C3F71 /* Yams */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 8C73C1162C21E17B00892670 /* XCRemoteSwiftPackageReference "Yams" */;
|
||||
productName = Yams;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
};
|
||||
rootObject = 5CA059BE279559F40002BEB4 /* Project object */;
|
||||
|
||||
@@ -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,7 @@ 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 apiStopChat
|
||||
case apiActivateChat(restoreChat: Bool)
|
||||
case apiSuspendChat(timeoutMicroseconds: Int)
|
||||
@@ -146,6 +146,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 +172,7 @@ 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 .apiStopChat: return "/_stop"
|
||||
case let .apiActivateChat(restore): return "/_app activate restore=\(onOff(restore))"
|
||||
case let .apiSuspendChat(timeoutMicroseconds): return "/_app suspend \(timeoutMicroseconds)"
|
||||
@@ -309,6 +310,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
|
||||
@@ -447,6 +449,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 +578,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 +665,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 +681,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 +747,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 +843,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 +914,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 +1010,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))
|
||||
@@ -1122,20 +1131,20 @@ public struct ProtoServersConfig: Codable {
|
||||
public struct UserProtoServers: Decodable {
|
||||
public var serverProtocol: ServerProtocol
|
||||
public var protoServers: [ServerCfg]
|
||||
public var presetServers: [String]
|
||||
public var presetServers: [ServerCfg]
|
||||
}
|
||||
|
||||
public struct ServerCfg: Identifiable, Equatable, Codable {
|
||||
public struct ServerCfg: Identifiable, Equatable, Codable, Hashable {
|
||||
public var server: String
|
||||
public var preset: Bool
|
||||
public var tested: Bool?
|
||||
public var enabled: ServerEnabled
|
||||
public var enabled: Bool
|
||||
var createdAt = Date()
|
||||
// public var sendEnabled: Bool // can we potentially want to prevent sending on the servers we use to receive?
|
||||
// Even if we don't see the use case, it's probably better to allow it in the model
|
||||
// In any case, "trusted/known" servers are out of scope of this change
|
||||
|
||||
public init(server: String, preset: Bool, tested: Bool?, enabled: ServerEnabled) {
|
||||
public init(server: String, preset: Bool, tested: Bool?, enabled: Bool) {
|
||||
self.server = server
|
||||
self.preset = preset
|
||||
self.tested = tested
|
||||
@@ -1148,7 +1157,7 @@ public struct ServerCfg: Identifiable, Equatable, Codable {
|
||||
|
||||
public var id: String { "\(server) \(createdAt)" }
|
||||
|
||||
public static var empty = ServerCfg(server: "", preset: false, tested: nil, enabled: .enabled)
|
||||
public static var empty = ServerCfg(server: "", preset: false, tested: nil, enabled: false)
|
||||
|
||||
public var isEmpty: Bool {
|
||||
server.trimmingCharacters(in: .whitespaces) == ""
|
||||
@@ -1165,19 +1174,19 @@ public struct ServerCfg: Identifiable, Equatable, Codable {
|
||||
server: "smp://abcd@smp8.simplex.im",
|
||||
preset: true,
|
||||
tested: true,
|
||||
enabled: .enabled
|
||||
enabled: true
|
||||
),
|
||||
custom: ServerCfg(
|
||||
server: "smp://abcd@smp9.simplex.im",
|
||||
preset: false,
|
||||
tested: false,
|
||||
enabled: .disabled
|
||||
enabled: false
|
||||
),
|
||||
untested: ServerCfg(
|
||||
server: "smp://abcd@smp10.simplex.im",
|
||||
preset: false,
|
||||
tested: nil,
|
||||
enabled: .enabled
|
||||
enabled: true
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1189,12 +1198,6 @@ public struct ServerCfg: Identifiable, Equatable, Codable {
|
||||
}
|
||||
}
|
||||
|
||||
public enum ServerEnabled: String, Codable {
|
||||
case disabled
|
||||
case enabled
|
||||
case known
|
||||
}
|
||||
|
||||
public enum ProtocolTestStep: String, Decodable, Equatable {
|
||||
case connect
|
||||
case disconnect
|
||||
@@ -1234,7 +1237,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")
|
||||
@@ -1293,42 +1296,32 @@ public struct NetCfg: Codable, Equatable, Hashable {
|
||||
var socksMode: SocksMode = .always
|
||||
public var hostMode: HostMode = .publicHost
|
||||
public var requiredHostMode = true
|
||||
public var sessionMode: TransportSessionMode
|
||||
public var smpProxyMode: SMPProxyMode = .never
|
||||
public var smpProxyFallback: SMPProxyFallback = .allow
|
||||
public var sessionMode = TransportSessionMode.user
|
||||
public var smpProxyMode: SMPProxyMode = .unknown
|
||||
public var smpProxyFallback: SMPProxyFallback = .allowProtected
|
||||
public var tcpConnectTimeout: Int // microseconds
|
||||
public var tcpTimeout: Int // microseconds
|
||||
public var tcpTimeoutPerKb: Int // microseconds
|
||||
public var rcvConcurrency: Int // pool size
|
||||
public var tcpKeepAlive: KeepAliveOpts?
|
||||
public var tcpKeepAlive: KeepAliveOpts? = KeepAliveOpts.defaults
|
||||
public var smpPingInterval: Int // microseconds
|
||||
public var smpPingCount: Int // times
|
||||
public var logTLSErrors: Bool
|
||||
public var smpPingCount: Int = 3 // times
|
||||
public var logTLSErrors: Bool = false
|
||||
|
||||
public static let defaults: NetCfg = NetCfg(
|
||||
socksProxy: nil,
|
||||
sessionMode: TransportSessionMode.user,
|
||||
tcpConnectTimeout: 25_000_000,
|
||||
tcpTimeout: 15_000_000,
|
||||
tcpTimeoutPerKb: 10_000,
|
||||
rcvConcurrency: 12,
|
||||
tcpKeepAlive: KeepAliveOpts.defaults,
|
||||
smpPingInterval: 1200_000_000,
|
||||
smpPingCount: 3,
|
||||
logTLSErrors: false
|
||||
smpPingInterval: 1200_000_000
|
||||
)
|
||||
|
||||
public static let proxyDefaults: NetCfg = NetCfg(
|
||||
socksProxy: nil,
|
||||
sessionMode: TransportSessionMode.user,
|
||||
tcpConnectTimeout: 35_000_000,
|
||||
tcpTimeout: 20_000_000,
|
||||
tcpTimeoutPerKb: 15_000,
|
||||
rcvConcurrency: 8,
|
||||
tcpKeepAlive: KeepAliveOpts.defaults,
|
||||
smpPingInterval: 1200_000_000,
|
||||
smpPingCount: 3,
|
||||
logTLSErrors: false
|
||||
smpPingInterval: 1200_000_000
|
||||
)
|
||||
|
||||
public var enableKeepAlive: Bool { tcpKeepAlive != nil }
|
||||
@@ -1903,9 +1896,10 @@ 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)
|
||||
case RCP(rcpErr: RCErrorType)
|
||||
case BROKER(brokerAddress: String, brokerErr: BrokerErrorType)
|
||||
case AGENT(agentErr: SMPAgentError)
|
||||
@@ -1943,13 +1937,23 @@ public enum ProtocolErrorType: Decodable, Hashable {
|
||||
case BLOCK
|
||||
case SESSION
|
||||
case CMD(cmdErr: ProtocolCommandError)
|
||||
indirect case PROXY(proxyErr: ProxyError)
|
||||
case AUTH
|
||||
case CRYPTO
|
||||
case QUOTA
|
||||
case NO_MSG
|
||||
case LARGE_MSG
|
||||
case EXPIRED
|
||||
case INTERNAL
|
||||
}
|
||||
|
||||
public enum ProxyError: Decodable, Hashable {
|
||||
case PROTOCOL(protocolErr: ProtocolErrorType)
|
||||
case BROKER(brokerErr: BrokerErrorType)
|
||||
case BASIC_AUTH
|
||||
case NO_SESSION
|
||||
}
|
||||
|
||||
public enum XFTPErrorType: Decodable, Hashable {
|
||||
case BLOCK
|
||||
case SESSION
|
||||
@@ -1967,6 +1971,12 @@ public enum XFTPErrorType: Decodable, Hashable {
|
||||
case INTERNAL
|
||||
}
|
||||
|
||||
public enum ProxyClientError: Decodable, Hashable {
|
||||
case protocolError(protocolErr: ProtocolErrorType)
|
||||
case unexpectedResponse(responseStr: String)
|
||||
case responseError(responseErr: ProtocolErrorType)
|
||||
}
|
||||
|
||||
public enum RCErrorType: Decodable, Hashable {
|
||||
case `internal`(internalErr: String)
|
||||
case identity
|
||||
@@ -1996,6 +2006,7 @@ public enum ProtocolCommandError: Decodable, Hashable {
|
||||
|
||||
public enum ProtocolTransportError: Decodable, Hashable {
|
||||
case badBlock
|
||||
case version
|
||||
case largeMsg
|
||||
case badSession
|
||||
case noServerAuth
|
||||
@@ -2085,6 +2096,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
|
||||
@@ -2114,6 +2126,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 }
|
||||
@@ -2144,6 +2157,7 @@ public struct AppSettings: Codable, Equatable, Hashable {
|
||||
privacyShowChatPreviews: true,
|
||||
privacySaveLastDraft: true,
|
||||
privacyProtectScreen: false,
|
||||
privacyMediaBlurRadius: 0,
|
||||
notificationMode: AppSettingsNotificationMode.instant,
|
||||
notificationPreviewMode: NotificationPreviewMode.message,
|
||||
webrtcPolicyRelay: true,
|
||||
@@ -2319,6 +2333,8 @@ public struct ServerSessions: Codable {
|
||||
ssErrors: 0,
|
||||
ssConnecting: 0
|
||||
)
|
||||
|
||||
public var hasSess: Bool { ssConnected > 0 }
|
||||
}
|
||||
|
||||
public struct SMPServerSubs: Codable {
|
||||
@@ -2372,6 +2388,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 {
|
||||
@@ -2411,3 +2431,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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -1611,11 +1612,12 @@ public struct Connection: Decodable, Hashable {
|
||||
public var pqSndEnabled: Bool?
|
||||
public var pqRcvEnabled: Bool?
|
||||
public var authErrCounter: Int
|
||||
public var quotaErrCounter: Int
|
||||
|
||||
public var connectionStats: ConnectionStats? = nil
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case connId, agentConnId, peerChatVRange, connStatus, connLevel, viaGroupLink, customUserProfileId, connectionCode, pqSupport, pqEncryption, pqSndEnabled, pqRcvEnabled, authErrCounter
|
||||
case connId, agentConnId, peerChatVRange, connStatus, connLevel, viaGroupLink, customUserProfileId, connectionCode, pqSupport, pqEncryption, pqSndEnabled, pqRcvEnabled, authErrCounter, quotaErrCounter
|
||||
}
|
||||
|
||||
public var id: ChatId { get { ":\(connId)" } }
|
||||
@@ -1624,6 +1626,10 @@ public struct Connection: Decodable, Hashable {
|
||||
authErrCounter >= 10 // authErrDisableCount in core
|
||||
}
|
||||
|
||||
public var connInactive: Bool {
|
||||
quotaErrCounter >= 5 // quotaErrInactiveCount in core
|
||||
}
|
||||
|
||||
public var connPQEnabled: Bool {
|
||||
pqSndEnabled == true && pqRcvEnabled == true
|
||||
}
|
||||
@@ -1637,7 +1643,8 @@ public struct Connection: Decodable, Hashable {
|
||||
viaGroupLink: false,
|
||||
pqSupport: false,
|
||||
pqEncryption: false,
|
||||
authErrCounter: 0
|
||||
authErrCounter: 0,
|
||||
quotaErrCounter: 0
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1818,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
|
||||
}
|
||||
@@ -2846,6 +2853,62 @@ public enum SndCIStatusProgress: String, Decodable, Hashable {
|
||||
case complete
|
||||
}
|
||||
|
||||
public enum GroupSndStatus: Decodable, Hashable {
|
||||
case new
|
||||
case forwarded
|
||||
case inactive
|
||||
case sent
|
||||
case rcvd(msgRcptStatus: MsgReceiptStatus)
|
||||
case error(agentError: SndError)
|
||||
case warning(agentError: SndError)
|
||||
case invalid(text: String)
|
||||
|
||||
public func statusIcon(_ metaColor: Color/* = .secondary*/, _ primaryColor: Color = .accentColor) -> (String, Color) {
|
||||
switch self {
|
||||
case .new: return ("ellipsis", metaColor)
|
||||
case .forwarded: return ("chevron.forward.2", metaColor)
|
||||
case .inactive: return ("person.badge.minus", metaColor)
|
||||
case .sent: return ("checkmark", metaColor)
|
||||
case let .rcvd(msgRcptStatus):
|
||||
switch msgRcptStatus {
|
||||
case .ok: return ("checkmark", metaColor)
|
||||
case .badMsgHash: return ("checkmark", .red)
|
||||
}
|
||||
case .error: return ("multiply", .red)
|
||||
case .warning: return ("exclamationmark.triangle.fill", .orange)
|
||||
case .invalid: return ("questionmark", metaColor)
|
||||
}
|
||||
}
|
||||
|
||||
public var statusInfo: (String, String)? {
|
||||
switch self {
|
||||
case .new: return nil
|
||||
case .forwarded: return (
|
||||
NSLocalizedString("Message forwarded", comment: "item status text"),
|
||||
NSLocalizedString("No direct connection yet, message is forwarded by admin.", comment: "item status description")
|
||||
)
|
||||
case .inactive: return (
|
||||
NSLocalizedString("Member inactive", comment: "item status text"),
|
||||
NSLocalizedString("Message may be delivered later if member becomes active.", comment: "item status description")
|
||||
)
|
||||
case .sent: return nil
|
||||
case .rcvd: return nil
|
||||
case let .error(agentError): return (
|
||||
NSLocalizedString("Message delivery error", comment: "item status text"),
|
||||
agentError.errorInfo
|
||||
)
|
||||
case let .warning(agentError): return (
|
||||
NSLocalizedString("Message delivery warning", comment: "item status text"),
|
||||
agentError.errorInfo
|
||||
)
|
||||
case let .invalid(text): return (
|
||||
NSLocalizedString("Invalid status", comment: "item status text"),
|
||||
text
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum CIDeleted: Decodable, Hashable {
|
||||
case deleted(deletedTs: Date?)
|
||||
case blocked(deletedTs: Date?)
|
||||
@@ -3231,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 {
|
||||
@@ -4012,6 +4097,6 @@ public struct ChatItemVersion: Decodable, Hashable {
|
||||
|
||||
public struct MemberDeliveryStatus: Decodable, Hashable {
|
||||
public var groupMemberId: Int64
|
||||
public var memberDeliveryStatus: CIStatus
|
||||
public var memberDeliveryStatus: GroupSndStatus
|
||||
public var sentViaProxy: Bool?
|
||||
}
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SimpleXChat
|
||||
import SwiftUI
|
||||
import AVKit
|
||||
import SwiftyGif
|
||||
|
||||
func getLoadedFileSource(_ file: CIFile?) -> CryptoFile? {
|
||||
public func getLoadedFileSource(_ file: CIFile?) -> CryptoFile? {
|
||||
if let file = file, file.loaded {
|
||||
return file.fileSource
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getLoadedImage(_ file: CIFile?) -> UIImage? {
|
||||
public func getLoadedImage(_ file: CIFile?) -> UIImage? {
|
||||
if let fileSource = getLoadedFileSource(file) {
|
||||
let filePath = getAppFilePath(fileSource.filePath)
|
||||
do {
|
||||
@@ -37,7 +37,7 @@ func getLoadedImage(_ file: CIFile?) -> UIImage? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getFileData(_ path: URL, _ cfArgs: CryptoFileArgs?) throws -> Data {
|
||||
public func getFileData(_ path: URL, _ cfArgs: CryptoFileArgs?) throws -> Data {
|
||||
if let cfArgs = cfArgs {
|
||||
return try readCryptoFile(path: path.path, cryptoArgs: cfArgs)
|
||||
} else {
|
||||
@@ -45,7 +45,7 @@ func getFileData(_ path: URL, _ cfArgs: CryptoFileArgs?) throws -> Data {
|
||||
}
|
||||
}
|
||||
|
||||
func getLoadedVideo(_ file: CIFile?) -> URL? {
|
||||
public func getLoadedVideo(_ file: CIFile?) -> URL? {
|
||||
if let fileSource = getLoadedFileSource(file) {
|
||||
let filePath = getAppFilePath(fileSource.filePath)
|
||||
if FileManager.default.fileExists(atPath: filePath.path) {
|
||||
@@ -55,13 +55,13 @@ func getLoadedVideo(_ file: CIFile?) -> URL? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveAnimImage(_ image: UIImage) -> CryptoFile? {
|
||||
public func saveAnimImage(_ image: UIImage) -> CryptoFile? {
|
||||
let fileName = generateNewFileName("IMG", "gif")
|
||||
guard let imageData = image.imageData else { return nil }
|
||||
return saveFile(imageData, fileName, encrypted: privacyEncryptLocalFilesGroupDefault.get())
|
||||
}
|
||||
|
||||
func saveImage(_ uiImage: UIImage) -> CryptoFile? {
|
||||
public func saveImage(_ uiImage: UIImage) -> CryptoFile? {
|
||||
let hasAlpha = imageHasAlpha(uiImage)
|
||||
let ext = hasAlpha ? "png" : "jpg"
|
||||
if let imageDataResized = resizeImageToDataSize(uiImage, maxDataSize: MAX_IMAGE_SIZE, hasAlpha: hasAlpha) {
|
||||
@@ -71,7 +71,7 @@ func saveImage(_ uiImage: UIImage) -> CryptoFile? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func cropToSquare(_ image: UIImage) -> UIImage {
|
||||
public func cropToSquare(_ image: UIImage) -> UIImage {
|
||||
let size = image.size
|
||||
let side = min(size.width, size.height)
|
||||
let newSize = CGSize(width: side, height: side)
|
||||
@@ -84,7 +84,7 @@ func cropToSquare(_ image: UIImage) -> UIImage {
|
||||
return resizeImage(image, newBounds: CGRect(origin: .zero, size: newSize), drawIn: CGRect(origin: origin, size: size), hasAlpha: imageHasAlpha(image))
|
||||
}
|
||||
|
||||
func resizeImageToDataSize(_ image: UIImage, maxDataSize: Int64, hasAlpha: Bool) -> Data? {
|
||||
public func resizeImageToDataSize(_ image: UIImage, maxDataSize: Int64, hasAlpha: Bool) -> Data? {
|
||||
var img = image
|
||||
var data = hasAlpha ? img.pngData() : img.jpegData(compressionQuality: 0.85)
|
||||
var dataSize = data?.count ?? 0
|
||||
@@ -99,7 +99,7 @@ func resizeImageToDataSize(_ image: UIImage, maxDataSize: Int64, hasAlpha: Bool)
|
||||
return data
|
||||
}
|
||||
|
||||
func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int64) -> String? {
|
||||
public func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int64) -> String? {
|
||||
var img = image
|
||||
let hasAlpha = imageHasAlpha(image)
|
||||
var str = compressImageStr(img, hasAlpha: hasAlpha)
|
||||
@@ -115,7 +115,7 @@ func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int64) -> String? {
|
||||
return str
|
||||
}
|
||||
|
||||
func compressImageStr(_ image: UIImage, _ compressionQuality: CGFloat = 0.85, hasAlpha: Bool) -> String? {
|
||||
public func compressImageStr(_ image: UIImage, _ compressionQuality: CGFloat = 0.85, hasAlpha: Bool) -> String? {
|
||||
let ext = hasAlpha ? "png" : "jpg"
|
||||
if let data = hasAlpha ? image.pngData() : image.jpegData(compressionQuality: compressionQuality) {
|
||||
return "data:image/\(ext);base64,\(data.base64EncodedString())"
|
||||
@@ -138,7 +138,7 @@ private func resizeImage(_ image: UIImage, newBounds: CGRect, drawIn: CGRect, ha
|
||||
}
|
||||
}
|
||||
|
||||
func imageHasAlpha(_ img: UIImage) -> Bool {
|
||||
public func imageHasAlpha(_ img: UIImage) -> Bool {
|
||||
if let cgImage = img.cgImage {
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue)
|
||||
@@ -158,7 +158,7 @@ func imageHasAlpha(_ img: UIImage) -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func saveFileFromURL(_ url: URL) -> CryptoFile? {
|
||||
public func saveFileFromURL(_ url: URL) -> CryptoFile? {
|
||||
let encrypted = privacyEncryptLocalFilesGroupDefault.get()
|
||||
let savedFile: CryptoFile?
|
||||
if url.startAccessingSecurityScopedResource() {
|
||||
@@ -184,7 +184,7 @@ func saveFileFromURL(_ url: URL) -> CryptoFile? {
|
||||
return savedFile
|
||||
}
|
||||
|
||||
func moveTempFileFromURL(_ url: URL) -> CryptoFile? {
|
||||
public func moveTempFileFromURL(_ url: URL) -> CryptoFile? {
|
||||
do {
|
||||
let encrypted = privacyEncryptLocalFilesGroupDefault.get()
|
||||
let fileName = uniqueCombine(url.lastPathComponent)
|
||||
@@ -197,7 +197,6 @@ func moveTempFileFromURL(_ url: URL) -> CryptoFile? {
|
||||
try FileManager.default.moveItem(at: url, to: getAppFilePath(fileName))
|
||||
savedFile = CryptoFile.plain(fileName)
|
||||
}
|
||||
ChatModel.shared.filesToDelete.remove(url)
|
||||
return savedFile
|
||||
} catch {
|
||||
logger.error("ImageUtils.moveTempFileFromURL error: \(error.localizedDescription)")
|
||||
@@ -205,7 +204,7 @@ func moveTempFileFromURL(_ url: URL) -> CryptoFile? {
|
||||
}
|
||||
}
|
||||
|
||||
func saveWallpaperFile(url: URL) -> String? {
|
||||
public func saveWallpaperFile(url: URL) -> String? {
|
||||
let destFile = URL(fileURLWithPath: generateNewFileName(getWallpaperDirectory().path + "/" + "wallpaper", "jpg", fullPath: true))
|
||||
do {
|
||||
try FileManager.default.copyItem(atPath: url.path, toPath: destFile.path)
|
||||
@@ -216,7 +215,7 @@ func saveWallpaperFile(url: URL) -> String? {
|
||||
}
|
||||
}
|
||||
|
||||
func saveWallpaperFile(image: UIImage) -> String? {
|
||||
public func saveWallpaperFile(image: UIImage) -> String? {
|
||||
let hasAlpha = imageHasAlpha(image)
|
||||
let destFile = URL(fileURLWithPath: generateNewFileName(getWallpaperDirectory().path + "/" + "wallpaper", hasAlpha ? "png" : "jpg", fullPath: true))
|
||||
let dataResized = resizeImageToDataSize(image, maxDataSize: 5_000_000, hasAlpha: hasAlpha)
|
||||
@@ -229,7 +228,7 @@ func saveWallpaperFile(image: UIImage) -> String? {
|
||||
}
|
||||
}
|
||||
|
||||
func removeWallpaperFile(fileName: String? = nil) {
|
||||
public func removeWallpaperFile(fileName: String? = nil) {
|
||||
do {
|
||||
try FileManager.default.contentsOfDirectory(atPath: getWallpaperDirectory().path).forEach {
|
||||
if URL(fileURLWithPath: $0).lastPathComponent == fileName { try FileManager.default.removeItem(atPath: $0) }
|
||||
@@ -242,7 +241,7 @@ func removeWallpaperFile(fileName: String? = nil) {
|
||||
}
|
||||
}
|
||||
|
||||
func generateNewFileName(_ prefix: String, _ ext: String, fullPath: Bool = false) -> String {
|
||||
public func generateNewFileName(_ prefix: String, _ ext: String, fullPath: Bool = false) -> String {
|
||||
uniqueCombine("\(prefix)_\(getTimestamp()).\(ext)", fullPath: fullPath)
|
||||
}
|
||||
|
||||
@@ -274,7 +273,7 @@ private func getTimestamp() -> String {
|
||||
return df.string(from: Date())
|
||||
}
|
||||
|
||||
func dropImagePrefix(_ s: String) -> String {
|
||||
public func dropImagePrefix(_ s: String) -> String {
|
||||
dropPrefix(dropPrefix(s, "data:image/png;base64,"), "data:image/jpg;base64,")
|
||||
}
|
||||
|
||||
@@ -283,7 +282,7 @@ private func dropPrefix(_ s: String, _ prefix: String) -> String {
|
||||
}
|
||||
|
||||
extension AVAsset {
|
||||
func generatePreview() -> (UIImage, Int)? {
|
||||
public func generatePreview() -> (UIImage, Int)? {
|
||||
let generator = AVAssetImageGenerator(asset: self)
|
||||
generator.appliesPreferredTrackTransform = true
|
||||
var actualTime = CMTimeMake(value: 0, timescale: 0)
|
||||
@@ -295,7 +294,7 @@ extension AVAsset {
|
||||
}
|
||||
|
||||
extension UIImage {
|
||||
func replaceColor(_ from: UIColor, _ to: UIColor) -> UIImage {
|
||||
public func replaceColor(_ from: UIColor, _ to: UIColor) -> UIImage {
|
||||
if let cgImage = cgImage {
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue)
|
||||
@@ -340,4 +339,12 @@ extension UIImage {
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
public convenience init?(base64Encoded: String?) {
|
||||
if let base64Encoded, let data = Data(base64Encoded: dropImagePrefix(base64Encoded)) {
|
||||
self.init(data: data)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -154,9 +154,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"%@ is verified" = "%@ е потвърдено";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ servers" = "%@ сървъри";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@ uploaded" = "%@ качено";
|
||||
|
||||
@@ -337,9 +334,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "по-горе, след това избери:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Основен цвят";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Приеми";
|
||||
@@ -369,7 +363,7 @@
|
||||
"Add profile" = "Добави профил";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Добави сървър…";
|
||||
"Add server" = "Добави сървър";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Добави сървъри чрез сканиране на QR кодове.";
|
||||
@@ -831,9 +825,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "цветен";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Цветове";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Сравни файл";
|
||||
|
||||
@@ -1011,7 +1002,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Продължи";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Копирай";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1779,7 +1770,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Грешка: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Грешка: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -3791,9 +3783,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Текстът, който поставихте, не е SimpleX линк за връзка.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Тема";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Тези настройки са за текущия ви профил **%@**.";
|
||||
|
||||
@@ -4305,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!";
|
||||
|
||||
@@ -289,9 +286,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "výše, pak vyberte:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Zbarvení";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Přijmout";
|
||||
@@ -318,7 +312,7 @@
|
||||
"Add profile" = "Přidat profil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Přidat server…";
|
||||
"Add server" = "Přidat server";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Přidejte servery skenováním QR kódů.";
|
||||
@@ -678,9 +672,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "barevné";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Barvy";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Porovnat soubor";
|
||||
|
||||
@@ -813,7 +804,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Pokračovat";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Kopírovat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1461,7 +1452,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Chyba: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Chyba: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -3095,9 +3087,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The servers for new connections of your current chat profile **%@**." = "Servery pro nová připojení vašeho aktuálního chat profilu **%@**.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Téma";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Toto nastavení je pro váš aktuální profil **%@**.";
|
||||
|
||||
@@ -3447,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";
|
||||
|
||||
@@ -337,9 +334,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "y después elige:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Color";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Aceptar";
|
||||
@@ -369,7 +363,7 @@
|
||||
"Add profile" = "Añadir perfil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Añadir servidor…";
|
||||
"Add server" = "Añadir servidor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Añadir servidores mediante el escaneo de códigos QR.";
|
||||
@@ -840,9 +834,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "coloreado";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Colores";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Comparar archivo";
|
||||
|
||||
@@ -967,7 +958,7 @@
|
||||
"Connection error" = "Error conexión";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connection error (AUTH)" = "Error conexión (Autenticación)";
|
||||
"Connection error (AUTH)" = "Error de conexión (Autenticación)";
|
||||
|
||||
/* chat list item title (it should not be shown */
|
||||
"connection established" = "conexión establecida";
|
||||
@@ -979,7 +970,7 @@
|
||||
"Connection terminated" = "Conexión finalizada";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connection timeout" = "Tiempo de conexión expirado";
|
||||
"Connection timeout" = "Tiempo de conexión agotado";
|
||||
|
||||
/* connection information */
|
||||
"connection:%@" = "conexión: % @";
|
||||
@@ -1023,7 +1014,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Continuar";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Copiar";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1167,6 +1158,9 @@
|
||||
/* time unit */
|
||||
"days" = "días";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Informe debug";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Descentralizada";
|
||||
|
||||
@@ -1800,7 +1794,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Error: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Error: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2101,7 +2096,7 @@
|
||||
"ICE servers (one per line)" = "Servidores ICE (uno por línea)";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"If you can't meet in person, show QR code in a video call, or share the link." = "Si no puedes reunirte en persona, muestra el código QR por videollamada, o comparte el enlace.";
|
||||
"If you can't meet in person, show QR code in a video call, or share the link." = "Si no puedes reunirte en persona, muestra el código QR por videollamada o comparte el enlace.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"If you enter this passcode when opening the app, all app data will be irreversibly removed!" = "¡Si introduces este código al abrir la aplicación, todos los datos de la misma se eliminarán de forma irreversible!";
|
||||
@@ -2496,6 +2491,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Borrador de mensaje";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Información cola de mensajes";
|
||||
|
||||
/* chat feature */
|
||||
"Message reactions" = "Reacciones a mensajes";
|
||||
|
||||
@@ -2766,7 +2764,7 @@
|
||||
"on" = "Activado";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"One-time invitation link" = "Enlace único de invitación de un uso";
|
||||
"One-time invitation link" = "Enlace de invitación de un solo uso";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Onion hosts will be required for connection. Requires enabling VPN." = "Se requieren hosts .onion para la conexión. Requiere activación de la VPN.";
|
||||
@@ -2850,13 +2848,13 @@
|
||||
"Or paste archive link" = "O pegar enlace del archivo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Or scan QR code" = "O escanear código QR";
|
||||
"Or scan QR code" = "O escanea el código QR";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Or securely share this file link" = "O comparte de forma segura este enlace al archivo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Or show this code" = "O mostrar este código";
|
||||
"Or show this code" = "O muestra este código QR";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Other" = "Otro";
|
||||
@@ -2898,7 +2896,7 @@
|
||||
"Paste link to connect!" = "Pegar enlace para conectar!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Paste the link you received" = "Pegar el enlace recibido";
|
||||
"Paste the link you received" = "Pega el enlace recibido";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"peer-to-peer" = "p2p";
|
||||
@@ -2907,7 +2905,7 @@
|
||||
"People can connect to you only via the links you share." = "Las personas pueden conectarse contigo solo mediante los enlaces que compartes.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Periodically" = "Periódico";
|
||||
"Periodically" = "Periódicamente";
|
||||
|
||||
/* message decrypt error item */
|
||||
"Permanent decryption error" = "Error permanente descifrado";
|
||||
@@ -3063,10 +3061,10 @@
|
||||
"Protect your IP address from the messaging relays chosen by your contacts.\nEnable in *Network & servers* settings." = "Protege tu dirección IP de los servidores de retransmisión elegidos por tus contactos.\nActívalo en ajustes de *Servidores y Redes*.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Protocol timeout" = "Tiempo de espera del protocolo";
|
||||
"Protocol timeout" = "Timeout protocolo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Protocol timeout per KB" = "Límite de espera del protocolo por KB";
|
||||
"Protocol timeout per KB" = "Timeout protocolo por KB";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Push notifications" = "Notificaciones automáticas";
|
||||
@@ -3090,22 +3088,22 @@
|
||||
"Read" = "Leer";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Read more" = "Saber más";
|
||||
"Read more" = "Conoce más";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address)." = "Saber más en el [Manual del Usuario](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address).";
|
||||
"Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address)." = "Conoce más en el [Manual del Usuario](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address).";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode)." = "Saber más en [Guía de Usuario](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode).";
|
||||
"Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode)." = "Conoce más en la [Guía del Usuario](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode).";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends)." = "Saber más en el [Manual del Usuario](https://simplex.chat/docs/guide/readme.html#connect-to-friends).";
|
||||
"Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends)." = "Conoce más en el [Manual del Usuario](https://simplex.chat/docs/guide/readme.html#connect-to-friends).";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme)." = "Saber más en nuestro [repositorio GitHub](https://github.com/simplex-chat/simplex-chat#readme).";
|
||||
"Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme)." = "Conoce más en nuestro [repositorio GitHub](https://github.com/simplex-chat/simplex-chat#readme).";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Read more in our GitHub repository." = "Saber más en nuestro repositorio GitHub.";
|
||||
"Read more in our GitHub repository." = "Conoce más en nuestro repositorio GitHub.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Receipts are disabled" = "Las confirmaciones están desactivadas";
|
||||
@@ -3518,6 +3516,9 @@
|
||||
/* srv error text. */
|
||||
"Server address is incompatible with network settings." = "La dirección del servidor es incompatible con la configuración de la red.";
|
||||
|
||||
/* queue info */
|
||||
"server queue info: %@\n\nlast received msg: %@" = "información cola del servidor: %1$@\n\núltimo mensaje recibido: %2$@";
|
||||
|
||||
/* server test error */
|
||||
"Server requires authorization to create queues, check password" = "El servidor requiere autorización para crear colas, comprueba la contraseña";
|
||||
|
||||
@@ -3591,7 +3592,7 @@
|
||||
"Share link" = "Compartir enlace";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Share this 1-time invite link" = "Compartir este enlace de un uso";
|
||||
"Share this 1-time invite link" = "Comparte este enlace de un solo uso";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Share with contacts" = "Compartir con contactos";
|
||||
@@ -3771,7 +3772,7 @@
|
||||
"Tap to join incognito" = "Pulsa para unirte en modo incógnito";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Tap to paste link" = "Pulsa para pegar enlace";
|
||||
"Tap to paste link" = "Pulsa para pegar el enlacePulsa para pegar enlace";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Tap to scan" = "Pulsa para escanear";
|
||||
@@ -3780,7 +3781,7 @@
|
||||
"Tap to start a new chat" = "Pulsa para iniciar chat nuevo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"TCP connection timeout" = "Tiempo de espera de la conexión TCP agotado";
|
||||
"TCP connection timeout" = "Timeout de la conexión TCP";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"TCP_KEEPCNT" = "TCP_KEEPCNT";
|
||||
@@ -3872,9 +3873,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "El texto pegado no es un enlace SimpleX.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Tema";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Esta configuración afecta a tu perfil actual **%@**.";
|
||||
|
||||
@@ -3942,7 +3940,7 @@
|
||||
"To protect your information, turn on SimpleX Lock.\nYou will be prompted to complete authentication before this feature is enabled." = "Para proteger tu información, activa el Bloqueo SimpleX.\nSe te pedirá que completes la autenticación antes de activar esta función.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To protect your IP address, private routing uses your SMP servers to deliver messages." = "Para proteger tu dirección IP, el enrutamiento privado usa tus servidores SMP para enviar mensajes.";
|
||||
"To protect your IP address, private routing uses your SMP servers to deliver messages." = "Para proteger tu dirección IP, el enrutamiento privado usa tu lista de servidores SMP para enviar mensajes.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record voice message please grant permission to use Microphone." = "Para grabar el mensaje de voz concede permiso para usar el micrófono.";
|
||||
@@ -4029,7 +4027,7 @@
|
||||
"Unknown error" = "Error desconocido";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"unknown relays" = "servidor de retransmisión desconocido";
|
||||
"unknown relays" = "con servidores desconocidos";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Unknown servers!" = "¡Servidores desconocidos!";
|
||||
@@ -4041,7 +4039,7 @@
|
||||
"Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." = "A menos que utilices la interfaz de llamadas de iOS, activa el modo No molestar para evitar interrupciones.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"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." = "A menos que tu contacto haya eliminado la conexión o\nque este enlace ya se haya usado, podría ser un error. Por favor, notifícalo.\nPara conectarte, pide a tu contacto que cree otro enlace de conexión y comprueba que tienes buena conexión de red.";
|
||||
"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." = "A menos que tu contacto haya eliminado la conexión o el enlace haya sido usado, podría ser un error. Por favor, notifícalo.\nPara conectarte pide a tu contacto que cree otro enlace y comprueba la conexión de red.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Unlink" = "Desenlazar";
|
||||
@@ -4059,7 +4057,7 @@
|
||||
"Unmute" = "Activar audio";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"unprotected" = "desprotegido";
|
||||
"unprotected" = "con IP desprotegida";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Unread" = "No leído";
|
||||
@@ -4131,10 +4129,10 @@
|
||||
"Use only local notifications?" = "¿Usar sólo notificaciones locales?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Use private routing with unknown servers when IP address is not protected." = "Usar enrutamiento privado con servidores desconocidos cuando la dirección IP no está protegida.";
|
||||
"Use private routing with unknown servers when IP address is not protected." = "Usar enrutamiento privado con servidores desconocidos cuando tu dirección IP no está protegida.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Use private routing with unknown servers." = "Usar enrutamiento privado con servidores desconocidos.";
|
||||
"Use private routing with unknown servers." = "Usar enrutamiento privado con servidores de retransmisión desconocidos.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Use server" = "Usar servidor";
|
||||
@@ -4416,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.";
|
||||
@@ -4524,7 +4522,7 @@
|
||||
"You will be connected when your contact's device is online, please wait or check later!" = "Te conectarás cuando el dispositivo del contacto esté en línea, por favor espera o compruébalo más tarde.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You will be required to authenticate when you start or resume the app after 30 seconds in background." = "Se te pedirá identificarte cuándo inicies o continues usando la aplicación tras 30 segundos en segundo plano.";
|
||||
"You will be required to authenticate when you start or resume the app after 30 seconds in background." = "Se te pedirá autenticarte cuando inicies la aplicación o sigas usándola tras 30 segundos en segundo plano.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You will connect to all group members." = "Te conectarás con todos los miembros del grupo.";
|
||||
@@ -4596,7 +4594,7 @@
|
||||
"Your profile **%@** will be shared." = "Tu perfil **%@** será compartido.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your profile is stored on your device and shared only with your contacts.\nSimpleX servers cannot see your profile." = "Tu perfil se almacena en tu dispositivo y sólo se comparte con tus contactos.\nLos servidores de SimpleX no pueden ver tu perfil.";
|
||||
"Your profile is stored on your device and shared only with your contacts.\nSimpleX servers cannot see your profile." = "Tu perfil es almacenado en tu dispositivo y solamente se comparte con tus contactos.\nLos servidores SimpleX no pueden ver tu perfil.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your profile, contacts and delivered messages are stored on your device." = "Tu perfil, contactos y mensajes se almacenan en tu dispositivo.";
|
||||
|
||||
@@ -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!";
|
||||
|
||||
@@ -280,9 +277,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "edellä, valitse sitten:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Korostusväri";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Hyväksy";
|
||||
@@ -309,7 +303,7 @@
|
||||
"Add profile" = "Lisää profiili";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Lisää palvelin…";
|
||||
"Add server" = "Lisää palvelin";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Lisää palvelimia skannaamalla QR-koodeja.";
|
||||
@@ -663,9 +657,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "värillinen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Värit";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Vertaa tiedostoa";
|
||||
|
||||
@@ -795,7 +786,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Jatka";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Kopioi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1434,7 +1425,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Virhe: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Virhe: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -3056,9 +3048,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The servers for new connections of your current chat profile **%@**." = "Palvelimet nykyisen keskusteluprofiilisi uusille yhteyksille **%@**.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Teema";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Nämä asetukset koskevat nykyistä profiiliasi **%@**.";
|
||||
|
||||
@@ -3405,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é";
|
||||
|
||||
@@ -337,9 +334,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "ci-dessus, puis choisissez :";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Couleur principale";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Accepter";
|
||||
@@ -369,7 +363,7 @@
|
||||
"Add profile" = "Ajouter un profil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Ajouter un serveur…";
|
||||
"Add server" = "Ajouter un serveur";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Ajoutez des serveurs en scannant des codes QR.";
|
||||
@@ -840,9 +834,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "coloré";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Couleurs";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Comparer le fichier";
|
||||
|
||||
@@ -1023,7 +1014,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Continuer";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Copier";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1167,6 +1158,9 @@
|
||||
/* time unit */
|
||||
"days" = "jours";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Livraison de débogage";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Décentralisé";
|
||||
|
||||
@@ -1800,7 +1794,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Erreur : ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Erreur : %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2496,6 +2491,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Brouillon de message";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Informations sur la file d'attente des messages";
|
||||
|
||||
/* chat feature */
|
||||
"Message reactions" = "Réactions aux messages";
|
||||
|
||||
@@ -3518,6 +3516,9 @@
|
||||
/* srv error text. */
|
||||
"Server address is incompatible with network settings." = "L'adresse du serveur est incompatible avec les paramètres du réseau.";
|
||||
|
||||
/* queue info */
|
||||
"server queue info: %@\n\nlast received msg: %@" = "info sur la file d'attente du serveur : %1$@\n\ndernier message reçu : %2$@";
|
||||
|
||||
/* server test error */
|
||||
"Server requires authorization to create queues, check password" = "Le serveur requiert une autorisation pour créer des files d'attente, vérifiez le mot de passe";
|
||||
|
||||
@@ -3872,9 +3873,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Le texte collé n'est pas un lien SimpleX.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Thème";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Ces paramètres s'appliquent à votre profil actuel **%@**.";
|
||||
|
||||
@@ -4416,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.";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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";
|
||||
|
||||
@@ -338,7 +335,7 @@
|
||||
"above, then choose:" = "sopra, quindi scegli:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Colore principale";
|
||||
"Accent" = "Principale";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
@@ -356,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.";
|
||||
|
||||
@@ -369,7 +372,7 @@
|
||||
"Add profile" = "Aggiungi profilo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Aggiungi server…";
|
||||
"Add server" = "Aggiungi server";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Aggiungi server scansionando codici QR.";
|
||||
@@ -380,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";
|
||||
|
||||
@@ -401,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 %@…";
|
||||
|
||||
@@ -416,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.";
|
||||
|
||||
@@ -431,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.";
|
||||
|
||||
@@ -557,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";
|
||||
|
||||
@@ -566,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";
|
||||
|
||||
@@ -608,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";
|
||||
|
||||
@@ -629,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";
|
||||
|
||||
@@ -719,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";
|
||||
|
||||
@@ -777,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";
|
||||
|
||||
@@ -804,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";
|
||||
|
||||
@@ -822,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";
|
||||
|
||||
@@ -838,10 +889,10 @@
|
||||
"Clear verification" = "Annulla la verifica";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "colorato";
|
||||
"Color mode" = "Modalità di colore";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Colori";
|
||||
"colored" = "colorato";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Confronta file";
|
||||
@@ -852,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";
|
||||
|
||||
@@ -921,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)";
|
||||
|
||||
@@ -981,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$@";
|
||||
|
||||
@@ -1023,9 +1092,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Continua";
|
||||
|
||||
/* chat item action */
|
||||
/* 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%@";
|
||||
|
||||
@@ -1071,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";
|
||||
|
||||
@@ -1095,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 %@.";
|
||||
|
||||
@@ -1104,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";
|
||||
|
||||
@@ -1167,12 +1251,18 @@
|
||||
/* time unit */
|
||||
"days" = "giorni";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Debug della consegna";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Decentralizzato";
|
||||
|
||||
/* message decrypt error item */
|
||||
"Decryption error" = "Errore di decifrazione";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"decryption errors" = "errori di decifrazione";
|
||||
|
||||
/* pref value */
|
||||
"default (%@)" = "predefinito (%@)";
|
||||
|
||||
@@ -1299,6 +1389,9 @@
|
||||
/* deleted chat item */
|
||||
"deleted" = "eliminato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Deleted" = "Eliminato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Deleted at" = "Eliminato il";
|
||||
|
||||
@@ -1311,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";
|
||||
|
||||
@@ -1335,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";
|
||||
|
||||
@@ -1437,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";
|
||||
|
||||
@@ -1455,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";
|
||||
|
||||
@@ -1713,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";
|
||||
|
||||
@@ -1728,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 %@";
|
||||
|
||||
@@ -1800,7 +1926,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Errore: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Errore: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1809,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.";
|
||||
|
||||
@@ -1821,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.";
|
||||
|
||||
@@ -1848,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.";
|
||||
|
||||
@@ -1962,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";
|
||||
|
||||
@@ -2139,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";
|
||||
|
||||
@@ -2160,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";
|
||||
|
||||
@@ -2223,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";
|
||||
|
||||
@@ -2475,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.";
|
||||
|
||||
@@ -2484,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";
|
||||
|
||||
@@ -2496,6 +2668,15 @@
|
||||
/* 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";
|
||||
|
||||
/* chat feature */
|
||||
"Message reactions" = "Reazioni ai messaggi";
|
||||
|
||||
@@ -2517,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";
|
||||
|
||||
@@ -2532,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.";
|
||||
|
||||
@@ -2697,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";
|
||||
|
||||
@@ -2709,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";
|
||||
|
||||
@@ -2834,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";
|
||||
|
||||
@@ -2858,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";
|
||||
|
||||
@@ -2903,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.";
|
||||
|
||||
@@ -2924,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.";
|
||||
|
||||
@@ -2981,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";
|
||||
|
||||
@@ -2991,7 +3208,7 @@
|
||||
"Private filenames" = "Nomi di file privati";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Private message routing" = "Instradamento privato messaggi";
|
||||
"Private message routing" = "Instradamento privato dei messaggi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Private message routing 🚀" = "Instradamento privato dei messaggi 🚀";
|
||||
@@ -3020,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.";
|
||||
|
||||
@@ -3068,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";
|
||||
|
||||
@@ -3110,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…";
|
||||
|
||||
@@ -3128,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.";
|
||||
|
||||
@@ -3146,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?";
|
||||
|
||||
@@ -3182,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";
|
||||
|
||||
@@ -3239,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";
|
||||
|
||||
@@ -3359,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";
|
||||
|
||||
@@ -3386,6 +3660,9 @@
|
||||
/* network option */
|
||||
"sec" = "sec";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Secondary" = "Secondario";
|
||||
|
||||
/* time unit */
|
||||
"seconds" = "secondi";
|
||||
|
||||
@@ -3395,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";
|
||||
|
||||
@@ -3407,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";
|
||||
|
||||
@@ -3440,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";
|
||||
|
||||
@@ -3506,18 +3792,39 @@
|
||||
/* 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.";
|
||||
|
||||
/* queue info */
|
||||
"server queue info: %@\n\nlast received msg: %@" = "info coda server: %1$@\n\nultimo msg ricevuto: %2$@";
|
||||
|
||||
/* server test error */
|
||||
"Server requires authorization to create queues, check password" = "Il server richiede l'autorizzazione di creare code, controlla la password";
|
||||
|
||||
@@ -3527,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";
|
||||
|
||||
@@ -3542,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";
|
||||
|
||||
@@ -3620,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";
|
||||
|
||||
@@ -3665,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";
|
||||
|
||||
@@ -3674,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";
|
||||
|
||||
@@ -3698,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";
|
||||
|
||||
@@ -3743,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";
|
||||
|
||||
@@ -3791,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 %@.";
|
||||
|
||||
@@ -3873,7 +4219,7 @@
|
||||
"The text you pasted is not a SimpleX link." = "Il testo che hai incollato non è un link SimpleX.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Tema";
|
||||
"Themes" = "Temi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Queste impostazioni sono per il tuo profilo attuale **%@**.";
|
||||
@@ -3917,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:";
|
||||
|
||||
@@ -3959,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: %@).";
|
||||
|
||||
@@ -4097,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";
|
||||
|
||||
@@ -4148,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.";
|
||||
|
||||
@@ -4256,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!";
|
||||
|
||||
@@ -4328,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";
|
||||
|
||||
@@ -4388,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";
|
||||
|
||||
@@ -4416,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" = "%@ アップロード済";
|
||||
|
||||
@@ -331,9 +328,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "上で選んでください:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "アクセントカラー";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "承諾";
|
||||
@@ -360,7 +354,7 @@
|
||||
"Add profile" = "プロフィールを追加";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "サーバを追加…";
|
||||
"Add server" = "サーバを追加";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "QRコードでサーバを追加する。";
|
||||
@@ -735,9 +729,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "色付き";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "色";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "ファイルを比較";
|
||||
|
||||
@@ -867,7 +858,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "続ける";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "コピー";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1509,7 +1500,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "エラー : ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "エラー : %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -3113,9 +3105,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The servers for new connections of your current chat profile **%@**." = "現在のチャットプロフィールの新しい接続のサーバ **%@**。";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "テーマ";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "これらの設定は現在のプロファイル **%@** 用です。";
|
||||
|
||||
@@ -3459,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";
|
||||
|
||||
@@ -337,9 +334,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "hier boven, kies dan:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Accent kleur";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Accepteer";
|
||||
@@ -369,7 +363,7 @@
|
||||
"Add profile" = "Profiel toevoegen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Server toevoegen…";
|
||||
"Add server" = "Server toevoegen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Servers toevoegen door QR-codes te scannen.";
|
||||
@@ -840,9 +834,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "gekleurd";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Kleuren";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Bestand vergelijken";
|
||||
|
||||
@@ -1023,7 +1014,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Doorgaan";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Kopiëren";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1167,6 +1158,9 @@
|
||||
/* time unit */
|
||||
"days" = "dagen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Foutopsporing bezorging";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Gedecentraliseerd";
|
||||
|
||||
@@ -1800,7 +1794,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Fout: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Fout: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2496,6 +2491,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Concept bericht";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Informatie over berichtenwachtrij";
|
||||
|
||||
/* chat feature */
|
||||
"Message reactions" = "Reacties op berichten";
|
||||
|
||||
@@ -3518,6 +3516,9 @@
|
||||
/* srv error text. */
|
||||
"Server address is incompatible with network settings." = "Serveradres is niet compatibel met netwerkinstellingen.";
|
||||
|
||||
/* queue info */
|
||||
"server queue info: %@\n\nlast received msg: %@" = "informatie over serverwachtrij: %1$@\n\nlaatst ontvangen bericht: %2$@";
|
||||
|
||||
/* server test error */
|
||||
"Server requires authorization to create queues, check password" = "Server vereist autorisatie om wachtrijen te maken, controleer wachtwoord";
|
||||
|
||||
@@ -3872,9 +3873,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "De tekst die u hebt geplakt is geen SimpleX link.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Thema";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Deze instellingen zijn voor uw huidige profiel **%@**.";
|
||||
|
||||
@@ -4416,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";
|
||||
|
||||
@@ -337,9 +334,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "powyżej, a następnie wybierz:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Kolor akcentu";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Akceptuj";
|
||||
@@ -369,7 +363,7 @@
|
||||
"Add profile" = "Dodaj profil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Dodaj serwer…";
|
||||
"Add server" = "Dodaj serwer";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Dodaj serwery, skanując kody QR.";
|
||||
@@ -840,9 +834,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "kolorowy";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Kolory";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Porównaj plik";
|
||||
|
||||
@@ -1023,7 +1014,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Kontynuuj";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Kopiuj";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1167,6 +1158,9 @@
|
||||
/* time unit */
|
||||
"days" = "dni";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Dostarczenie debugowania";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Zdecentralizowane";
|
||||
|
||||
@@ -1800,7 +1794,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Błąd: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Błąd: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2496,6 +2491,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Wersja robocza wiadomości";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Informacje kolejki wiadomości";
|
||||
|
||||
/* chat feature */
|
||||
"Message reactions" = "Reakcje wiadomości";
|
||||
|
||||
@@ -3518,6 +3516,9 @@
|
||||
/* srv error text. */
|
||||
"Server address is incompatible with network settings." = "Adres serwera jest niekompatybilny z ustawieniami sieciowymi.";
|
||||
|
||||
/* queue info */
|
||||
"server queue info: %@\n\nlast received msg: %@" = "Informacje kolejki serwera: %1$@\n\nostatnia otrzymana wiadomość: %2$@";
|
||||
|
||||
/* server test error */
|
||||
"Server requires authorization to create queues, check password" = "Serwer wymaga autoryzacji do tworzenia kolejek, sprawdź hasło";
|
||||
|
||||
@@ -3872,9 +3873,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Tekst, który wkleiłeś nie jest linkiem SimpleX.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Motyw";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Te ustawienia dotyczą Twojego bieżącego profilu **%@**.";
|
||||
|
||||
@@ -4416,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" = "%@ загружено";
|
||||
|
||||
@@ -337,9 +334,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "наверху, затем выберите:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Основной цвет";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Принять";
|
||||
@@ -369,7 +363,7 @@
|
||||
"Add profile" = "Добавить профиль";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Добавить сервер…";
|
||||
"Add server" = "Добавить сервер";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Добавить серверы через QR код.";
|
||||
@@ -840,9 +834,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "цвет";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Цвета";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Сравнение файла";
|
||||
|
||||
@@ -1023,7 +1014,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Продолжить";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Скопировать";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1800,7 +1791,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Ошибка: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Ошибка: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -3872,9 +3864,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Вставленный текст не является SimpleX-ссылкой.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Тема";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Установки для Вашего активного профиля **%@**.";
|
||||
|
||||
@@ -4416,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!" = "%@ อยากเชื่อมต่อ!";
|
||||
|
||||
@@ -259,9 +256,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "ด้านบน จากนั้นเลือก:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "สีเน้น";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "รับ";
|
||||
@@ -285,7 +279,7 @@
|
||||
"Add profile" = "เพิ่มโปรไฟล์";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "เพิ่มเซิร์ฟเวอร์…";
|
||||
"Add server" = "เพิ่มเซิร์ฟเวอร์";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "เพิ่มเซิร์ฟเวอร์โดยการสแกนรหัสคิวอาร์โค้ด";
|
||||
@@ -639,9 +633,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "มีสี";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "สี";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "เปรียบเทียบไฟล์";
|
||||
|
||||
@@ -765,7 +756,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "ดำเนินการต่อ";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "คัดลอก";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1386,7 +1377,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "ผิดพลาด: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "ข้อผิดพลาด: % @";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2975,9 +2967,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The servers for new connections of your current chat profile **%@**." = "เซิร์ฟเวอร์สำหรับการเชื่อมต่อใหม่ของโปรไฟล์การแชทปัจจุบันของคุณ **%@**";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "ธีม";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "การตั้งค่าเหล่านี้ใช้สำหรับโปรไฟล์ปัจจุบันของคุณ **%@**";
|
||||
|
||||
@@ -3312,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";
|
||||
|
||||
@@ -337,9 +334,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "yukarı çıkın, ardından seçin:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Vurgu rengi";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Kabul et";
|
||||
@@ -369,7 +363,7 @@
|
||||
"Add profile" = "Profil ekle";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Sunucu ekle…";
|
||||
"Add server" = "Sunucu ekle";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Karekod taratarak sunucuları ekleyin.";
|
||||
@@ -840,9 +834,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "renklendirilmiş";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Renkler";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Dosya karşılaştır";
|
||||
|
||||
@@ -1023,7 +1014,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Devam et";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Kopyala";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1167,6 +1158,9 @@
|
||||
/* time unit */
|
||||
"days" = "gün";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Hata ayıklama teslimatı";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Merkezi Olmayan";
|
||||
|
||||
@@ -1800,7 +1794,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Hata: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Hata: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2496,6 +2491,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Mesaj taslağı";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Mesaj kuyruğu bilgisi";
|
||||
|
||||
/* chat feature */
|
||||
"Message reactions" = "Mesaj tepkileri";
|
||||
|
||||
@@ -3518,6 +3516,9 @@
|
||||
/* srv error text. */
|
||||
"Server address is incompatible with network settings." = "Sunucu adresi ağ ayarlarıyla uyumlu değil.";
|
||||
|
||||
/* queue info */
|
||||
"server queue info: %@\n\nlast received msg: %@" = "sunucu kuyruk bilgisi: %1$@\n\nson alınan msj: %2$@";
|
||||
|
||||
/* server test error */
|
||||
"Server requires authorization to create queues, check password" = "Sunucunun sıra oluşturması için yetki gereklidir, şifreyi kontrol edin";
|
||||
|
||||
@@ -3872,9 +3873,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Yapıştırdığın metin bir SimpleX bağlantısı değildir.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Tema";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Bu ayarlar mevcut profiliniz **%@** içindir.";
|
||||
|
||||
@@ -4416,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" = "%@ завантажено";
|
||||
|
||||
@@ -337,9 +334,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "вище, а потім обирайте:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Акцентний колір";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Прийняти";
|
||||
@@ -369,7 +363,7 @@
|
||||
"Add profile" = "Додати профіль";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Додати сервер…";
|
||||
"Add server" = "Додати сервер";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Додайте сервери, відсканувавши QR-код.";
|
||||
@@ -840,9 +834,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "кольоровий";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Кольори";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Порівняти файл";
|
||||
|
||||
@@ -1023,7 +1014,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Продовжуйте";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Копіювати";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1167,6 +1158,9 @@
|
||||
/* time unit */
|
||||
"days" = "днів";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Доставка налагодження";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Децентралізований";
|
||||
|
||||
@@ -1800,7 +1794,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Помилка: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Помилка: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2496,6 +2491,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Чернетка повідомлення";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Інформація про чергу повідомлень";
|
||||
|
||||
/* chat feature */
|
||||
"Message reactions" = "Реакції на повідомлення";
|
||||
|
||||
@@ -3518,6 +3516,9 @@
|
||||
/* srv error text. */
|
||||
"Server address is incompatible with network settings." = "Адреса сервера несумісна з налаштуваннями мережі.";
|
||||
|
||||
/* queue info */
|
||||
"server queue info: %@\n\nlast received msg: %@" = "інформація про чергу на сервері: %1$@\n\nостаннє отримане повідомлення: %2$@";
|
||||
|
||||
/* server test error */
|
||||
"Server requires authorization to create queues, check password" = "Сервер вимагає авторизації для створення черг, перевірте пароль";
|
||||
|
||||
@@ -3872,9 +3873,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Текст, який ви вставили, не є посиланням SimpleX.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Тема";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Ці налаштування стосуються вашого поточного профілю **%@**.";
|
||||
|
||||
@@ -4416,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!" = "%@ 要连接!";
|
||||
|
||||
@@ -301,9 +298,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "上面,然后选择:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "色调";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "接受";
|
||||
@@ -333,7 +327,7 @@
|
||||
"Add profile" = "添加个人资料";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "添加服务器…";
|
||||
"Add server" = "添加服务器";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "扫描二维码来添加服务器。";
|
||||
@@ -786,9 +780,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "彩色";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "颜色";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "对比文件";
|
||||
|
||||
@@ -951,7 +942,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "继续";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "复制";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1689,7 +1680,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "错误: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "错误: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -3644,9 +3636,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "您粘贴的文本不是 SimpleX 链接。";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "主题";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "这些设置适用于您当前的配置文件 **%@**。";
|
||||
|
||||
@@ -4122,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." = "您可以通过设置来设置锁屏通知预览。";
|
||||
|
||||
@@ -105,6 +105,7 @@ kotlin {
|
||||
implementation("uk.co.caprica:vlcj:4.8.2")
|
||||
implementation("com.github.NanoHttpd.nanohttpd:nanohttpd:efb2ebf85a")
|
||||
implementation("com.github.NanoHttpd.nanohttpd:nanohttpd-websocket:efb2ebf85a")
|
||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
}
|
||||
}
|
||||
val desktopTest by getting
|
||||
|
||||
+2
-2
@@ -6,8 +6,6 @@ import android.net.LocalServerSocket
|
||||
import android.util.Log
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import chat.simplex.common.*
|
||||
import chat.simplex.common.platform.*
|
||||
import java.io.*
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
@@ -24,6 +22,8 @@ var isAppOnForeground: Boolean = false
|
||||
@Suppress("ConstantLocale")
|
||||
val defaultLocale: Locale = Locale.getDefault()
|
||||
|
||||
actual fun isAppVisibleAndFocused(): Boolean = isAppOnForeground
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
lateinit var androidAppContext: Context
|
||||
var mainActivity: WeakReference<FragmentActivity> = WeakReference(null)
|
||||
|
||||
+2
@@ -29,6 +29,8 @@ actual val remoteHostsDir: File = File(tmpDir.absolutePath + File.separator + "r
|
||||
|
||||
actual fun desktopOpenDatabaseDir() {}
|
||||
|
||||
actual fun desktopOpenDir(dir: File) {}
|
||||
|
||||
@Composable
|
||||
actual fun rememberFileChooserLauncher(getContent: Boolean, rememberedValue: Any?, onResult: (URI?) -> Unit): FileChooserLauncher {
|
||||
val launcher = rememberLauncherForActivityResult(
|
||||
|
||||
+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