mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3bd47130e7 | |||
| 12c1b348fe | |||
| ecc8a42b66 | |||
| cd5bb4c146 | |||
| 64f4bcc6fc | |||
| 060d3dd4d4 | |||
| cea3aad0d4 | |||
| f43a2d070b | |||
| 69ad380245 | |||
| 3133d01690 | |||
| 69da8b6345 | |||
| f053447f5f | |||
| a57a2c277d | |||
| 670bf34ff5 | |||
| 3e873fcb32 | |||
| 387faa0c27 | |||
| 23f24b1677 | |||
| 17526fa385 | |||
| 70204e071d | |||
| b348979b32 | |||
| aa990da17c | |||
| 71ad8f2fd1 | |||
| 2dff94cbb4 | |||
| a73abfe642 | |||
| 859fa0bc22 | |||
| 41c4f13939 | |||
| a48c82f4a1 | |||
| f84ac713d7 | |||
| f41c04735b | |||
| a8da9b9cd9 | |||
| 64a0f509f7 | |||
| c4f8a50f0d | |||
| 93a4c0854e | |||
| 49c29c74df | |||
| e6ee5df158 | |||
| f4be0278b6 | |||
| a9d2535292 | |||
| 3e623684bc | |||
| fd90b47194 | |||
| acd3467d10 | |||
| 71ce598355 | |||
| 63393eaf0b | |||
| f90de83215 | |||
| 1c10209a31 | |||
| 5d7abf31ce | |||
| 44c0861fe4 | |||
| 1e6dc8002c |
@@ -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? {
|
||||
@@ -379,8 +403,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) {
|
||||
@@ -525,13 +549,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 +576,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 +694,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 {
|
||||
@@ -702,7 +732,7 @@ final class ChatModel: ObservableObject {
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
return UnreadChatItemCounts(totalBelow: totalBelow, unreadBelow: unreadBelow)
|
||||
return UnreadChatItemCounts(isNearBottom: totalBelow < 16, unreadBelow: unreadBelow)
|
||||
}
|
||||
|
||||
func topItemInView(itemsInView: Set<String>) -> ChatItem? {
|
||||
@@ -740,7 +770,7 @@ struct NTFContactRequest {
|
||||
}
|
||||
|
||||
struct UnreadChatItemCounts: Equatable {
|
||||
var totalBelow: Int
|
||||
var isNearBottom: Bool
|
||||
var unreadBelow: Int
|
||||
}
|
||||
|
||||
|
||||
@@ -1091,23 +1091,55 @@ 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(.PROXY(proxyErr)))):
|
||||
return proxyErrorAlert(proxyErr)
|
||||
case let .chatCmdError(_, .errorAgent(.PROXY(_, _, .protocolError(.PROXY(proxyErr))))):
|
||||
return proxyErrorAlert(proxyErr)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
private func proxyErrorAlert(_ proxyErr: ProxyError) -> ErrorAlert? {
|
||||
switch proxyErr {
|
||||
case .BROKER(brokerErr: .TIMEOUT):
|
||||
return ErrorAlert(title: "Private routing error", message: "Please try later.")
|
||||
case .BROKER(brokerErr: .NETWORK):
|
||||
return ErrorAlert(title: "Private routing error", message: "Please try later.")
|
||||
case .NO_SESSION:
|
||||
return ErrorAlert(title: "Private routing error", message: "Please try later.")
|
||||
case .BROKER(brokerErr: .HOST):
|
||||
return ErrorAlert(title: "Private routing error", message: "Server address is incompatible with network settings.")
|
||||
case .BROKER(brokerErr: .TRANSPORT(.version)):
|
||||
return ErrorAlert(title: "Private routing error", message: "Server version is incompatible with network settings.")
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func networkErrorAlert(_ r: ChatResponse) -> Alert? {
|
||||
if let alert = getNetworkErrorAlert(r) {
|
||||
return mkAlert(title: alert.title, message: alert.message)
|
||||
} 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: [])
|
||||
@@ -1207,7 +1239,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))")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -70,7 +70,6 @@ struct CIGroupInvitationView: View {
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(chatItemFrameColor(chatItem, theme))
|
||||
.cornerRadius(18)
|
||||
.textSelection(.disabled)
|
||||
.onPreferenceChange(DetermineWidth.Key.self) { frameWidth = $0 }
|
||||
.onChange(of: inProgress) { inProgress in
|
||||
|
||||
@@ -22,7 +22,6 @@ struct CIInvalidJSONView: View {
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
.cornerRadius(18)
|
||||
.textSelection(.disabled)
|
||||
.onTapGesture { showJSON = true }
|
||||
.appSheet(isPresented: $showJSON) {
|
||||
|
||||
@@ -15,8 +15,7 @@ struct CILinkView: View {
|
||||
|
||||
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()
|
||||
|
||||
@@ -132,7 +132,6 @@ struct CIRcvDecryptionError: View {
|
||||
.onTapGesture(perform: { onClick() })
|
||||
.padding(.vertical, 6)
|
||||
.background(Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
.cornerRadius(18)
|
||||
.textSelection(.disabled)
|
||||
}
|
||||
|
||||
@@ -152,7 +151,6 @@ struct CIRcvDecryptionError: View {
|
||||
.onTapGesture(perform: { onClick() })
|
||||
.padding(.vertical, 6)
|
||||
.background(Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
.cornerRadius(18)
|
||||
.textSelection(.disabled)
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ struct DeletedItemView: View {
|
||||
.padding(.leading, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(chatItemFrameColor(chatItem, theme))
|
||||
.cornerRadius(18)
|
||||
.textSelection(.disabled)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,6 @@ struct FramedItemView: View {
|
||||
}
|
||||
}
|
||||
.background(chatItemFrameColorMaybeImageOrVideo(chatItem, theme))
|
||||
.cornerRadius(18)
|
||||
.onPreferenceChange(DetermineWidth.Key.self) { msgWidth = $0 }
|
||||
|
||||
if let (title, text) = chatItem.meta.itemStatus.statusInfo {
|
||||
@@ -189,8 +188,7 @@ struct FramedItemView: View {
|
||||
let v = ZStack(alignment: .topTrailing) {
|
||||
switch (qi.content) {
|
||||
case let .image(_, image):
|
||||
if let data = Data(base64Encoded: dropImagePrefix(image)),
|
||||
let uiImage = UIImage(data: data) {
|
||||
if let uiImage = UIImage(base64Encoded: image) {
|
||||
ciQuotedMsgView(qi)
|
||||
.padding(.trailing, 70).frame(minWidth: msgWidth, alignment: .leading)
|
||||
Image(uiImage: uiImage)
|
||||
@@ -202,8 +200,7 @@ struct FramedItemView: View {
|
||||
ciQuotedMsgView(qi)
|
||||
}
|
||||
case let .video(_, image, _):
|
||||
if let data = Data(base64Encoded: dropImagePrefix(image)),
|
||||
let uiImage = UIImage(data: data) {
|
||||
if let uiImage = UIImage(base64Encoded: image) {
|
||||
ciQuotedMsgView(qi)
|
||||
.padding(.trailing, 70).frame(minWidth: msgWidth, alignment: .leading)
|
||||
Image(uiImage: uiImage)
|
||||
|
||||
@@ -70,7 +70,6 @@ struct CIMsgError: View {
|
||||
.padding(.leading, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
.cornerRadius(18)
|
||||
.textSelection(.disabled)
|
||||
.onTapGesture(perform: onTap)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ struct MarkedDeletedItemView: View {
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(chatItemFrameColor(chatItem, theme))
|
||||
.cornerRadius(18)
|
||||
.textSelection(.disabled)
|
||||
}
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ struct ChatItemInfoView: View {
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(chatItemFrameColor(ci, theme))
|
||||
.cornerRadius(18)
|
||||
.modifier(ChatItemClipped())
|
||||
.contextMenu {
|
||||
if itemVersion.msgContent.text != "" {
|
||||
Button {
|
||||
@@ -302,7 +302,7 @@ struct ChatItemInfoView: View {
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(quotedMsgFrameColor(qi, theme))
|
||||
.cornerRadius(18)
|
||||
.modifier(ChatItemClipped())
|
||||
.contextMenu {
|
||||
if qi.text != "" {
|
||||
Button {
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,9 +68,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
|
||||
|
||||
@@ -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
|
||||
@@ -121,7 +120,8 @@ struct ChatView: View {
|
||||
chatModel.chatItemStatuses = [:]
|
||||
chatModel.reversedChatItems = []
|
||||
chatModel.groupMembers = []
|
||||
membersLoaded = false
|
||||
chatModel.groupMembersIndexes.removeAll()
|
||||
chatModel.membersLoaded = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,7 +163,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 +249,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.
|
||||
@@ -410,7 +399,7 @@ struct ChatView: View {
|
||||
|
||||
init() {
|
||||
unreadChatItemCounts = UnreadChatItemCounts(
|
||||
totalBelow: .zero,
|
||||
isNearBottom: true,
|
||||
unreadBelow: .zero
|
||||
)
|
||||
events
|
||||
@@ -425,9 +414,9 @@ struct ChatView: View {
|
||||
itemsInView
|
||||
}
|
||||
}
|
||||
.throttle(for: .seconds(0.2), scheduler: DispatchQueue.main, latest: true)
|
||||
.map { ChatModel.shared.unreadChatItemCounts(itemsInView: $0) }
|
||||
.removeDuplicates()
|
||||
.throttle(for: .seconds(0.2), scheduler: DispatchQueue.main, latest: true)
|
||||
.assign(to: \.unreadChatItemCounts, on: self)
|
||||
.store(in: &bag)
|
||||
}
|
||||
@@ -475,11 +464,9 @@ 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.totalBelow > 16 {
|
||||
} else if !counts.isNearBottom {
|
||||
circleButton {
|
||||
Image(systemName: "chevron.down")
|
||||
.foregroundColor(theme.colors.primary)
|
||||
@@ -532,7 +519,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")
|
||||
@@ -602,11 +589,9 @@ struct ChatView: View {
|
||||
chat: chat,
|
||||
chatItem: ci,
|
||||
maxWidth: maxWidth,
|
||||
itemWidth: maxWidth,
|
||||
composeState: $composeState,
|
||||
selectedMember: $selectedMember,
|
||||
revealedChatItem: $revealedChatItem,
|
||||
chatView: self
|
||||
revealedChatItem: $revealedChatItem
|
||||
)
|
||||
}
|
||||
|
||||
@@ -614,13 +599,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
|
||||
@@ -698,11 +681,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)
|
||||
}
|
||||
}
|
||||
@@ -754,6 +737,7 @@ struct ChatView: View {
|
||||
playbackState: $playbackState,
|
||||
playbackTime: $playbackTime
|
||||
)
|
||||
.modifier(ChatItemClipped(ci))
|
||||
.contextMenu { menu(ci, range, live: composeState.liveMessage != nil) }
|
||||
.accessibilityLabel("")
|
||||
if ci.content.msgContent != nil && (ci.meta.itemDeleted == nil || revealed) && ci.reactions.count > 0 {
|
||||
@@ -1096,7 +1080,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))")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -69,8 +69,7 @@ struct ComposeLinkView: View {
|
||||
|
||||
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)
|
||||
|
||||
@@ -849,6 +849,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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -141,12 +141,6 @@ struct GroupMemberInfoView: View {
|
||||
} else {
|
||||
infoRow("Role", member.memberRole.text)
|
||||
}
|
||||
|
||||
// TODO invited by - need to get contact by contact id
|
||||
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 {
|
||||
@@ -183,6 +177,10 @@ struct GroupMemberInfoView: View {
|
||||
Section(header: Text("For console").foregroundColor(theme.colors.secondary)) {
|
||||
infoRow("Local name", member.localDisplayName)
|
||||
infoRow("Database ID", "\(member.groupMemberId)")
|
||||
if let conn = member.activeConn {
|
||||
let connLevelDesc = conn.connLevel == 0 ? NSLocalizedString("direct", comment: "connection level description") : String.localizedStringWithFormat(NSLocalizedString("indirect (%d)", comment: "connection level description"), conn.connLevel)
|
||||
infoRow("Connection", connLevelDesc)
|
||||
}
|
||||
Button ("Debug delivery") {
|
||||
Task {
|
||||
do {
|
||||
|
||||
@@ -55,6 +55,7 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
// 1. Style
|
||||
tableView.separatorStyle = .none
|
||||
tableView.transform = .verticalFlip
|
||||
tableView.backgroundColor = .clear
|
||||
|
||||
// 2. Register cells
|
||||
if #available(iOS 16.0, *) {
|
||||
@@ -180,6 +181,7 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
/// Updates content of the cell
|
||||
/// For reference: https://noahgilmore.com/blog/swiftui-self-sizing-cells/
|
||||
func set(content: Hosted, parent: UIViewController) {
|
||||
hostingController.view.backgroundColor = .clear
|
||||
hostingController.rootView = content
|
||||
if let hostingView = hostingController.view {
|
||||
hostingView.invalidateIntrinsicContentSize()
|
||||
|
||||
@@ -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))")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,23 +266,19 @@ struct ChatListView: View {
|
||||
}
|
||||
|
||||
struct SubsStatusIndicator: View {
|
||||
@State private var subs: SMPServerSubs = SMPServerSubs.newSMPServerSubs
|
||||
@State private var sess: ServerSessions = ServerSessions.newServerSessions
|
||||
@State private var serversSummary: PresentedServersSummary?
|
||||
@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: {
|
||||
let subs = serversSummary?.allUsersSMP.smpTotals.subs ?? SMPServerSubs.newSMPServerSubs
|
||||
let sess = serversSummary?.allUsersSMP.smpTotals.sessions ?? ServerSessions.newServerSessions
|
||||
HStack(spacing: 4) {
|
||||
SubscriptionStatusIndicatorView(subs: subs, sess: sess)
|
||||
if showSubscriptionPercentage {
|
||||
@@ -291,34 +287,24 @@ struct SubsStatusIndicator: View {
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
startInitialTimer()
|
||||
startTimer()
|
||||
}
|
||||
.onDisappear {
|
||||
stopTimer()
|
||||
}
|
||||
.sheet(isPresented: $showServersSummary) {
|
||||
ServersSummaryView()
|
||||
ServersSummaryView(serversSummary: $serversSummary)
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
getServersSummary()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func switchToRegularTimer() {
|
||||
timer?.invalidate()
|
||||
timer = Timer.scheduledTimer(withTimeInterval: regularInterval, repeats: true) { _ in
|
||||
getServersSummary()
|
||||
}
|
||||
}
|
||||
|
||||
func stopTimer() {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
@@ -326,8 +312,7 @@ struct SubsStatusIndicator: View {
|
||||
|
||||
private func getServersSummary() {
|
||||
do {
|
||||
let summ = try getAgentServersSummary()
|
||||
(subs, sess) = (summ.allUsersSMP.smpTotals.subs, summ.allUsersSMP.smpTotals.sessions)
|
||||
serversSummary = try getAgentServersSummary()
|
||||
} catch let error {
|
||||
logger.error("getAgentServersSummary error: \(responseError(error))")
|
||||
}
|
||||
|
||||
@@ -11,12 +11,12 @@ import SimpleXChat
|
||||
|
||||
struct ServersSummaryView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@State private var serversSummary: PresentedServersSummary? = nil
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Binding var serversSummary: PresentedServersSummary?
|
||||
@State private var selectedUserCategory: PresentedUserCategory = .allUsers
|
||||
@State private var selectedServerType: PresentedServerType = .smp
|
||||
@State private var selectedSMPServer: String? = nil
|
||||
@State private var selectedXFTPServer: String? = nil
|
||||
@State private var timer: Timer? = nil
|
||||
@State private var alert: SomeAlert?
|
||||
|
||||
@AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false
|
||||
@@ -36,6 +36,7 @@ struct ServersSummaryView: View {
|
||||
viewBody()
|
||||
.navigationTitle("Servers info")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
shareButton()
|
||||
@@ -46,26 +47,10 @@ struct ServersSummaryView: View {
|
||||
if m.users.filter({ u in u.user.activeUser || !u.user.hidden }).count == 1 {
|
||||
selectedUserCategory = .currentUser
|
||||
}
|
||||
getServersSummary()
|
||||
startTimer()
|
||||
}
|
||||
.onDisappear {
|
||||
stopTimer()
|
||||
}
|
||||
.alert(item: $alert) { $0.alert }
|
||||
}
|
||||
|
||||
private func startTimer() {
|
||||
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
|
||||
getServersSummary()
|
||||
}
|
||||
}
|
||||
|
||||
func stopTimer() {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
}
|
||||
|
||||
private func shareButton() -> some View {
|
||||
Button {
|
||||
if let serversSummary = serversSummary {
|
||||
@@ -182,6 +167,8 @@ struct ServersSummaryView: View {
|
||||
}
|
||||
} else {
|
||||
Text("No info, try to reload")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.background(theme.colors.background)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,6 +251,7 @@ struct ServersSummaryView: View {
|
||||
)
|
||||
.navigationBarTitle("SMP server")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
} label: {
|
||||
HStack {
|
||||
Text(serverAddress(srvSumm.smpServer))
|
||||
@@ -332,6 +320,7 @@ struct ServersSummaryView: View {
|
||||
)
|
||||
.navigationBarTitle("XFTP server")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
} label: {
|
||||
HStack {
|
||||
Text(serverAddress(srvSumm.xftpServer))
|
||||
@@ -360,13 +349,12 @@ struct ServersSummaryView: View {
|
||||
Button {
|
||||
alert = SomeAlert(
|
||||
alert: Alert(
|
||||
title: Text("Reset all servers statistics?"),
|
||||
title: Text("Reset all statistics?"),
|
||||
message: Text("Servers statistics will be reset - this cannot be undone!"),
|
||||
primaryButton: .destructive(Text("Reset")) {
|
||||
Task {
|
||||
do {
|
||||
try await resetAgentServersStats()
|
||||
getServersSummary()
|
||||
} catch let error {
|
||||
alert = SomeAlert(
|
||||
alert: mkAlert(
|
||||
@@ -386,14 +374,6 @@ 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 {
|
||||
@@ -422,7 +402,7 @@ struct SubscriptionStatusPercentageView: View {
|
||||
var body: some View {
|
||||
let onionHosts = networkUseOnionHostsGroupDefault.get()
|
||||
let (_, _, _, statusPercent) = subscriptionStatusColorAndPercentage(m.networkInfo.online, onionHosts, subs, sess)
|
||||
Text("\(Int(floor(statusPercent * 100)))%")
|
||||
Text(verbatim: "\(Int(floor(statusPercent * 100)))%")
|
||||
.foregroundColor(.secondary)
|
||||
.font(.caption)
|
||||
}
|
||||
@@ -470,6 +450,7 @@ struct SMPServerSummaryView: View {
|
||||
NavigationLink {
|
||||
ProtocolServersView(serverProtocol: .smp)
|
||||
.navigationTitle("Your SMP servers")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
} label: {
|
||||
Text("Open server settings")
|
||||
}
|
||||
@@ -563,6 +544,7 @@ struct SMPStatsView: View {
|
||||
DetailedSMPStatsView(stats: stats, statsStartedAt: statsStartedAt)
|
||||
.navigationTitle("Detailed statistics")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
} label: {
|
||||
Text("Details")
|
||||
}
|
||||
@@ -590,21 +572,21 @@ struct DetailedSMPStatsView: View {
|
||||
infoRowTwoValues("Sent via proxy", "attempts", stats._sentViaProxy, stats._sentViaProxyAttempts)
|
||||
infoRowTwoValues("Proxied", "attempts", stats._sentProxied, stats._sentProxiedAttempts)
|
||||
Text("Send errors")
|
||||
indentedInfoRow("AUTH", numOrDash(stats._sentAuthErrs))
|
||||
indentedInfoRow("QUOTA", numOrDash(stats._sentQuotaErrs))
|
||||
indentedInfoRow("expired", numOrDash(stats._sentExpiredErrs))
|
||||
indentedInfoRow("other", numOrDash(stats._sentOtherErrs))
|
||||
infoRow(Text(verbatim: "AUTH"), numOrDash(stats._sentAuthErrs)).padding(.leading, 24)
|
||||
infoRow(Text(verbatim: "QUOTA"), numOrDash(stats._sentQuotaErrs)).padding(.leading, 24)
|
||||
infoRow("expired", numOrDash(stats._sentExpiredErrs)).padding(.leading, 24)
|
||||
infoRow("other", numOrDash(stats._sentOtherErrs)).padding(.leading, 24)
|
||||
}
|
||||
Section("Received messages") {
|
||||
infoRow("Received total", numOrDash(stats._recvMsgs))
|
||||
Text("Receive errors")
|
||||
indentedInfoRow("duplicates", numOrDash(stats._recvDuplicates))
|
||||
indentedInfoRow("decryption errors", numOrDash(stats._recvCryptoErrs))
|
||||
indentedInfoRow("other errors", numOrDash(stats._recvErrs))
|
||||
infoRow("duplicates", numOrDash(stats._recvDuplicates)).padding(.leading, 24)
|
||||
infoRow("decryption errors", numOrDash(stats._recvCryptoErrs)).padding(.leading, 24)
|
||||
infoRow("other errors", numOrDash(stats._recvErrs)).padding(.leading, 24)
|
||||
infoRowTwoValues("Acknowledged", "attempts", stats._ackMsgs, stats._ackAttempts)
|
||||
Text("Acknowledgement errors")
|
||||
indentedInfoRow("NO_MSG errors", numOrDash(stats._ackNoMsgErrs))
|
||||
indentedInfoRow("other errors", numOrDash(stats._ackOtherErrs))
|
||||
infoRow(Text(verbatim: "NO_MSG errors"), numOrDash(stats._ackNoMsgErrs)).padding(.leading, 24)
|
||||
infoRow("other errors", numOrDash(stats._ackOtherErrs)).padding(.leading, 24)
|
||||
}
|
||||
Section {
|
||||
infoRow("Created", numOrDash(stats._connCreated))
|
||||
@@ -613,7 +595,7 @@ struct DetailedSMPStatsView: View {
|
||||
infoRowTwoValues("Deleted", "attempts", stats._connDeleted, stats._connDelAttempts)
|
||||
infoRow("Deletion errors", numOrDash(stats._connDelErrs))
|
||||
infoRowTwoValues("Subscribed", "attempts", stats._connSubscribed, stats._connSubAttempts)
|
||||
infoRow("Subscription results ignored", numOrDash(stats._connSubIgnored))
|
||||
infoRow("Subscriptions ignored", numOrDash(stats._connSubIgnored))
|
||||
infoRow("Subscription errors", numOrDash(stats._connSubErrs))
|
||||
} header: {
|
||||
Text("Connections")
|
||||
@@ -626,29 +608,19 @@ struct DetailedSMPStatsView: View {
|
||||
|
||||
private func infoRowTwoValues(_ title: LocalizedStringKey, _ title2: LocalizedStringKey, _ value: Int, _ value2: Int) -> some View {
|
||||
HStack {
|
||||
Text(title) + Text(" / ").font(.caption2) + Text(title2).font(.caption2)
|
||||
Text(title) + Text(verbatim: " / ").font(.caption2) + Text(title2).font(.caption2)
|
||||
Spacer()
|
||||
Group {
|
||||
if value == 0 && value2 == 0 {
|
||||
Text("-")
|
||||
Text(verbatim: "-")
|
||||
} else {
|
||||
Text(numOrDash(value)) + Text(" / ").font(.caption2) + Text(numOrDash(value2)).font(.caption2)
|
||||
Text(numOrDash(value)) + Text(verbatim: " / ").font(.caption2) + Text(numOrDash(value2)).font(.caption2)
|
||||
}
|
||||
}
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
private func indentedInfoRow(_ title: LocalizedStringKey, _ value: String) -> some View {
|
||||
HStack {
|
||||
Text(title)
|
||||
.padding(.leading, 24)
|
||||
Spacer()
|
||||
Text(value)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
struct XFTPServerSummaryView: View {
|
||||
var summary: XFTPServerSummary
|
||||
var statsStartedAt: Date
|
||||
@@ -662,6 +634,7 @@ struct XFTPServerSummaryView: View {
|
||||
NavigationLink {
|
||||
ProtocolServersView(serverProtocol: .xftp)
|
||||
.navigationTitle("Your XFTP servers")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
} label: {
|
||||
Text("Open server settings")
|
||||
}
|
||||
@@ -692,6 +665,7 @@ struct XFTPStatsView: View {
|
||||
DetailedXFTPStatsView(stats: stats, statsStartedAt: statsStartedAt)
|
||||
.navigationTitle("Detailed statistics")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
} label: {
|
||||
Text("Details")
|
||||
}
|
||||
@@ -725,8 +699,8 @@ struct DetailedXFTPStatsView: View {
|
||||
infoRow("Size", prettySize(stats._downloadsSize))
|
||||
infoRowTwoValues("Chunks downloaded", "attempts", stats._downloads, stats._downloadAttempts)
|
||||
Text("Download errors")
|
||||
indentedInfoRow("AUTH", numOrDash(stats._downloadAuthErrs))
|
||||
indentedInfoRow("other", numOrDash(stats._downloadErrs))
|
||||
infoRow(Text(verbatim: "AUTH"), numOrDash(stats._downloadAuthErrs)).padding(.leading, 24)
|
||||
infoRow("other", numOrDash(stats._downloadErrs)).padding(.leading, 24)
|
||||
} header: {
|
||||
Text("Downloaded files")
|
||||
} footer: {
|
||||
@@ -737,5 +711,7 @@ struct DetailedXFTPStatsView: View {
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ServersSummaryView()
|
||||
ServersSummaryView(
|
||||
serversSummary: Binding.constant(nil)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// ChatItemClipShape.swift
|
||||
// SimpleX (iOS)
|
||||
//
|
||||
// Created by Levitating Pineapple on 04/07/2024.
|
||||
// Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
/// Modifier, which provides clipping mask for ``ChatItemWithMenu`` view
|
||||
/// and it's previews: (drag interaction, context menu, etc.)
|
||||
/// Supports [Dynamic Type](https://developer.apple.com/documentation/uikit/uifont/scaling_fonts_automatically)
|
||||
/// by retaining pill shape, even when ``ChatItem``'s height is less that twice its corner radius
|
||||
struct ChatItemClipped: ViewModifier {
|
||||
struct ClipShape: Shape {
|
||||
let maxCornerRadius: Double
|
||||
|
||||
func path(in rect: CGRect) -> Path {
|
||||
Path(
|
||||
roundedRect: rect,
|
||||
cornerRadius: min((rect.height / 2), maxCornerRadius),
|
||||
style: .circular
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
clipShape = ClipShape(
|
||||
maxCornerRadius: 18
|
||||
)
|
||||
}
|
||||
|
||||
init(_ chatItem: ChatItem) {
|
||||
clipShape = ClipShape(
|
||||
maxCornerRadius: {
|
||||
switch chatItem.content {
|
||||
case
|
||||
.sndMsgContent,
|
||||
.rcvMsgContent,
|
||||
.rcvDecryptionError,
|
||||
.rcvGroupInvitation,
|
||||
.sndGroupInvitation,
|
||||
.sndDeleted,
|
||||
.rcvDeleted,
|
||||
.rcvIntegrityError,
|
||||
.sndModerated,
|
||||
.rcvModerated,
|
||||
.rcvBlocked,
|
||||
.invalidJSON: 18
|
||||
default: 8
|
||||
}
|
||||
}()
|
||||
)
|
||||
}
|
||||
|
||||
private let clipShape: ClipShape
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
.contentShape(.dragPreview, clipShape)
|
||||
.contentShape(.contextMenuPreview, clipShape)
|
||||
.clipShape(clipShape)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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: [])
|
||||
|
||||
@@ -305,13 +305,16 @@ struct ChatThemePreview: View {
|
||||
let view = VStack {
|
||||
if withMessages {
|
||||
let alice = ChatItem.getSample(1, CIDirection.directRcv, Date.now, NSLocalizedString("Good afternoon!", comment: "message preview"))
|
||||
let bob = ChatItem.getSample(2, CIDirection.directSnd, Date.now, NSLocalizedString("Good morning!", comment: "message preview"), quotedItem: CIQuote.getSample(alice.id, alice.meta.itemTs, alice.content.text, chatDir: alice.chatDir))
|
||||
HStack {
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: alice, revealed: Binding.constant(false))
|
||||
.modifier(ChatItemClipped())
|
||||
Spacer()
|
||||
}
|
||||
HStack {
|
||||
Spacer()
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, CIDirection.directSnd, Date.now, NSLocalizedString("Good morning!", comment: "message preview"), quotedItem: CIQuote.getSample(alice.id, alice.meta.itemTs, alice.content.text, chatDir: alice.chatDir)), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: bob, revealed: Binding.constant(false))
|
||||
.modifier(ChatItemClipped())
|
||||
.frame(alignment: .trailing)
|
||||
}
|
||||
} else {
|
||||
@@ -747,7 +750,7 @@ struct ThemeDestinationPicker: View {
|
||||
let values = [(nil, "All profiles")] + m.users.filter { $0.user.activeUser }.map { ($0.user.userId, $0.user.chatViewName)}
|
||||
|
||||
if values.contains(where: { (userId, text) in userId == themeUserDestination?.0 }) {
|
||||
Picker("Apply to mode", selection: $themeUserDest) {
|
||||
Picker("Apply to", selection: $themeUserDest) {
|
||||
ForEach(values, id: \.0) { (_, text) in
|
||||
Text(text)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "bg",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
@@ -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">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "cs",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "de",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
@@ -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">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "en",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "es",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "fi",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "fr",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
@@ -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
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "hu",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "it",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "ja",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
@@ -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">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "nl",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "pl",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
@@ -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">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "ru",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "th",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "tr",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "uk",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
||||
"project" : "SimpleX.xcodeproj",
|
||||
"targetLocale" : "zh-Hans",
|
||||
"toolInfo" : {
|
||||
"toolBuildNumber" : "15A240d",
|
||||
"toolBuildNumber" : "15F31d",
|
||||
"toolID" : "com.apple.dt.xcode",
|
||||
"toolName" : "Xcode",
|
||||
"toolVersion" : "15.0"
|
||||
"toolVersion" : "15.4"
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
@@ -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">
|
||||
|
||||
@@ -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 */; };
|
||||
@@ -195,6 +194,9 @@
|
||||
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 */; };
|
||||
D72A9088294BD7A70047C86D /* NativeTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A9087294BD7A70047C86D /* NativeTextEditor.swift */; };
|
||||
@@ -202,11 +204,12 @@
|
||||
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 */; };
|
||||
E50581002C3DDD7F009C3F71 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50580FB2C3DDD7F009C3F71 /* libffi.a */; };
|
||||
E50581012C3DDD7F009C3F71 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50580FC2C3DDD7F009C3F71 /* libgmp.a */; };
|
||||
E50581022C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50580FD2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a */; };
|
||||
E50581032C3DDD7F009C3F71 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50580FE2C3DDD7F009C3F71 /* libgmpxx.a */; };
|
||||
E50581042C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50580FF2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a */; };
|
||||
E50581062C3DDD9D009C3F71 /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = E50581052C3DDD9D009C3F71 /* Yams */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -501,16 +504,17 @@
|
||||
8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeModeEditor.swift; sourceTree = "<group>"; };
|
||||
8CC4ED8F2BD7B8530078AEE8 /* CallAudioDeviceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallAudioDeviceManager.swift; sourceTree = "<group>"; };
|
||||
8CC956ED2BC0041000412A11 /* NetworkObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkObserver.swift; sourceTree = "<group>"; };
|
||||
CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemClipShape.swift; sourceTree = "<group>"; };
|
||||
CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseList.swift; sourceTree = "<group>"; };
|
||||
D72A9087294BD7A70047C86D /* NativeTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeTextEditor.swift; sourceTree = "<group>"; };
|
||||
D741547729AF89AF0022400A /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/StoreKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||
D741547929AF90B00022400A /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/PushKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||
D7AA2C3429A936B400737B40 /* MediaEncryption.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; name = MediaEncryption.playground; path = Shared/MediaEncryption.playground; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
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>"; };
|
||||
E50580FB2C3DDD7F009C3F71 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
E50580FC2C3DDD7F009C3F71 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
E50580FD2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
E50580FE2C3DDD7F009C3F71 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
E50580FF2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -549,13 +553,15 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E52FF8DE2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a in Frameworks */,
|
||||
E52FF8DB2C34676700BF81EB /* libgmpxx.a in Frameworks */,
|
||||
E50581032C3DDD7F009C3F71 /* libgmpxx.a in Frameworks */,
|
||||
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
|
||||
E50581002C3DDD7F009C3F71 /* libffi.a in Frameworks */,
|
||||
E50581012C3DDD7F009C3F71 /* libgmp.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 */,
|
||||
E50581022C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a in Frameworks */,
|
||||
E50581062C3DDD9D009C3F71 /* Yams in Frameworks */,
|
||||
E50581042C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a in Frameworks */,
|
||||
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -622,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 */,
|
||||
E50580FB2C3DDD7F009C3F71 /* libffi.a */,
|
||||
E50580FC2C3DDD7F009C3F71 /* libgmp.a */,
|
||||
E50580FE2C3DDD7F009C3F71 /* libgmpxx.a */,
|
||||
E50580FD2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a */,
|
||||
E50580FF2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a */,
|
||||
);
|
||||
path = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@@ -654,7 +660,6 @@
|
||||
5CF937212B25034A00E1D781 /* NSESubscriber.swift */,
|
||||
5CB346E82869E8BA001FD2EF /* PushEnvironment.swift */,
|
||||
5C93293E2928E0FD0090FFF9 /* AudioRecPlay.swift */,
|
||||
5CBD2859295711D700EC2CF4 /* ImageUtils.swift */,
|
||||
8CC956ED2BC0041000412A11 /* NetworkObserver.swift */,
|
||||
);
|
||||
path = Model;
|
||||
@@ -683,6 +688,7 @@
|
||||
8C7F8F0D2C19C0C100D16888 /* ViewModifiers.swift */,
|
||||
8C74C3ED2C1B942300039E77 /* ChatWallpaper.swift */,
|
||||
8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */,
|
||||
CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
@@ -853,6 +859,7 @@
|
||||
5C9FD96A27A56D4D0075386C /* JSON.swift */,
|
||||
5CDCAD7D2818941F00503DA2 /* API.swift */,
|
||||
5CDCAD80281A7E2700503DA2 /* Notifications.swift */,
|
||||
5CBD2859295711D700EC2CF4 /* ImageUtils.swift */,
|
||||
64DAE1502809D9F5000DA960 /* FileUtils.swift */,
|
||||
5C9D81182AA7A4F1001D49FD /* CryptoFile.swift */,
|
||||
5C00168028C4FE760094D739 /* KeyChain.swift */,
|
||||
@@ -1062,6 +1069,8 @@
|
||||
);
|
||||
name = SimpleXChat;
|
||||
packageProductDependencies = (
|
||||
E50581052C3DDD9D009C3F71 /* Yams */,
|
||||
CE38A29B2C3FCD72005ED185 /* SwiftyGif */,
|
||||
);
|
||||
productName = SimpleXChat;
|
||||
productReference = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */;
|
||||
@@ -1199,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 */,
|
||||
@@ -1225,6 +1233,7 @@
|
||||
5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */,
|
||||
5C10D88A28F187F300E58BF0 /* FullScreenMediaView.swift in Sources */,
|
||||
D72A9088294BD7A70047C86D /* NativeTextEditor.swift in Sources */,
|
||||
CE984D4B2C36C5D500E3AEFF /* ChatItemClipShape.swift in Sources */,
|
||||
64D0C2C629FAC1EC00B38D5F /* AddContactLearnMore.swift in Sources */,
|
||||
5C3A88D127DF57800060F1C2 /* FramedItemView.swift in Sources */,
|
||||
5C65F343297D45E100B67AF3 /* VersionView.swift in Sources */,
|
||||
@@ -1369,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 */,
|
||||
@@ -1608,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 = 227;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -1633,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;
|
||||
@@ -1657,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 = 227;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -1682,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;
|
||||
@@ -1743,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 = 227;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
@@ -1758,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 = "";
|
||||
@@ -1780,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 = 227;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
ENABLE_CODE_COVERAGE = NO;
|
||||
@@ -1795,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 = "";
|
||||
@@ -1817,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 = 227;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@@ -1843,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;
|
||||
@@ -1868,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 = 227;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@@ -1894,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;
|
||||
@@ -2016,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" */;
|
||||
@@ -2031,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 */;
|
||||
|
||||
@@ -1122,20 +1122,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 +1148,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 +1165,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 +1189,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
|
||||
@@ -1906,6 +1900,7 @@ public enum AgentErrorType: Decodable, Hashable {
|
||||
case SMP(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 +1938,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 +1972,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 +2007,7 @@ public enum ProtocolCommandError: Decodable, Hashable {
|
||||
|
||||
public enum ProtocolTransportError: Decodable, Hashable {
|
||||
case badBlock
|
||||
case version
|
||||
case largeMsg
|
||||
case badSession
|
||||
case noServerAuth
|
||||
|
||||
@@ -1611,11 +1611,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 +1625,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 +1642,8 @@ public struct Connection: Decodable, Hashable {
|
||||
viaGroupLink: false,
|
||||
pqSupport: false,
|
||||
pqEncryption: false,
|
||||
authErrCounter: 0
|
||||
authErrCounter: 0,
|
||||
quotaErrCounter: 0
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2846,6 +2852,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?)
|
||||
@@ -4012,6 +4074,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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -337,9 +337,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 +366,7 @@
|
||||
"Add profile" = "Добави профил";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Добави сървър…";
|
||||
"Add server" = "Добави сървър";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Добави сървъри чрез сканиране на QR кодове.";
|
||||
@@ -647,7 +644,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "блокиран %@";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "блокиран от админ";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -831,9 +828,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "цветен";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Цветове";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Сравни файл";
|
||||
|
||||
@@ -1011,7 +1005,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Продължи";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Копирай";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1779,7 +1773,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Грешка: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Грешка: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -3791,9 +3786,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 **%@**." = "Тези настройки са за текущия ви профил **%@**.";
|
||||
|
||||
|
||||
@@ -289,9 +289,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 +315,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 +675,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "barevné";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Barvy";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Porovnat soubor";
|
||||
|
||||
@@ -813,7 +807,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 +1455,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 +3090,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 **%@**.";
|
||||
|
||||
|
||||
@@ -337,9 +337,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "Danach die gewünschte Aktion auswählen:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Akzentfarbe";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Annehmen";
|
||||
@@ -369,7 +366,7 @@
|
||||
"Add profile" = "Profil hinzufügen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Füge Server hinzu…";
|
||||
"Add server" = "Füge Server hinzu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Fügen Sie Server durch Scannen der QR Codes hinzu.";
|
||||
@@ -653,7 +650,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "%@ wurde blockiert";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "wurde vom Administrator blockiert";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -726,7 +723,7 @@
|
||||
"Capacity exceeded - recipient did not receive previously sent messages." = "Kapazität überschritten - der Empfänger hat die zuvor gesendeten Nachrichten nicht empfangen.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Cellular" = "Zellulär";
|
||||
"Cellular" = "Mobilfunknetz";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Change" = "Ändern";
|
||||
@@ -840,9 +837,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "farbig";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Farben";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Datei vergleichen";
|
||||
|
||||
@@ -1023,7 +1017,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Weiter";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Kopieren";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1167,6 +1161,9 @@
|
||||
/* time unit */
|
||||
"days" = "Tage";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Debugging-Zustellung";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Dezentral";
|
||||
|
||||
@@ -1800,7 +1797,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Fehler: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Fehler: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2496,6 +2494,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Nachrichtenentwurf";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Nachrichten-Warteschlangen-Information";
|
||||
|
||||
/* chat feature */
|
||||
"Message reactions" = "Reaktionen auf Nachrichten";
|
||||
|
||||
@@ -3060,7 +3061,7 @@
|
||||
"Protect your chat profiles with a password!" = "Ihre Chat-Profile mit einem Passwort schützen!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Protect your IP address from the messaging relays chosen by your contacts.\nEnable in *Network & servers* settings." = "Schützen Sie Ihre IP-Adresse vor den Nachrichten-Relais , die Ihre Kontakte ausgewählt haben.\nAktivieren Sie es in den *Netzwerk & Server* Einstellungen.";
|
||||
"Protect your IP address from the messaging relays chosen by your contacts.\nEnable in *Network & servers* settings." = "Schützen Sie Ihre IP-Adresse vor den Nachrichten-Relais, die Ihre Kontakte ausgewählt haben.\nAktivieren Sie es in den *Netzwerk & Server* Einstellungen.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Protocol timeout" = "Protokollzeitüberschreitung";
|
||||
@@ -3518,6 +3519,9 @@
|
||||
/* srv error text. */
|
||||
"Server address is incompatible with network settings." = "Die Server-Adresse ist nicht mit den Netzwerk-Einstellungen kompatibel.";
|
||||
|
||||
/* queue info */
|
||||
"server queue info: %@\n\nlast received msg: %@" = "Server-Warteschlangen-Information: %1$@\n\nZuletzt empfangene Nachricht: %2$@";
|
||||
|
||||
/* server test error */
|
||||
"Server requires authorization to create queues, check password" = "Um Warteschlangen zu erzeugen benötigt der Server eine Authentifizierung. Bitte überprüfen Sie das Passwort";
|
||||
|
||||
@@ -3872,9 +3876,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Der von Ihnen eingefügte Text ist kein SimpleX-Link.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Design";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Diese Einstellungen betreffen Ihr aktuelles Profil **%@**.";
|
||||
|
||||
|
||||
@@ -337,9 +337,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 +366,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.";
|
||||
@@ -653,7 +650,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "ha bloqueado a %@";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "bloqueado por administrador";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -840,9 +837,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "coloreado";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Colores";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Comparar archivo";
|
||||
|
||||
@@ -967,7 +961,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 +973,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 +1017,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 +1161,9 @@
|
||||
/* time unit */
|
||||
"days" = "días";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Informe debug";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Descentralizada";
|
||||
|
||||
@@ -1800,7 +1797,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 +2099,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 +2494,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 +2767,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 +2851,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 +2899,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 +2908,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 +3064,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 +3091,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 +3519,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 +3595,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 +3775,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 +3784,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 +3876,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 +3943,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 +4030,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 +4042,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 +4060,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 +4132,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";
|
||||
@@ -4524,7 +4525,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 +4597,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.";
|
||||
|
||||
@@ -280,9 +280,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 +306,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 +660,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 +789,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 +1428,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 +3051,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 **%@**.";
|
||||
|
||||
|
||||
@@ -337,9 +337,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 +366,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.";
|
||||
@@ -653,7 +650,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "%@ bloqué";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "bloqué par l'administrateur";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -840,9 +837,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 +1017,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 +1161,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 +1797,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 +2494,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 +3519,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 +3876,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 **%@**.";
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
"`a + b`" = "a + b";
|
||||
|
||||
/* email text */
|
||||
"<p>Hi!</p>\n<p><a href=\"%@\">Connect to me via SimpleX Chat</a></p>" = "<p>Üdvözlöm!</p>\n<p><a href=\"%@\">Csatlakozzon hozzám a SimpleX Chaten</a></p>";
|
||||
"<p>Hi!</p>\n<p><a href=\"%@\">Connect to me via SimpleX Chat</a></p>" = "<p>Üdvözlöm!</p>\n<p><a href=„%@”>Csatlakozzon hozzám a SimpleX Chaten</a></p>";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"~strike~" = "\\~áthúzott~";
|
||||
@@ -326,20 +326,17 @@
|
||||
"Abort changing address?" = "Címváltoztatás megszakítása??";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"About SimpleX" = "A SimpleX névjegye";
|
||||
"About SimpleX" = "A SimpleX-ről";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"About SimpleX address" = "A SimpleX azonosítóról";
|
||||
"About SimpleX address" = "A SimpleX címről";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"About SimpleX Chat" = "A SimpleX Chat névjegye";
|
||||
"About SimpleX Chat" = "A SimpleX Chat-ről";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "gombra fent, majd válassza ki:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Kiemelő szín";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Elfogadás";
|
||||
@@ -357,7 +354,7 @@
|
||||
"accepted call" = "elfogadott hívás";
|
||||
|
||||
/* 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." = "Azonosító hozzáadása a profilhoz, hogy az ismerősei megoszthassák másokkal. A profilfrissítés elküldésre kerül az ismerősei számára.";
|
||||
"Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." = "Cím hozzáadása a profilhoz, hogy az ismerősei megoszthassák másokkal. A profilfrissítés elküldésre kerül az ismerősei számára.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add contact" = "Ismerős hozzáadása";
|
||||
@@ -369,7 +366,7 @@
|
||||
"Add profile" = "Profil hozzáadása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Kiszolgáló hozzáadása…";
|
||||
"Add server" = "Kiszolgáló hozzáadása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Kiszolgáló hozzáadása QR-kód beolvasásával.";
|
||||
@@ -462,7 +459,7 @@
|
||||
"Allow message reactions." = "Üzenetreakciók engedélyezése.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Allow sending direct messages to members." = "Közvetlen üzenetek küldésének engedélyezése a tagok számára.";
|
||||
"Allow sending direct messages to members." = "A közvetlen üzenetek küldése a tagok között engedélyezve van.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Allow sending disappearing messages." = "Az eltűnő üzenetek küldése engedélyezve van.";
|
||||
@@ -522,7 +519,7 @@
|
||||
"An empty chat profile with the provided name is created, and the app opens as usual." = "Egy üres csevegési profil jön létre a megadott névvel, és az alkalmazás a szokásos módon megnyílik.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"and %lld other events" = "és %lld további esemény";
|
||||
"and %lld other events" = "és további %lld esemény";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Answer call" = "Hívás fogadása";
|
||||
@@ -609,7 +606,7 @@
|
||||
"Back" = "Vissza";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Bad desktop address" = "Hibás számítógép azonosító";
|
||||
"Bad desktop address" = "Hibás számítógép cím";
|
||||
|
||||
/* integrity error chat item */
|
||||
"bad message hash" = "téves üzenet hash";
|
||||
@@ -633,7 +630,7 @@
|
||||
"Block" = "Blokkolás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Block for all" = "Mindenki számára letiltva";
|
||||
"Block for all" = "Letiltás mindenki számára";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Block group members" = "Csoporttagok blokkolása";
|
||||
@@ -651,9 +648,9 @@
|
||||
"blocked" = "blokkolva";
|
||||
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "%@ letiltva";
|
||||
"blocked %@" = "letiltotta őt: %@";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "letiltva az admin által";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -699,7 +696,7 @@
|
||||
"Calls" = "Hívások";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Camera not available" = "A fényképező nem elérhető";
|
||||
"Camera not available" = "A kamera nem elérhető";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Can't invite contact!" = "Ismerősök meghívása le van tiltva!";
|
||||
@@ -769,10 +766,10 @@
|
||||
"changed your role to %@" = "megváltoztatta a szerepkörét erre: %@";
|
||||
|
||||
/* chat item text */
|
||||
"changing address for %@…" = "cím módosítása %@ számára…";
|
||||
"changing address for %@…" = "cím megváltoztatása nála: %@…";
|
||||
|
||||
/* chat item text */
|
||||
"changing address…" = "azonosító megváltoztatása…";
|
||||
"changing address…" = "cím megváltoztatása…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat archive" = "Csevegési archívum";
|
||||
@@ -840,9 +837,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "színes";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Színek";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Fájl összehasonlítás";
|
||||
|
||||
@@ -904,10 +898,10 @@
|
||||
"Connect to yourself?\nThis is your own one-time link!" = "Kapcsolódás saját magához?\nEz az egyszer használatos hivatkozása!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connect to yourself?\nThis is your own SimpleX address!" = "Kapcsolódás saját magához?\nEz a SimpleX azonosítója!";
|
||||
"Connect to yourself?\nThis is your own SimpleX address!" = "Kapcsolódás saját magához?\nEz az ön SimpleX címe!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connect via contact address" = "Kapcsolódás a kapcsolattartási azonosítón keresztül";
|
||||
"Connect via contact address" = "Kapcsolódás a kapcsolattartási címen keresztül";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Connect via link" = "Kapcsolódás egy hivatkozáson keresztül";
|
||||
@@ -1023,7 +1017,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Folytatás";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Másolás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1039,7 +1033,7 @@
|
||||
"Create a group using a random profile." = "Csoport létrehozása véletlenszerűen létrehozott profillal.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Create an address to let people connect with you." = "Azonosító létrehozása, hogy az emberek kapcsolatba léphessenek önnel.";
|
||||
"Create an address to let people connect with you." = "Cím létrehozása, hogy az emberek kapcsolatba léphessenek önnel.";
|
||||
|
||||
/* server test step */
|
||||
"Create file" = "Fájl létrehozása";
|
||||
@@ -1066,7 +1060,7 @@
|
||||
"Create secret group" = "Titkos csoport létrehozása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Create SimpleX address" = "SimpleX azonosító létrehozása";
|
||||
"Create SimpleX address" = "SimpleX cím létrehozása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Create your profile" = "Saját profil létrehozása";
|
||||
@@ -1167,6 +1161,9 @@
|
||||
/* time unit */
|
||||
"days" = "nap";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Kézbesítési hibák felderítése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Decentralizált";
|
||||
|
||||
@@ -1189,10 +1186,10 @@
|
||||
"Delete %lld messages?" = "Töröl %lld üzenetet?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete address" = "Azonosító törlése";
|
||||
"Delete address" = "Cím törlése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete address?" = "Azonosító törlése?";
|
||||
"Delete address?" = "Cím törlése?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete after" = "Törlés ennyi idő után";
|
||||
@@ -1324,7 +1321,7 @@
|
||||
"Description" = "Leírás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Desktop address" = "Számítógép azonosítója";
|
||||
"Desktop address" = "Számítógép címe";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Desktop app version %@ is not compatible with this app." = "Az asztali kliens verziója %@ nem kompatibilis ezzel az alkalmazással.";
|
||||
@@ -1423,7 +1420,7 @@
|
||||
"Do NOT use SimpleX for emergency calls." = "NE használja a SimpleX-et segélyhívásokhoz.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Don't create address" = "Ne hozzon létre azonosítót";
|
||||
"Don't create address" = "Ne hozzon létre címet";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Don't enable" = "Ne engedélyezze";
|
||||
@@ -1453,7 +1450,7 @@
|
||||
"Duplicate display name!" = "Duplikált megjelenítési név!";
|
||||
|
||||
/* integrity error chat item */
|
||||
"duplicate message" = "duplikálódott üzenet";
|
||||
"duplicate message" = "duplikált üzenet";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Duration" = "Időtartam";
|
||||
@@ -1507,7 +1504,7 @@
|
||||
"Enable SimpleX Lock" = "SimpleX zárolás engedélyezése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Enable TCP keep-alive" = "TCP életben tartásának engedélyezése";
|
||||
"Enable TCP keep-alive" = "TCP életben tartása";
|
||||
|
||||
/* enabled status */
|
||||
"enabled" = "engedélyezve";
|
||||
@@ -1633,7 +1630,7 @@
|
||||
"Error" = "Hiba";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error aborting address change" = "Hiba az azonosító megváltoztatásának megszakításakor";
|
||||
"Error aborting address change" = "Hiba a cím megváltoztatásának megszakításakor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error accepting contact request" = "Hiba történt a kapcsolatfelvételi kérelem elfogadásakor";
|
||||
@@ -1645,7 +1642,7 @@
|
||||
"Error adding member(s)" = "Hiba a tag(-ok) hozzáadásakor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing address" = "Hiba az azonosító megváltoztatásakor";
|
||||
"Error changing address" = "Hiba a cím megváltoztatásakor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing role" = "Hiba a szerepkör megváltoztatásakor";
|
||||
@@ -1654,7 +1651,7 @@
|
||||
"Error changing setting" = "Hiba a beállítás megváltoztatásakor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error creating address" = "Hiba az azonosító létrehozásakor";
|
||||
"Error creating address" = "Hiba a cím létrehozásakor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error creating group" = "Hiba a csoport létrehozásakor";
|
||||
@@ -1735,7 +1732,7 @@
|
||||
"Error saving %@ servers" = "Hiba történt a %@ kiszolgálók mentése közben";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error saving group profile" = "Hiba a csoport profil mentésekor";
|
||||
"Error saving group profile" = "Hiba a csoportprofil mentésekor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error saving ICE servers" = "Hiba az ICE kiszolgálók mentésekor";
|
||||
@@ -1800,7 +1797,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Hiba: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Hiba: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2029,13 +2027,13 @@
|
||||
"Group preferences" = "Csoport beállítások";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Group profile" = "Csoport profil";
|
||||
"Group profile" = "Csoportprofil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Group profile is stored on members' devices, not on the servers." = "A csoport profilja a tagok eszközein tárolódik, nem a kiszolgálókon.";
|
||||
|
||||
/* snd group event chat item */
|
||||
"group profile updated" = "csoport profil frissítve";
|
||||
"group profile updated" = "csoportprofil frissítve";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Group welcome message" = "Csoport üdvözlő üzenete";
|
||||
@@ -2437,10 +2435,10 @@
|
||||
"Make profile private!" = "Tegye priváttá a profilját!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Make sure %@ server addresses are in correct format, line separated and are not duplicated (%@)." = "Győződjön meg arról, hogy a %@ kiszolgálócímek megfelelő formátumúak, sorszeparáltak és nem duplikáltak (%@).";
|
||||
"Make sure %@ server addresses are in correct format, line separated and are not duplicated (%@)." = "Győződjön meg arról, hogy a %@ kiszolgálócímek megfelelő formátumúak, sorszeparáltak és nincsenek duplikálva (%@).";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated." = "Győződjön meg arról, hogy a WebRTC ICE-kiszolgáló címei megfelelő formátumúak, sorszeparáltak és nem duplikáltak.";
|
||||
"Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated." = "Győződjön meg arról, hogy a WebRTC ICE-kiszolgáló címei megfelelő formátumúak, sorszeparáltak és nincsenek duplikálva.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*" = "Sokan kérdezték: *ha a SimpleX-nek nincsenek felhasználói azonosítói, akkor hogyan tud üzeneteket kézbesíteni?*";
|
||||
@@ -2476,10 +2474,10 @@
|
||||
"member connected" = "kapcsolódott";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Member role will be changed to \"%@\". All group members will be notified." = "A tag szerepköre meg fog változni erre: \"%@\". A csoport minden tagja értesítést kap róla.";
|
||||
"Member role will be changed to \"%@\". All group members will be notified." = "A tag szerepköre meg fog változni erre: „%@”. A csoport minden tagja értesítést kap róla.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Member role will be changed to \"%@\". The member will receive a new invitation." = "A tag szerepköre meg fog változni erre: \"%@\". A tag új meghívást fog kapni.";
|
||||
"Member role will be changed to \"%@\". The member will receive a new invitation." = "A tag szerepköre meg fog változni erre: „%@”. A tag új meghívást fog kapni.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Member will be removed from group - this cannot be undone!" = "A tag eltávolítása a csoportból - ez a művelet nem vonható vissza!";
|
||||
@@ -2496,6 +2494,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Üzenetvázlat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Üzenet-várakoztatási információ";
|
||||
|
||||
/* chat feature */
|
||||
"Message reactions" = "Üzenetreakciók";
|
||||
|
||||
@@ -2731,7 +2732,7 @@
|
||||
"Notifications are disabled!" = "Az értesítések le vannak tiltva!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)" = "Most már az adminok is:\n- törölhetik a tagok üzeneteit.\n- letilthatnak tagokat (\"megfigyelő\" szerepkör)";
|
||||
"Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)" = "Most már az adminok is:\n- törölhetik a tagok üzeneteit.\n- letilthatnak tagokat („megfigyelő” szerepkör)";
|
||||
|
||||
/* member role */
|
||||
"observer" = "megfigyelő";
|
||||
@@ -2739,7 +2740,7 @@
|
||||
/* enabled status
|
||||
group pref value
|
||||
time to disappear */
|
||||
"off" = "ki";
|
||||
"off" = "kikapcsolva";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Off" = "Ki";
|
||||
@@ -2886,10 +2887,10 @@
|
||||
"Password to show" = "Jelszó megjelenítése";
|
||||
|
||||
/* past/unknown group member */
|
||||
"Past member %@" = "Korábbi csoport tag %@";
|
||||
"Past member %@" = "Már nem tag - %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Paste desktop address" = "Számítógép azonosítójának beillesztése";
|
||||
"Paste desktop address" = "Számítógép címének beillesztése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Paste image" = "Kép beillesztése";
|
||||
@@ -3036,7 +3037,7 @@
|
||||
"Prohibit messages reactions." = "Az üzenetreakciók tiltása.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Prohibit sending direct messages to members." = "A közvetlen üzenetek küldése le van tiltva a tagok között.";
|
||||
"Prohibit sending direct messages to members." = "A közvetlen üzenetek küldése a tagok között le van tiltva.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Prohibit sending disappearing messages." = "Az eltűnő üzenetek küldése le van tiltva.";
|
||||
@@ -3054,7 +3055,7 @@
|
||||
"Protect app screen" = "Alkalmazás képernyőjének védelme";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Protect IP address" = "Az IP-cím védelme";
|
||||
"Protect IP address" = "IP-cím védelem";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Protect your chat profiles with a password!" = "Csevegési profiljok védelme jelszóval!";
|
||||
@@ -3174,10 +3175,10 @@
|
||||
"rejected call" = "elutasított hívás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Relay server is only used if necessary. Another party can observe your IP address." = "Az átjátszó kiszolgáló csak szükség esetén kerül használatra. Egy másik fél megfigyelheti az IP-címét.";
|
||||
"Relay server is only used if necessary. Another party can observe your IP address." = "Az átjátszó kiszolgáló csak szükség esetén kerül használatra. Egy másik fél megfigyelheti az IP-címet.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Relay server protects your IP address, but it can observe the duration of the call." = "Az átjátszó kiszolgáló megvédi IP-címét, de megfigyelheti a hívás időtartamát.";
|
||||
"Relay server protects your IP address, but it can observe the duration of the call." = "Az átjátszó kiszolgáló megvédi az IP-címet, de megfigyelheti a hívás időtartamát.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove" = "Eltávolítás";
|
||||
@@ -3198,7 +3199,7 @@
|
||||
"removed %@" = "%@ eltávolítva";
|
||||
|
||||
/* profile update event chat item */
|
||||
"removed contact address" = "törölt kapcsolattartási azonosító";
|
||||
"removed contact address" = "törölt kapcsolattartási cím";
|
||||
|
||||
/* profile update event chat item */
|
||||
"removed profile picture" = "törölt profilkép";
|
||||
@@ -3270,7 +3271,7 @@
|
||||
"Reveal" = "Felfedés";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Revert" = "Visszaállít";
|
||||
"Revert" = "Visszaállítás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Revoke" = "Visszavonás";
|
||||
@@ -3306,7 +3307,7 @@
|
||||
"Save and notify group members" = "Mentés és a csoporttagok értesítése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Save and update group profile" = "Mentés és a csoport profil frissítése";
|
||||
"Save and update group profile" = "Mentés és csoportprofil frissítése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Save archive" = "Archívum mentése";
|
||||
@@ -3315,7 +3316,7 @@
|
||||
"Save auto-accept settings" = "Automatikus elfogadási beállítások mentése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Save group profile" = "Csoport profil elmentése";
|
||||
"Save group profile" = "Csoportprofil elmentése";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Save passphrase and open chat" = "Jelmondat elmentése és csevegés megnyitása";
|
||||
@@ -3518,6 +3519,9 @@
|
||||
/* srv error text. */
|
||||
"Server address is incompatible with network settings." = "A kiszolgáló címe nem kompatibilis a hálózati beállításokkal.";
|
||||
|
||||
/* queue info */
|
||||
"server queue info: %@\n\nlast received msg: %@" = "kiszolgáló üzenet-várakotatási információ: %1$@\n\nutoljára fogadott üzenet: %2$@";
|
||||
|
||||
/* server test error */
|
||||
"Server requires authorization to create queues, check password" = "A kiszolgálónak engedélyre van szüksége a várólisták létrehozásához, ellenőrizze jelszavát";
|
||||
|
||||
@@ -3549,10 +3553,10 @@
|
||||
"Set it instead of system authentication." = "Rendszerhitelesítés helyetti beállítás.";
|
||||
|
||||
/* profile update event chat item */
|
||||
"set new contact address" = "új kapcsolattartási azonosító beállítása";
|
||||
"set new contact address" = "új kapcsolattartási cím beállítása";
|
||||
|
||||
/* profile update event chat item */
|
||||
"set new profile picture" = "új profilkép beállítása";
|
||||
"set new profile picture" = "új profilképet állított be";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Set passcode" = "Jelkód beállítása";
|
||||
@@ -3582,10 +3586,10 @@
|
||||
"Share 1-time link" = "Egyszer használatos hivatkozás megosztása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Share address" = "Azonosító megosztása";
|
||||
"Share address" = "Cím megosztása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Share address with contacts?" = "Megosztja az azonosítót az ismerőseivel?";
|
||||
"Share address with contacts?" = "Megosztja a címet az ismerőseivel?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Share link" = "Hivatkozás megosztása";
|
||||
@@ -3621,16 +3625,16 @@
|
||||
"Show:" = "Megjelenítés:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX address" = "SimpleX azonosító";
|
||||
"SimpleX address" = "SimpleX cím";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX Address" = "SimpleX azonosító";
|
||||
"SimpleX Address" = "SimpleX cím";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX Chat security was audited by Trail of Bits." = "A SimpleX Chat biztonsága a Trail of Bits által lett auditálva.";
|
||||
|
||||
/* simplex link type */
|
||||
"SimpleX contact address" = "SimpleX kapcsolattartási azonosító";
|
||||
"SimpleX contact address" = "SimpleX kapcsolattartási cím";
|
||||
|
||||
/* notification */
|
||||
"SimpleX encrypted message or connection event" = "SimpleX titkosított üzenet vagy kapcsolati esemény";
|
||||
@@ -3675,7 +3679,7 @@
|
||||
"Small groups (max 20)" = "Kis csoportok (max. 20 tag)";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SMP servers" = "Üzenetküldő (SMP) kiszolgálók";
|
||||
"SMP servers" = "SMP kiszolgálók";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Some non-fatal errors occurred during import - you may see Chat console for more details." = "Néhány nem végzetes hiba történt az importálás során – további részletekért a csevegési konzolban olvashat.";
|
||||
@@ -3872,9 +3876,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "A beillesztett szöveg nem egy SimpleX hivatkozás.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Téma";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Ezek a beállítások a jelenlegi **%@** profiljára vonatkoznak.";
|
||||
|
||||
@@ -3915,7 +3916,7 @@
|
||||
"This is your own one-time link!" = "Ez az egyszer használatos hivatkozása!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"This is your own SimpleX address!" = "Ez a SimpleX azonosítója!";
|
||||
"This is your own SimpleX address!" = "Ez az ön SimpleX címe!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"This setting applies to messages in your current chat profile **%@**." = "Ez a beállítás a jelenlegi **%@** profiljában lévő üzenetekre érvényes.";
|
||||
@@ -3942,7 +3943,7 @@
|
||||
"To protect your information, turn on SimpleX Lock.\nYou will be prompted to complete authentication before this feature is enabled." = "Az adatavédelem érdekében kapcsolja be a SimpleX zárolás funkciót.\nA funkció engedélyezése előtt a rendszer felszólítja a hitelesítés befejezésére.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To protect your IP address, private routing uses your SMP servers to deliver messages." = "Az IP-címe védelme érdekében a privát útválasztás az SMP-kiszolgálókat használja az üzenetek kézbesítéséhez.";
|
||||
"To protect your IP address, private routing uses your SMP servers to deliver messages." = "Az IP-cím védelmének érdekében a privát útválasztás az SMP kiszolgálókat használja az üzenetek kézbesítéséhez.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record voice message please grant permission to use Microphone." = "Hangüzenet rögzítéséhez adjon engedélyt a mikrofon használathoz.";
|
||||
@@ -4185,7 +4186,7 @@
|
||||
"Via browser" = "Böngészőn keresztül";
|
||||
|
||||
/* chat list item description */
|
||||
"via contact address link" = "kapcsolattartási azonosító-hivatkozáson keresztül";
|
||||
"via contact address link" = "kapcsolattartási cím-hivatkozáson keresztül";
|
||||
|
||||
/* chat list item description */
|
||||
"via group link" = "csoport hivatkozáson keresztül";
|
||||
@@ -4347,7 +4348,7 @@
|
||||
"You **must not** use the same database on two devices." = "**Nem szabad** ugyanazt az adatbázist használni egyszerre két eszközön.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You accepted connection" = "Kapcsolódás elfogadva";
|
||||
"You accepted connection" = "Kapcsolat létrehozása";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You allow" = "Engedélyezte";
|
||||
@@ -4425,10 +4426,10 @@
|
||||
"You can share a link or a QR code - anybody will be able to join the group. You won't lose members of the group if you later delete it." = "Megoszthat egy hivatkozást vagy QR-kódot - így bárki csatlakozhat a csoporthoz. Ha a csoport később törlésre kerül, akkor nem fogja elveszíteni annak tagjait.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can share this address with your contacts to let them connect with **%@**." = "Megoszthatja ezt az azonosítót az ismerőseivel, hogy kapcsolatba léphessenek önnel a **%@** nevű profilján keresztül.";
|
||||
"You can share this address with your contacts to let them connect with **%@**." = "Megoszthatja ezt a címet az ismerőseivel, hogy kapcsolatba léphessenek önnel a(z) **%@** nevű profilján keresztül.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can share your address as a link or QR code - anybody can connect to you." = "Megoszthatja azonosítóját hivatkozásként vagy QR-kódként – így bárki kapcsolódhat önhöz.";
|
||||
"You can share your address as a link or QR code - anybody can connect to you." = "Megoszthatja a címét egy hivatkozásként vagy QR-kódként – így bárki kapcsolódhat önhöz.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can start chat via app Settings / Database or by restarting the app" = "A csevegést az alkalmazás Beállítások / Adatbázis menü segítségével vagy az alkalmazás újraindításával indíthatja el";
|
||||
@@ -4446,10 +4447,10 @@
|
||||
"You can't send messages!" = "Nem lehet üzeneteket küldeni!";
|
||||
|
||||
/* chat item text */
|
||||
"you changed address" = "azonosítója megváltoztatva";
|
||||
"you changed address" = "cím megváltoztatva";
|
||||
|
||||
/* chat item text */
|
||||
"you changed address for %@" = "%@ azonosítója megváltoztatva";
|
||||
"you changed address for %@" = "cím megváltoztatva nála: %@";
|
||||
|
||||
/* snd group event chat item */
|
||||
"you changed role for yourself to %@" = "saját szerepkör megváltoztatva erre: %@";
|
||||
@@ -4464,7 +4465,7 @@
|
||||
"You could not be verified; please try again." = "Nem lehetett ellenőrizni; próbálja meg újra.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You have already requested connection via this address!" = "Már kért egy kapcsolódási kérelmet ezen az azonosítón keresztül!";
|
||||
"You have already requested connection via this address!" = "Már kért egy kapcsolódási kérelmet ezen a címen keresztül!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You have already requested connection!\nRepeat connection request?" = "Már kért egy kapcsolódási kérelmet!\nKapcsolódási kérés megismétlése?";
|
||||
@@ -4536,7 +4537,7 @@
|
||||
"You will stop receiving messages from this group. Chat history will be preserved." = "Ettől a csoporttól nem fog értesítéseket kapni. A csevegési előzmények megmaradnak.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You won't lose your contacts if you later delete your address." = "Nem veszíti el az ismerőseit, ha később törli az azonosítóját.";
|
||||
"You won't lose your contacts if you later delete your address." = "Nem veszíti el az ismerőseit, ha később törli a címét.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"you: " = "ön: ";
|
||||
@@ -4614,7 +4615,7 @@
|
||||
"Your settings" = "Beállítások";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your SimpleX address" = "SimpleX azonosítója";
|
||||
"Your SimpleX address" = "Az ön SimpleX címe";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your SMP servers" = "SMP kiszolgálók";
|
||||
|
||||
@@ -337,9 +337,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"above, then choose:" = "sopra, quindi scegli:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Accent color" = "Colore principale";
|
||||
|
||||
/* accept contact request via notification
|
||||
accept incoming call via notification */
|
||||
"Accept" = "Accetta";
|
||||
@@ -369,7 +366,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.";
|
||||
@@ -653,7 +650,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "ha bloccato %@";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "bloccato dall'amministratore";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -840,9 +837,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "colorato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Colori";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Confronta file";
|
||||
|
||||
@@ -1023,7 +1017,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Continua";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Copia";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1167,6 +1161,9 @@
|
||||
/* time unit */
|
||||
"days" = "giorni";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Debug della consegna";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Decentralizzato";
|
||||
|
||||
@@ -1800,7 +1797,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Errore: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Errore: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2496,6 +2494,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Bozza dei messaggi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Info coda messaggi";
|
||||
|
||||
/* chat feature */
|
||||
"Message reactions" = "Reazioni ai messaggi";
|
||||
|
||||
@@ -2991,7 +2992,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 🚀";
|
||||
@@ -3518,6 +3519,9 @@
|
||||
/* 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";
|
||||
|
||||
@@ -3872,9 +3876,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Il testo che hai incollato non è un link SimpleX.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Theme" = "Tema";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"These settings are for your current profile **%@**." = "Queste impostazioni sono per il tuo profilo attuale **%@**.";
|
||||
|
||||
|
||||
@@ -331,9 +331,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 +357,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 +732,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "色付き";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "色";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "ファイルを比較";
|
||||
|
||||
@@ -867,7 +861,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "続ける";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "コピー";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1509,7 +1503,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "エラー : ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "エラー : %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -3113,9 +3108,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 **%@**." = "これらの設定は現在のプロファイル **%@** 用です。";
|
||||
|
||||
|
||||
@@ -337,9 +337,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 +366,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.";
|
||||
@@ -653,7 +650,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "geblokkeerd %@";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "geblokkeerd door beheerder";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -840,9 +837,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "gekleurd";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Kleuren";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Bestand vergelijken";
|
||||
|
||||
@@ -1023,7 +1017,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 +1161,9 @@
|
||||
/* time unit */
|
||||
"days" = "dagen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Foutopsporing bezorging";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Gedecentraliseerd";
|
||||
|
||||
@@ -1800,7 +1797,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 +2494,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 +3519,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 +3876,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 **%@**.";
|
||||
|
||||
|
||||
@@ -337,9 +337,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 +366,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.";
|
||||
@@ -653,7 +650,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "zablokowany %@";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "zablokowany przez admina";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -840,9 +837,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 +1017,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 +1161,9 @@
|
||||
/* time unit */
|
||||
"days" = "dni";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Dostarczenie debugowania";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Zdecentralizowane";
|
||||
|
||||
@@ -1800,7 +1797,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 +2494,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 +3519,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 +3876,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 **%@**.";
|
||||
|
||||
|
||||
@@ -337,9 +337,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 +366,7 @@
|
||||
"Add profile" = "Добавить профиль";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Добавить сервер…";
|
||||
"Add server" = "Добавить сервер";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Добавить серверы через QR код.";
|
||||
@@ -653,7 +650,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "%@ заблокирован";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "заблокировано администратором";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -840,9 +837,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "цвет";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Цвета";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Сравнение файла";
|
||||
|
||||
@@ -1023,7 +1017,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Продолжить";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Скопировать";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -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. */
|
||||
@@ -3872,9 +3867,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 **%@**." = "Установки для Вашего активного профиля **%@**.";
|
||||
|
||||
|
||||
@@ -259,9 +259,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 +282,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 +636,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "มีสี";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "สี";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "เปรียบเทียบไฟล์";
|
||||
|
||||
@@ -765,7 +759,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "ดำเนินการต่อ";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "คัดลอก";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1386,7 +1380,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "ผิดพลาด: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "ข้อผิดพลาด: % @";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2975,9 +2970,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 **%@**." = "การตั้งค่าเหล่านี้ใช้สำหรับโปรไฟล์ปัจจุบันของคุณ **%@**";
|
||||
|
||||
|
||||
@@ -337,9 +337,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 +366,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.";
|
||||
@@ -653,7 +650,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "engellendi %@";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "yönetici tarafından engellendi";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -840,9 +837,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 +1017,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 +1161,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 +1797,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 +2494,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 +3519,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 +3876,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.";
|
||||
|
||||
|
||||
@@ -337,9 +337,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 +366,7 @@
|
||||
"Add profile" = "Додати профіль";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "Додати сервер…";
|
||||
"Add server" = "Додати сервер";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "Додайте сервери, відсканувавши QR-код.";
|
||||
@@ -653,7 +650,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "заблоковано %@";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "заблоковано адміністратором";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -840,9 +837,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "кольоровий";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "Кольори";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "Порівняти файл";
|
||||
|
||||
@@ -1023,7 +1017,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "Продовжуйте";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "Копіювати";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1167,6 +1161,9 @@
|
||||
/* time unit */
|
||||
"days" = "днів";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Debug delivery" = "Доставка налагодження";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Decentralized" = "Децентралізований";
|
||||
|
||||
@@ -1800,7 +1797,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "Помилка: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "Помилка: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -2496,6 +2494,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message draft" = "Чернетка повідомлення";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message queue info" = "Інформація про чергу повідомлень";
|
||||
|
||||
/* chat feature */
|
||||
"Message reactions" = "Реакції на повідомлення";
|
||||
|
||||
@@ -3518,6 +3519,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 +3876,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 **%@**." = "Ці налаштування стосуються вашого поточного профілю **%@**.";
|
||||
|
||||
|
||||
@@ -301,9 +301,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 +330,7 @@
|
||||
"Add profile" = "添加个人资料";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add server…" = "添加服务器…";
|
||||
"Add server" = "添加服务器";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Add servers by scanning QR codes." = "扫描二维码来添加服务器。";
|
||||
@@ -605,7 +602,7 @@
|
||||
/* rcv group event chat item */
|
||||
"blocked %@" = "已封禁 %@";
|
||||
|
||||
/* marked deleted chat item preview text */
|
||||
/* blocked chat item */
|
||||
"blocked by admin" = "由管理员封禁";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -786,9 +783,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"colored" = "彩色";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Colors" = "颜色";
|
||||
|
||||
/* server test step */
|
||||
"Compare file" = "对比文件";
|
||||
|
||||
@@ -951,7 +945,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Continue" = "继续";
|
||||
|
||||
/* chat item action */
|
||||
/* No comment provided by engineer. */
|
||||
"Copy" = "复制";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -1689,7 +1683,8 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error: " = "错误: ";
|
||||
|
||||
/* snd error text */
|
||||
/* file error text
|
||||
snd error text */
|
||||
"Error: %@" = "错误: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
@@ -3644,9 +3639,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 **%@**." = "这些设置适用于您当前的配置文件 **%@**。";
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
+3
-2
@@ -29,6 +29,7 @@ import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import chat.simplex.common.R
|
||||
import chat.simplex.common.helpers.toURI
|
||||
import chat.simplex.common.model.ChatController.appPrefs
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.ui.theme.CurrentColors
|
||||
import chat.simplex.common.views.chat.*
|
||||
@@ -107,7 +108,7 @@ actual fun PlatformTextField(
|
||||
editText.maxLines = 16
|
||||
editText.inputType = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES or editText.inputType
|
||||
editText.setTextColor(textColor.toArgb())
|
||||
editText.textSize = textStyle.value.fontSize.value
|
||||
editText.textSize = textStyle.value.fontSize.value * appPrefs.fontScale.get()
|
||||
val drawable = androidAppContext.getDrawable(R.drawable.send_msg_view_background)!!
|
||||
DrawableCompat.setTint(drawable, tintColor.toArgb())
|
||||
editText.background = drawable
|
||||
@@ -135,7 +136,7 @@ actual fun PlatformTextField(
|
||||
editText
|
||||
}) {
|
||||
it.setTextColor(textColor.toArgb())
|
||||
it.textSize = textStyle.value.fontSize.value
|
||||
it.textSize = textStyle.value.fontSize.value * appPrefs.fontScale.get()
|
||||
DrawableCompat.setTint(it.background, tintColor.toArgb())
|
||||
it.isFocusable = composeState.value.preview !is ComposePreview.VoicePreview
|
||||
it.isFocusableInTouchMode = it.isFocusable
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user