mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3bd47130e7 | |||
| 12c1b348fe | |||
| ecc8a42b66 | |||
| cd5bb4c146 | |||
| 64f4bcc6fc | |||
| 060d3dd4d4 | |||
| cea3aad0d4 | |||
| f43a2d070b | |||
| 69ad380245 | |||
| 3133d01690 | |||
| 69da8b6345 | |||
| f053447f5f | |||
| a57a2c277d | |||
| 670bf34ff5 | |||
| 3e873fcb32 | |||
| 23f24b1677 | |||
| 17526fa385 | |||
| 70204e071d | |||
| b348979b32 | |||
| 71ad8f2fd1 | |||
| 2dff94cbb4 | |||
| a73abfe642 | |||
| 859fa0bc22 | |||
| 41c4f13939 | |||
| f84ac713d7 |
@@ -74,6 +74,7 @@ final class ChatModel: ObservableObject {
|
||||
@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] = []
|
||||
@@ -195,6 +196,18 @@ final class ChatModel: ObservableObject {
|
||||
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? {
|
||||
chats.firstIndex(where: { $0.id == id })
|
||||
}
|
||||
@@ -390,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) {
|
||||
@@ -536,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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -558,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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -188,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)
|
||||
@@ -201,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)
|
||||
|
||||
@@ -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
|
||||
@@ -122,7 +121,7 @@ struct ChatView: View {
|
||||
chatModel.reversedChatItems = []
|
||||
chatModel.groupMembers = []
|
||||
chatModel.groupMembersIndexes.removeAll()
|
||||
membersLoaded = false
|
||||
chatModel.membersLoaded = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,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)
|
||||
@@ -250,19 +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) }
|
||||
chatModel.populateGroupMembersIndexes()
|
||||
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.
|
||||
@@ -477,9 +464,7 @@ struct ChatView: View {
|
||||
.foregroundColor(theme.colors.primary)
|
||||
}
|
||||
.onTapGesture {
|
||||
if let latestUnreadItem = filtered(chatModel.reversedChatItems).last(where: { $0.isRcvNew }) {
|
||||
scrollModel.scrollToItem(id: latestUnreadItem.id)
|
||||
}
|
||||
scrollModel.scrollToBottom()
|
||||
}
|
||||
} else if !counts.isNearBottom {
|
||||
circleButton {
|
||||
@@ -534,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")
|
||||
@@ -604,11 +589,9 @@ struct ChatView: View {
|
||||
chat: chat,
|
||||
chatItem: ci,
|
||||
maxWidth: maxWidth,
|
||||
itemWidth: maxWidth,
|
||||
composeState: $composeState,
|
||||
selectedMember: $selectedMember,
|
||||
revealedChatItem: $revealedChatItem,
|
||||
chatView: self
|
||||
revealedChatItem: $revealedChatItem
|
||||
)
|
||||
}
|
||||
|
||||
@@ -616,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
|
||||
@@ -700,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)
|
||||
}
|
||||
}
|
||||
@@ -1099,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
|
||||
|
||||
@@ -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
|
||||
@@ -47,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 {
|
||||
@@ -183,6 +167,8 @@ struct ServersSummaryView: View {
|
||||
}
|
||||
} else {
|
||||
Text("No info, try to reload")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.background(theme.colors.background)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,7 +355,6 @@ struct ServersSummaryView: View {
|
||||
Task {
|
||||
do {
|
||||
try await resetAgentServersStats()
|
||||
getServersSummary()
|
||||
} catch let error {
|
||||
alert = SomeAlert(
|
||||
alert: mkAlert(
|
||||
@@ -389,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 {
|
||||
@@ -734,5 +711,7 @@ struct DetailedXFTPStatsView: View {
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ServersSummaryView()
|
||||
ServersSummaryView(
|
||||
serversSummary: Binding.constant(nil)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -615,9 +615,9 @@
|
||||
<target>Добави сървъри чрез сканиране на QR кодове.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Добави сървър…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Добави сървър</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -596,9 +596,9 @@
|
||||
<target>Přidejte servery skenováním QR kódů.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Přidat server…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Přidat server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -615,9 +615,9 @@
|
||||
<target>Fügen Sie Server durch Scannen der QR Codes hinzu.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Füge Server hinzu…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Füge Server hinzu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -1152,7 +1152,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Cellular" xml:space="preserve">
|
||||
<source>Cellular</source>
|
||||
<target>Zellulär</target>
|
||||
<target>Mobilfunknetz</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Change" xml:space="preserve">
|
||||
@@ -1837,6 +1837,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Debugging-Zustellung</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3922,6 +3923,7 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Nachrichten-Warteschlangen-Information</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -4817,7 +4819,7 @@ Fehler: %@</target>
|
||||
<trans-unit id="Protect your IP address from the messaging relays chosen by your contacts. Enable in *Network & servers* settings." xml:space="preserve">
|
||||
<source>Protect your IP address from the messaging relays chosen by your contacts.
|
||||
Enable in *Network & servers* settings.</source>
|
||||
<target>Schützen Sie Ihre IP-Adresse vor den Nachrichten-Relais , die Ihre Kontakte ausgewählt haben.
|
||||
<target>Schützen Sie Ihre IP-Adresse vor den Nachrichten-Relais, die Ihre Kontakte ausgewählt haben.
|
||||
Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
@@ -8103,6 +8105,9 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>Server-Warteschlangen-Information: %1$@
|
||||
|
||||
Zuletzt empfangene Nachricht: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -618,9 +618,9 @@
|
||||
<target>Add servers by scanning QR codes.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Add server…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Add server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -615,9 +615,9 @@
|
||||
<target>Añadir servidores mediante el escaneo de códigos QR.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Añadir servidor…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Añadir servidor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -1507,7 +1507,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection error (AUTH)" xml:space="preserve">
|
||||
<source>Connection error (AUTH)</source>
|
||||
<target>Error conexión (Autenticación)</target>
|
||||
<target>Error de conexión (Autenticación)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection request sent!" xml:space="preserve">
|
||||
@@ -1522,7 +1522,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection timeout" xml:space="preserve">
|
||||
<source>Connection timeout</source>
|
||||
<target>Tiempo de conexión expirado</target>
|
||||
<target>Tiempo de conexión agotado</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection with desktop stopped" xml:space="preserve">
|
||||
@@ -1837,6 +1837,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Informe debug</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3333,7 +3334,7 @@ Error: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
|
||||
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
|
||||
<target>Si no puedes reunirte en persona, muestra el código QR por videollamada, o comparte el enlace.</target>
|
||||
<target>Si no puedes reunirte en persona, muestra el código QR por videollamada o comparte el enlace.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="If you enter this passcode when opening the app, all app data will be irreversibly removed!" xml:space="preserve">
|
||||
@@ -3922,6 +3923,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Información cola de mensajes</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -4323,7 +4325,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>Enlace único de invitación de un uso</target>
|
||||
<target>Enlace de invitación de un solo uso</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Onion hosts will be required for connection. Requires enabling VPN." xml:space="preserve">
|
||||
@@ -4467,7 +4469,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Or scan QR code" xml:space="preserve">
|
||||
<source>Or scan QR code</source>
|
||||
<target>O escanear código QR</target>
|
||||
<target>O escanea el código QR</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Or securely share this file link" xml:space="preserve">
|
||||
@@ -4477,7 +4479,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Or show this code" xml:space="preserve">
|
||||
<source>Or show this code</source>
|
||||
<target>O mostrar este código</target>
|
||||
<target>O muestra este código QR</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Other" xml:space="preserve">
|
||||
@@ -4547,7 +4549,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Paste the link you received" xml:space="preserve">
|
||||
<source>Paste the link you received</source>
|
||||
<target>Pegar el enlace recibido</target>
|
||||
<target>Pega el enlace recibido</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Pending" xml:space="preserve">
|
||||
@@ -4561,7 +4563,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Periodically" xml:space="preserve">
|
||||
<source>Periodically</source>
|
||||
<target>Periódico</target>
|
||||
<target>Periódicamente</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Permanent decryption error" xml:space="preserve">
|
||||
@@ -4828,12 +4830,12 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Protocol timeout" xml:space="preserve">
|
||||
<source>Protocol timeout</source>
|
||||
<target>Tiempo de espera del protocolo</target>
|
||||
<target>Timeout protocolo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Protocol timeout per KB" xml:space="preserve">
|
||||
<source>Protocol timeout per KB</source>
|
||||
<target>Límite de espera del protocolo por KB</target>
|
||||
<target>Timeout protocolo por KB</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proxied" xml:space="preserve">
|
||||
@@ -4876,32 +4878,32 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
<target>Saber más</target>
|
||||
<target>Conoce más</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address)." xml:space="preserve">
|
||||
<source>Read more in [User Guide](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address).</source>
|
||||
<target>Saber más en el [Manual del Usuario](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address).</target>
|
||||
<target>Conoce más en el [Manual del Usuario](https://simplex.chat/docs/guide/app-settings.html#your-simplex-contact-address).</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode)." xml:space="preserve">
|
||||
<source>Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode).</source>
|
||||
<target>Saber más en [Guía de Usuario](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode).</target>
|
||||
<target>Conoce más en la [Guía del Usuario](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode).</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends)." xml:space="preserve">
|
||||
<source>Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends).</source>
|
||||
<target>Saber más en el [Manual del Usuario](https://simplex.chat/docs/guide/readme.html#connect-to-friends).</target>
|
||||
<target>Conoce más en el [Manual del Usuario](https://simplex.chat/docs/guide/readme.html#connect-to-friends).</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more in our GitHub repository." xml:space="preserve">
|
||||
<source>Read more in our GitHub repository.</source>
|
||||
<target>Saber más en nuestro repositorio GitHub.</target>
|
||||
<target>Conoce más en nuestro repositorio GitHub.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme)." xml:space="preserve">
|
||||
<source>Read more in our [GitHub repository](https://github.com/simplex-chat/simplex-chat#readme).</source>
|
||||
<target>Saber más en nuestro [repositorio GitHub](https://github.com/simplex-chat/simplex-chat#readme).</target>
|
||||
<target>Conoce más en nuestro [repositorio GitHub](https://github.com/simplex-chat/simplex-chat#readme).</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Receipts are disabled" xml:space="preserve">
|
||||
@@ -5755,7 +5757,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<target>Compartir este enlace de un uso</target>
|
||||
<target>Comparte este enlace de un solo uso</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share with contacts" xml:space="preserve">
|
||||
@@ -6037,7 +6039,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="TCP connection timeout" xml:space="preserve">
|
||||
<source>TCP connection timeout</source>
|
||||
<target>Tiempo de espera de la conexión TCP agotado</target>
|
||||
<target>Timeout de la conexión TCP</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TCP_KEEPCNT" xml:space="preserve">
|
||||
@@ -6087,7 +6089,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tap to paste link" xml:space="preserve">
|
||||
<source>Tap to paste link</source>
|
||||
<target>Pulsa para pegar enlace</target>
|
||||
<target>Pulsa para pegar el enlacePulsa para pegar enlace</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tap to scan" xml:space="preserve">
|
||||
@@ -6355,7 +6357,7 @@ Puede ocurrir por algún bug o cuando la conexión está comprometida.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="To protect your IP address, private routing uses your SMP servers to deliver messages." xml:space="preserve">
|
||||
<source>To protect your IP address, private routing uses your SMP servers to deliver messages.</source>
|
||||
<target>Para proteger tu dirección IP, el enrutamiento privado usa tus servidores SMP para enviar mensajes.</target>
|
||||
<target>Para proteger tu dirección IP, el enrutamiento privado usa tu lista de servidores SMP para enviar mensajes.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To protect your information, turn on SimpleX Lock. You will be prompted to complete authentication before this feature is enabled." xml:space="preserve">
|
||||
@@ -6516,9 +6518,8 @@ Se te pedirá que completes la autenticación antes de activar esta función.</t
|
||||
<trans-unit id="Unless your contact deleted the connection or this link was already used, it might be a bug - please report it. To connect, please ask your contact to create another connection link and check that you have a stable network connection." xml:space="preserve">
|
||||
<source>Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.
|
||||
To connect, please ask your contact to create another connection link and check that you have a stable network connection.</source>
|
||||
<target>A menos que tu contacto haya eliminado la conexión o
|
||||
que este enlace ya se haya usado, podría ser un error. Por favor, notifícalo.
|
||||
Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueba que tienes buena conexión de red.</target>
|
||||
<target>A menos que tu contacto haya eliminado la conexión o el enlace haya sido usado, podría ser un error. Por favor, notifícalo.
|
||||
Para conectarte pide a tu contacto que cree otro enlace y comprueba la conexión de red.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unlink" xml:space="preserve">
|
||||
@@ -6670,12 +6671,12 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb
|
||||
</trans-unit>
|
||||
<trans-unit id="Use private routing with unknown servers when IP address is not protected." xml:space="preserve">
|
||||
<source>Use private routing with unknown servers when IP address is not protected.</source>
|
||||
<target>Usar enrutamiento privado con servidores desconocidos cuando la dirección IP no está protegida.</target>
|
||||
<target>Usar enrutamiento privado con servidores desconocidos cuando tu dirección IP no está protegida.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Use private routing with unknown servers." xml:space="preserve">
|
||||
<source>Use private routing with unknown servers.</source>
|
||||
<target>Usar enrutamiento privado con servidores desconocidos.</target>
|
||||
<target>Usar enrutamiento privado con servidores de retransmisión desconocidos.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Use server" xml:space="preserve">
|
||||
@@ -7218,7 +7219,7 @@ Repeat connection request?</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="You will be required to authenticate when you start or resume the app after 30 seconds in background." xml:space="preserve">
|
||||
<source>You will be required to authenticate when you start or resume the app after 30 seconds in background.</source>
|
||||
<target>Se te pedirá identificarte cuándo inicies o continues usando la aplicación tras 30 segundos en segundo plano.</target>
|
||||
<target>Se te pedirá autenticarte cuando inicies la aplicación o sigas usándola tras 30 segundos en segundo plano.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You will connect to all group members." xml:space="preserve">
|
||||
@@ -7351,8 +7352,8 @@ Puedes cancelarla y eliminar el contacto (e intentarlo más tarde con un enlace
|
||||
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
|
||||
<source>Your profile is stored on your device and shared only with your contacts.
|
||||
SimpleX servers cannot see your profile.</source>
|
||||
<target>Tu perfil se almacena en tu dispositivo y sólo se comparte con tus contactos.
|
||||
Los servidores de SimpleX no pueden ver tu perfil.</target>
|
||||
<target>Tu perfil es almacenado en tu dispositivo y solamente se comparte con tus contactos.
|
||||
Los servidores SimpleX no pueden ver tu perfil.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
|
||||
@@ -8104,6 +8105,9 @@ Los servidores de SimpleX no pueden ver tu perfil.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>información cola del servidor: %1$@
|
||||
|
||||
último mensaje recibido: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
@@ -8148,7 +8152,7 @@ last received msg: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="unknown relays" xml:space="preserve">
|
||||
<source>unknown relays</source>
|
||||
<target>servidor de retransmisión desconocido</target>
|
||||
<target>con servidores desconocidos</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="unknown status" xml:space="preserve">
|
||||
@@ -8158,7 +8162,7 @@ last received msg: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="unprotected" xml:space="preserve">
|
||||
<source>unprotected</source>
|
||||
<target>desprotegido</target>
|
||||
<target>con IP desprotegida</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="updated group profile" xml:space="preserve">
|
||||
|
||||
@@ -591,9 +591,9 @@
|
||||
<target>Lisää palvelimia skannaamalla QR-koodeja.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Lisää palvelin…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Lisää palvelin</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -615,9 +615,9 @@
|
||||
<target>Ajoutez des serveurs en scannant des codes QR.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Ajouter un serveur…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Ajouter un serveur</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -1837,6 +1837,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Livraison de débogage</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3922,6 +3923,7 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Informations sur la file d'attente des messages</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -8103,6 +8105,9 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>info sur la file d'attente du serveur : %1$@
|
||||
|
||||
dernier message reçu : %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -403,9 +403,9 @@ Available in v5.1</source>
|
||||
<target state="translated">הוספת שרתים על ידי סריקת קוד QR.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve" approved="no">
|
||||
<source>Add server…</source>
|
||||
<target state="translated">הוסף שרת…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve" approved="no">
|
||||
<source>Add server</source>
|
||||
<target state="translated">הוסף שרת</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve" approved="no">
|
||||
|
||||
@@ -300,8 +300,8 @@
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -367,8 +367,8 @@
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -497,7 +497,7 @@
|
||||
<source><p>Hi!</p>
|
||||
<p><a href="%@">Connect to me via SimpleX Chat</a></p></source>
|
||||
<target><p>Üdvözlöm!</p>
|
||||
<p><a href="%@">Csatlakozzon hozzám a SimpleX Chaten</a></p></target>
|
||||
<p><a href=„%@”>Csatlakozzon hozzám a SimpleX Chaten</a></p></target>
|
||||
<note>email text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="A few more things" xml:space="preserve">
|
||||
@@ -544,17 +544,17 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="About SimpleX" xml:space="preserve">
|
||||
<source>About SimpleX</source>
|
||||
<target>A SimpleX névjegye</target>
|
||||
<target>A SimpleX-ről</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="About SimpleX Chat" xml:space="preserve">
|
||||
<source>About SimpleX Chat</source>
|
||||
<target>A SimpleX Chat névjegye</target>
|
||||
<target>A SimpleX Chat-ről</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="About SimpleX address" xml:space="preserve">
|
||||
<source>About SimpleX address</source>
|
||||
<target>A SimpleX azonosítóról</target>
|
||||
<target>A SimpleX címről</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accent" xml:space="preserve">
|
||||
@@ -592,7 +592,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts." xml:space="preserve">
|
||||
<source>Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts.</source>
|
||||
<target>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.</target>
|
||||
<target>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.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add contact" xml:space="preserve">
|
||||
@@ -615,9 +615,9 @@
|
||||
<target>Kiszolgáló hozzáadása QR-kód beolvasásával.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Kiszolgáló hozzáadása…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Kiszolgáló hozzáadása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -766,7 +766,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow sending direct messages to members." xml:space="preserve">
|
||||
<source>Allow sending direct messages to members.</source>
|
||||
<target>Közvetlen üzenetek küldésének engedélyezése a tagok számára.</target>
|
||||
<target>A közvetlen üzenetek küldése a tagok között engedélyezve van.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow sending disappearing messages." xml:space="preserve">
|
||||
@@ -999,7 +999,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Bad desktop address" xml:space="preserve">
|
||||
<source>Bad desktop address</source>
|
||||
<target>Hibás számítógép azonosító</target>
|
||||
<target>Hibás számítógép cím</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Bad message ID" xml:space="preserve">
|
||||
@@ -1033,7 +1033,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Block for all" xml:space="preserve">
|
||||
<source>Block for all</source>
|
||||
<target>Mindenki számára letiltva</target>
|
||||
<target>Letiltás mindenki számára</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block group members" xml:space="preserve">
|
||||
@@ -1108,7 +1108,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Camera not available" xml:space="preserve">
|
||||
<source>Camera not available</source>
|
||||
<target>A fényképező nem elérhető</target>
|
||||
<target>A kamera nem elérhető</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't invite contact!" xml:space="preserve">
|
||||
@@ -1428,7 +1428,7 @@
|
||||
<source>Connect to yourself?
|
||||
This is your own SimpleX address!</source>
|
||||
<target>Kapcsolódás saját magához?
|
||||
Ez a SimpleX azonosítója!</target>
|
||||
Ez az ön SimpleX címe!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself? This is your own one-time link!" xml:space="preserve">
|
||||
@@ -1440,7 +1440,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect via contact address" xml:space="preserve">
|
||||
<source>Connect via contact address</source>
|
||||
<target>Kapcsolódás a kapcsolattartási azonosítón keresztül</target>
|
||||
<target>Kapcsolódás a kapcsolattartási címen keresztül</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect via link" xml:space="preserve">
|
||||
@@ -1613,7 +1613,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Create SimpleX address" xml:space="preserve">
|
||||
<source>Create SimpleX address</source>
|
||||
<target>SimpleX azonosító létrehozása</target>
|
||||
<target>SimpleX cím létrehozása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Create a group using a random profile." xml:space="preserve">
|
||||
@@ -1623,7 +1623,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
|
||||
<source>Create an address to let people connect with you.</source>
|
||||
<target>Azonosító létrehozása, hogy az emberek kapcsolatba léphessenek önnel.</target>
|
||||
<target>Cím létrehozása, hogy az emberek kapcsolatba léphessenek önnel.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Create file" xml:space="preserve">
|
||||
@@ -1837,6 +1837,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Kézbesítési hibák felderítése</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -1866,12 +1867,12 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete address" xml:space="preserve">
|
||||
<source>Delete address</source>
|
||||
<target>Azonosító törlése</target>
|
||||
<target>Cím törlése</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete address?" xml:space="preserve">
|
||||
<source>Delete address?</source>
|
||||
<target>Azonosító törlése?</target>
|
||||
<target>Cím törlése?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete after" xml:space="preserve">
|
||||
@@ -2081,7 +2082,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Desktop address" xml:space="preserve">
|
||||
<source>Desktop address</source>
|
||||
<target>Számítógép azonosítója</target>
|
||||
<target>Számítógép címe</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
|
||||
@@ -2239,7 +2240,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Don't create address" xml:space="preserve">
|
||||
<source>Don't create address</source>
|
||||
<target>Ne hozzon létre azonosítót</target>
|
||||
<target>Ne hozzon létre címet</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Don't enable" xml:space="preserve">
|
||||
@@ -2331,7 +2332,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Enable TCP keep-alive" xml:space="preserve">
|
||||
<source>Enable TCP keep-alive</source>
|
||||
<target>TCP életben tartásának engedélyezése</target>
|
||||
<target>TCP életben tartása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Enable automatic message deletion?" xml:space="preserve">
|
||||
@@ -2521,7 +2522,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error aborting address change" xml:space="preserve">
|
||||
<source>Error aborting address change</source>
|
||||
<target>Hiba az azonosító megváltoztatásának megszakításakor</target>
|
||||
<target>Hiba a cím megváltoztatásának megszakításakor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error accepting contact request" xml:space="preserve">
|
||||
@@ -2541,7 +2542,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing address" xml:space="preserve">
|
||||
<source>Error changing address</source>
|
||||
<target>Hiba az azonosító megváltoztatásakor</target>
|
||||
<target>Hiba a cím megváltoztatásakor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
@@ -2556,7 +2557,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error creating address" xml:space="preserve">
|
||||
<source>Error creating address</source>
|
||||
<target>Hiba az azonosító létrehozásakor</target>
|
||||
<target>Hiba a cím létrehozásakor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error creating group" xml:space="preserve">
|
||||
@@ -2712,7 +2713,7 @@ Ez a művelet nem vonható vissza!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error saving group profile" xml:space="preserve">
|
||||
<source>Error saving group profile</source>
|
||||
<target>Hiba a csoport profil mentésekor</target>
|
||||
<target>Hiba a csoportprofil mentésekor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error saving passcode" xml:space="preserve">
|
||||
@@ -3223,7 +3224,7 @@ Hiba: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Group profile" xml:space="preserve">
|
||||
<source>Group profile</source>
|
||||
<target>Csoport profil</target>
|
||||
<target>Csoportprofil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Group profile is stored on members' devices, not on the servers." xml:space="preserve">
|
||||
@@ -3826,12 +3827,12 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Make sure %@ server addresses are in correct format, line separated and are not duplicated (%@)." xml:space="preserve">
|
||||
<source>Make sure %@ server addresses are in correct format, line separated and are not duplicated (%@).</source>
|
||||
<target>Győződjön meg arról, hogy a %@ kiszolgálócímek megfelelő formátumúak, sorszeparáltak és nem duplikáltak (%@).</target>
|
||||
<target>Győződjön meg arról, hogy a %@ kiszolgálócímek megfelelő formátumúak, sorszeparáltak és nincsenek duplikálva (%@).</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated." xml:space="preserve">
|
||||
<source>Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated.</source>
|
||||
<target>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.</target>
|
||||
<target>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.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*" xml:space="preserve">
|
||||
@@ -3875,12 +3876,12 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member role will be changed to "%@". All group members will be notified." xml:space="preserve">
|
||||
<source>Member role will be changed to "%@". All group members will be notified.</source>
|
||||
<target>A tag szerepköre meg fog változni erre: "%@". A csoport minden tagja értesítést kap róla.</target>
|
||||
<target>A tag szerepköre meg fog változni erre: „%@”. A csoport minden tagja értesítést kap róla.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member role will be changed to "%@". The member will receive a new invitation." xml:space="preserve">
|
||||
<source>Member role will be changed to "%@". The member will receive a new invitation.</source>
|
||||
<target>A tag szerepköre meg fog változni erre: "%@". A tag új meghívást fog kapni.</target>
|
||||
<target>A tag szerepköre meg fog változni erre: „%@”. A tag új meghívást fog kapni.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Member will be removed from group - this cannot be undone!" xml:space="preserve">
|
||||
@@ -3922,6 +3923,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Üzenet-várakoztatási információ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -4293,7 +4295,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
- disable members ("observer" role)</source>
|
||||
<target>Most már az adminok is:
|
||||
- törölhetik a tagok üzeneteit.
|
||||
- letilthatnak tagokat ("megfigyelő" szerepkör)</target>
|
||||
- letilthatnak tagokat („megfigyelő” szerepkör)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="OK" xml:space="preserve">
|
||||
@@ -4527,12 +4529,12 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Past member %@" xml:space="preserve">
|
||||
<source>Past member %@</source>
|
||||
<target>Korábbi csoport tag %@</target>
|
||||
<target>Már nem tag - %@</target>
|
||||
<note>past/unknown group member</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Paste desktop address" xml:space="preserve">
|
||||
<source>Paste desktop address</source>
|
||||
<target>Számítógép azonosítójának beillesztése</target>
|
||||
<target>Számítógép címének beillesztése</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Paste image" xml:space="preserve">
|
||||
@@ -4786,7 +4788,7 @@ Hiba: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Prohibit sending direct messages to members." xml:space="preserve">
|
||||
<source>Prohibit sending direct messages to members.</source>
|
||||
<target>A közvetlen üzenetek küldése le van tiltva a tagok között.</target>
|
||||
<target>A közvetlen üzenetek küldése a tagok között le van tiltva.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Prohibit sending disappearing messages." xml:space="preserve">
|
||||
@@ -4806,7 +4808,7 @@ Hiba: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Protect IP address" xml:space="preserve">
|
||||
<source>Protect IP address</source>
|
||||
<target>Az IP-cím védelme</target>
|
||||
<target>IP-cím védelem</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Protect app screen" xml:space="preserve">
|
||||
@@ -5037,12 +5039,12 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Relay server is only used if necessary. Another party can observe your IP address." xml:space="preserve">
|
||||
<source>Relay server is only used if necessary. Another party can observe your IP address.</source>
|
||||
<target>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.</target>
|
||||
<target>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.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Relay server protects your IP address, but it can observe the duration of the call." xml:space="preserve">
|
||||
<source>Relay server protects your IP address, but it can observe the duration of the call.</source>
|
||||
<target>Az átjátszó kiszolgáló megvédi IP-címét, de megfigyelheti a hívás időtartamát.</target>
|
||||
<target>Az átjátszó kiszolgáló megvédi az IP-címet, de megfigyelheti a hívás időtartamát.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove" xml:space="preserve">
|
||||
@@ -5192,7 +5194,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Revert" xml:space="preserve">
|
||||
<source>Revert</source>
|
||||
<target>Visszaállít</target>
|
||||
<target>Visszaállítás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Revoke" xml:space="preserve">
|
||||
@@ -5226,7 +5228,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="SMP servers" xml:space="preserve">
|
||||
<source>SMP servers</source>
|
||||
<target>Üzenetküldő (SMP) kiszolgálók</target>
|
||||
<target>SMP kiszolgálók</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Safely receive files" xml:space="preserve">
|
||||
@@ -5261,7 +5263,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Save and update group profile" xml:space="preserve">
|
||||
<source>Save and update group profile</source>
|
||||
<target>Mentés és a csoport profil frissítése</target>
|
||||
<target>Mentés és csoportprofil frissítése</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save archive" xml:space="preserve">
|
||||
@@ -5276,7 +5278,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Save group profile" xml:space="preserve">
|
||||
<source>Save group profile</source>
|
||||
<target>Csoport profil elmentése</target>
|
||||
<target>Csoportprofil elmentése</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save passphrase and open chat" xml:space="preserve">
|
||||
@@ -5740,12 +5742,12 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Share address" xml:space="preserve">
|
||||
<source>Share address</source>
|
||||
<target>Azonosító megosztása</target>
|
||||
<target>Cím megosztása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share address with contacts?" xml:space="preserve">
|
||||
<source>Share address with contacts?</source>
|
||||
<target>Megosztja az azonosítót az ismerőseivel?</target>
|
||||
<target>Megosztja a címet az ismerőseivel?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
@@ -5809,7 +5811,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX Address" xml:space="preserve">
|
||||
<source>SimpleX Address</source>
|
||||
<target>SimpleX azonosító</target>
|
||||
<target>SimpleX cím</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX Chat security was audited by Trail of Bits." xml:space="preserve">
|
||||
@@ -5839,12 +5841,12 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX address" xml:space="preserve">
|
||||
<source>SimpleX address</source>
|
||||
<target>SimpleX azonosító</target>
|
||||
<target>SimpleX cím</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX contact address" xml:space="preserve">
|
||||
<source>SimpleX contact address</source>
|
||||
<target>SimpleX kapcsolattartási azonosító</target>
|
||||
<target>SimpleX kapcsolattartási cím</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX encrypted message or connection event" xml:space="preserve">
|
||||
@@ -6302,7 +6304,7 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="This is your own SimpleX address!" xml:space="preserve">
|
||||
<source>This is your own SimpleX address!</source>
|
||||
<target>Ez a SimpleX azonosítója!</target>
|
||||
<target>Ez az ön SimpleX címe!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="This is your own one-time link!" xml:space="preserve">
|
||||
@@ -6355,7 +6357,7 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="To protect your IP address, private routing uses your SMP servers to deliver messages." xml:space="preserve">
|
||||
<source>To protect your IP address, private routing uses your SMP servers to deliver messages.</source>
|
||||
<target>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.</target>
|
||||
<target>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.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To protect your information, turn on SimpleX Lock. You will be prompted to complete authentication before this feature is enabled." xml:space="preserve">
|
||||
@@ -6974,7 +6976,7 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol
|
||||
</trans-unit>
|
||||
<trans-unit id="You accepted connection" xml:space="preserve">
|
||||
<source>You accepted connection</source>
|
||||
<target>Kapcsolódás elfogadva</target>
|
||||
<target>Kapcsolat létrehozása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You allow" xml:space="preserve">
|
||||
@@ -7095,12 +7097,12 @@ Csatlakozási kérés megismétlése?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can share this address with your contacts to let them connect with **%@**." xml:space="preserve">
|
||||
<source>You can share this address with your contacts to let them connect with **%@**.</source>
|
||||
<target>Megoszthatja ezt az azonosítót az ismerőseivel, hogy kapcsolatba léphessenek önnel a **%@** nevű profilján keresztül.</target>
|
||||
<target>Megoszthatja ezt a címet az ismerőseivel, hogy kapcsolatba léphessenek önnel a(z) **%@** nevű profilján keresztül.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can share your address as a link or QR code - anybody can connect to you." xml:space="preserve">
|
||||
<source>You can share your address as a link or QR code - anybody can connect to you.</source>
|
||||
<target>Megoszthatja azonosítóját hivatkozásként vagy QR-kódként – így bárki kapcsolódhat önhöz.</target>
|
||||
<target>Megoszthatja a címét egy hivatkozásként vagy QR-kódként – így bárki kapcsolódhat önhöz.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can start chat via app Settings / Database or by restarting the app" xml:space="preserve">
|
||||
@@ -7140,7 +7142,7 @@ Csatlakozási kérés megismétlése?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You have already requested connection via this address!" xml:space="preserve">
|
||||
<source>You have already requested connection via this address!</source>
|
||||
<target>Már kért egy kapcsolódási kérelmet ezen az azonosítón keresztül!</target>
|
||||
<target>Már kért egy kapcsolódási kérelmet ezen a címen keresztül!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You have already requested connection! Repeat connection request?" xml:space="preserve">
|
||||
@@ -7237,7 +7239,7 @@ Kapcsolódási kérés megismétlése?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You won't lose your contacts if you later delete your address." xml:space="preserve">
|
||||
<source>You won't lose your contacts if you later delete your address.</source>
|
||||
<target>Nem veszíti el az ismerőseit, ha később törli az azonosítóját.</target>
|
||||
<target>Nem veszíti el az ismerőseit, ha később törli a címét.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You're trying to invite contact with whom you've shared an incognito profile to the group in which you're using your main profile" xml:space="preserve">
|
||||
@@ -7267,7 +7269,7 @@ Kapcsolódási kérés megismétlése?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your SimpleX address" xml:space="preserve">
|
||||
<source>Your SimpleX address</source>
|
||||
<target>SimpleX azonosítója</target>
|
||||
<target>Az ön SimpleX címe</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your XFTP servers" xml:space="preserve">
|
||||
@@ -7446,7 +7448,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="and %lld other events" xml:space="preserve">
|
||||
<source>and %lld other events</source>
|
||||
<target>és %lld további esemény</target>
|
||||
<target>és további %lld esemény</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="attempts" xml:space="preserve">
|
||||
@@ -7480,7 +7482,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="blocked %@" xml:space="preserve">
|
||||
<source>blocked %@</source>
|
||||
<target>%@ letiltva</target>
|
||||
<target>letiltotta őt: %@</target>
|
||||
<note>rcv group event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
@@ -7530,12 +7532,12 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="changing address for %@…" xml:space="preserve">
|
||||
<source>changing address for %@…</source>
|
||||
<target>cím módosítása %@ számára…</target>
|
||||
<target>cím megváltoztatása nála: %@…</target>
|
||||
<note>chat item text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="changing address…" xml:space="preserve">
|
||||
<source>changing address…</source>
|
||||
<target>azonosító megváltoztatása…</target>
|
||||
<target>cím megváltoztatása…</target>
|
||||
<note>chat item text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="colored" xml:space="preserve">
|
||||
@@ -7694,7 +7696,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="duplicate message" xml:space="preserve">
|
||||
<source>duplicate message</source>
|
||||
<target>duplikálódott üzenet</target>
|
||||
<target>duplikált üzenet</target>
|
||||
<note>integrity error chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="duplicates" xml:space="preserve">
|
||||
@@ -7797,7 +7799,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="group profile updated" xml:space="preserve">
|
||||
<source>group profile updated</source>
|
||||
<target>csoport profil frissítve</target>
|
||||
<target>csoportprofil frissítve</target>
|
||||
<note>snd group event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="hours" xml:space="preserve">
|
||||
@@ -7976,7 +7978,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="off" xml:space="preserve">
|
||||
<source>off</source>
|
||||
<target>ki</target>
|
||||
<target>kikapcsolva</target>
|
||||
<note>enabled status
|
||||
group pref value
|
||||
time to disappear</note>
|
||||
@@ -8051,7 +8053,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="removed contact address" xml:space="preserve">
|
||||
<source>removed contact address</source>
|
||||
<target>törölt kapcsolattartási azonosító</target>
|
||||
<target>törölt kapcsolattartási cím</target>
|
||||
<note>profile update event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="removed profile picture" xml:space="preserve">
|
||||
@@ -8103,16 +8105,19 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>kiszolgáló üzenet-várakotatási információ: %1$@
|
||||
|
||||
utoljára fogadott üzenet: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
<source>set new contact address</source>
|
||||
<target>új kapcsolattartási azonosító beállítása</target>
|
||||
<target>új kapcsolattartási cím beállítása</target>
|
||||
<note>profile update event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new profile picture" xml:space="preserve">
|
||||
<source>set new profile picture</source>
|
||||
<target>új profilkép beállítása</target>
|
||||
<target>új profilképet állított be</target>
|
||||
<note>profile update event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="standard end-to-end encryption" xml:space="preserve">
|
||||
@@ -8182,7 +8187,7 @@ last received msg: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="via contact address link" xml:space="preserve">
|
||||
<source>via contact address link</source>
|
||||
<target>kapcsolattartási azonosító-hivatkozáson keresztül</target>
|
||||
<target>kapcsolattartási cím-hivatkozáson keresztül</target>
|
||||
<note>chat list item description</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="via group link" xml:space="preserve">
|
||||
@@ -8257,12 +8262,12 @@ last received msg: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="you changed address" xml:space="preserve">
|
||||
<source>you changed address</source>
|
||||
<target>azonosítója megváltoztatva</target>
|
||||
<target>cím megváltoztatva</target>
|
||||
<note>chat item text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="you changed address for %@" xml:space="preserve">
|
||||
<source>you changed address for %@</source>
|
||||
<target>%@ azonosítója megváltoztatva</target>
|
||||
<target>cím megváltoztatva nála: %@</target>
|
||||
<note>chat item text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="you changed role for yourself to %@" xml:space="preserve">
|
||||
|
||||
@@ -615,9 +615,9 @@
|
||||
<target>Aggiungi server scansionando codici QR.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Aggiungi server…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Aggiungi server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -1837,6 +1837,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Debug della consegna</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3922,6 +3923,7 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Info coda messaggi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -4702,7 +4704,7 @@ Errore: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private message routing" xml:space="preserve">
|
||||
<source>Private message routing</source>
|
||||
<target>Instradamento privato messaggi</target>
|
||||
<target>Instradamento privato dei messaggi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Private message routing 🚀" xml:space="preserve">
|
||||
@@ -8103,6 +8105,9 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>info coda server: %1$@
|
||||
|
||||
ultimo msg ricevuto: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -608,9 +608,9 @@
|
||||
<target>QRコードでサーバを追加する。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>サーバを追加…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>サーバを追加</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -615,9 +615,9 @@
|
||||
<target>Servers toevoegen door QR-codes te scannen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Server toevoegen…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Server toevoegen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -1837,6 +1837,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Foutopsporing bezorging</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3922,6 +3923,7 @@ Dit is jouw link voor groep %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Informatie over berichtenwachtrij</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -8103,6 +8105,9 @@ SimpleX servers kunnen uw profiel niet zien.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>informatie over serverwachtrij: %1$@
|
||||
|
||||
laatst ontvangen bericht: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -615,9 +615,9 @@
|
||||
<target>Dodaj serwery, skanując kody QR.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Dodaj serwer…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Dodaj serwer</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -1837,6 +1837,7 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Dostarczenie debugowania</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3922,6 +3923,7 @@ To jest twój link do grupy %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Informacje kolejki wiadomości</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -8103,6 +8105,9 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>Informacje kolejki serwera: %1$@
|
||||
|
||||
ostatnia otrzymana wiadomość: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -374,9 +374,9 @@
|
||||
<target state="translated">Adicione servidores escaneando o QR code.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve" approved="no">
|
||||
<source>Add server…</source>
|
||||
<target state="translated">Adicionar servidor…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve" approved="no">
|
||||
<source>Add server</source>
|
||||
<target state="translated">Adicionar servidor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve" approved="no">
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
<tool tool-id="com.apple.dt.xcode" tool-name="Xcode" tool-version="14.2" build-num="14C18"/>
|
||||
</header>
|
||||
<body>
|
||||
<trans-unit id=" " xml:space="preserve">
|
||||
<trans-unit id=" " xml:space="preserve" approved="no">
|
||||
<source>
|
||||
</source>
|
||||
<target state="needs-translation">
|
||||
</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id=" Available in v5.1" xml:space="preserve">
|
||||
@@ -50,16 +52,19 @@ Available in v5.1</source>
|
||||
<target state="translated">#secreto#</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@" xml:space="preserve">
|
||||
<trans-unit id="%@" xml:space="preserve" approved="no">
|
||||
<source>%@</source>
|
||||
<target state="needs-translation">%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ %@" xml:space="preserve">
|
||||
<trans-unit id="%@ %@" xml:space="preserve" approved="no">
|
||||
<source>%@ %@</source>
|
||||
<target state="needs-translation">%@ %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ / %@" xml:space="preserve">
|
||||
<trans-unit id="%@ / %@" xml:space="preserve" approved="no">
|
||||
<source>%@ / %@</source>
|
||||
<target state="needs-translation">%@ / %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ is connected!" xml:space="preserve" approved="no">
|
||||
@@ -117,12 +122,14 @@ Available in v5.1</source>
|
||||
<target state="translated">%d mensagem(s) ignorada(s)</target>
|
||||
<note>integrity error chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld" xml:space="preserve">
|
||||
<trans-unit id="%lld" xml:space="preserve" approved="no">
|
||||
<source>%lld</source>
|
||||
<target state="needs-translation">%lld</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld %@" xml:space="preserve">
|
||||
<trans-unit id="%lld %@" xml:space="preserve" approved="no">
|
||||
<source>%lld %@</source>
|
||||
<target state="needs-translation">%lld %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld contact(s) selected" xml:space="preserve" approved="no">
|
||||
@@ -155,24 +162,29 @@ Available in v5.1</source>
|
||||
<target state="translated">%lld segundos</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lldd" xml:space="preserve">
|
||||
<trans-unit id="%lldd" xml:space="preserve" approved="no">
|
||||
<source>%lldd</source>
|
||||
<target state="needs-translation">%lldd</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lldh" xml:space="preserve">
|
||||
<trans-unit id="%lldh" xml:space="preserve" approved="no">
|
||||
<source>%lldh</source>
|
||||
<target state="needs-translation">%lldh</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lldk" xml:space="preserve">
|
||||
<trans-unit id="%lldk" xml:space="preserve" approved="no">
|
||||
<source>%lldk</source>
|
||||
<target state="needs-translation">%lldk</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lldm" xml:space="preserve">
|
||||
<trans-unit id="%lldm" xml:space="preserve" approved="no">
|
||||
<source>%lldm</source>
|
||||
<target state="needs-translation">%lldm</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lldmth" xml:space="preserve">
|
||||
<trans-unit id="%lldmth" xml:space="preserve" approved="no">
|
||||
<source>%lldmth</source>
|
||||
<target state="needs-translation">%lldmth</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%llds" xml:space="preserve">
|
||||
@@ -193,8 +205,9 @@ Available in v5.1</source>
|
||||
<target state="translated">%u mensagens ignoradas.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="(" xml:space="preserve">
|
||||
<trans-unit id="(" xml:space="preserve" approved="no">
|
||||
<source>(</source>
|
||||
<target state="needs-translation">(</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id=")" xml:space="preserve">
|
||||
@@ -359,8 +372,8 @@ Available in v5.1</source>
|
||||
<source>Add servers by scanning QR codes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -4540,6 +4553,31 @@ SimpleX servers cannot see your profile.</source>
|
||||
<target state="translated">Confirmar envio</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ downloaded" xml:space="preserve" approved="no">
|
||||
<source>%@ downloaded</source>
|
||||
<target state="translated">%@ baixado</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="# %@" xml:space="preserve" approved="no">
|
||||
<source># %@</source>
|
||||
<target state="needs-translation"># %@</target>
|
||||
<note>copied message info title, # <title></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@:" xml:space="preserve" approved="no">
|
||||
<source>%@:</source>
|
||||
<target state="needs-translation">%@:</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ (current)" xml:space="preserve" approved="no">
|
||||
<source>%@ (current)</source>
|
||||
<target state="translated">%@(atual)</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ (current):" xml:space="preserve" approved="no">
|
||||
<source>%@ (current):</source>
|
||||
<target state="translated">%@ (atual):</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
<file original="en.lproj/SimpleX--iOS--InfoPlist.strings" source-language="en" target-language="pt" datatype="plaintext">
|
||||
|
||||
@@ -615,9 +615,9 @@
|
||||
<target>Добавить серверы через QR код.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Добавить сервер…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Добавить сервер</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -583,9 +583,9 @@
|
||||
<target>เพิ่มเซิร์ฟเวอร์โดยการสแกนรหัสคิวอาร์โค้ด</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>เพิ่มเซิร์ฟเวอร์…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>เพิ่มเซิร์ฟเวอร์</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -615,9 +615,9 @@
|
||||
<target>Karekod taratarak sunucuları ekleyin.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Sunucu ekle…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Sunucu ekle</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -1837,6 +1837,7 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Hata ayıklama teslimatı</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3922,6 +3923,7 @@ Bu senin grup için bağlantın %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Mesaj kuyruğu bilgisi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -8103,6 +8105,9 @@ SimpleX sunucuları profilinizi göremez.</target>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>sunucu kuyruk bilgisi: %1$@
|
||||
|
||||
son alınan msj: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -615,9 +615,9 @@
|
||||
<target>Додайте сервери, відсканувавши QR-код.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>Додати сервер…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>Додати сервер</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
@@ -1837,6 +1837,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Debug delivery" xml:space="preserve">
|
||||
<source>Debug delivery</source>
|
||||
<target>Доставка налагодження</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Decentralized" xml:space="preserve">
|
||||
@@ -3922,6 +3923,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message queue info" xml:space="preserve">
|
||||
<source>Message queue info</source>
|
||||
<target>Інформація про чергу повідомлень</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reactions" xml:space="preserve">
|
||||
@@ -8103,6 +8105,9 @@ SimpleX servers cannot see your profile.</source>
|
||||
<source>server queue info: %1$@
|
||||
|
||||
last received msg: %2$@</source>
|
||||
<target>інформація про чергу на сервері: %1$@
|
||||
|
||||
останнє отримане повідомлення: %2$@</target>
|
||||
<note>queue info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new contact address" xml:space="preserve">
|
||||
|
||||
@@ -603,9 +603,9 @@
|
||||
<target>扫描二维码来添加服务器。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add server…" xml:space="preserve">
|
||||
<source>Add server…</source>
|
||||
<target>添加服务器…</target>
|
||||
<trans-unit id="Add server" xml:space="preserve">
|
||||
<source>Add server</source>
|
||||
<target>添加服务器</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add to another device" xml:space="preserve">
|
||||
|
||||
@@ -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,8 @@
|
||||
8C9BC2652C240D5200875A27 /* ThemeModeEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */; };
|
||||
8CC4ED902BD7B8530078AEE8 /* CallAudioDeviceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC4ED8F2BD7B8530078AEE8 /* CallAudioDeviceManager.swift */; };
|
||||
8CC956EE2BC0041000412A11 /* NetworkObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC956ED2BC0041000412A11 /* NetworkObserver.swift */; };
|
||||
CE38A29A2C3FCA54005ED185 /* ImageUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBD2859295711D700EC2CF4 /* ImageUtils.swift */; };
|
||||
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = CE38A29B2C3FCD72005ED185 /* SwiftyGif */; };
|
||||
CE984D4B2C36C5D500E3AEFF /* ChatItemClipShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */; };
|
||||
CEEA861D2C2ABCB50084E1EA /* ReverseList.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */; };
|
||||
D7197A1829AE89660055C05A /* WebRTC in Frameworks */ = {isa = PBXBuildFile; productRef = D7197A1729AE89660055C05A /* WebRTC */; };
|
||||
@@ -560,6 +561,7 @@
|
||||
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;
|
||||
};
|
||||
@@ -658,7 +660,6 @@
|
||||
5CF937212B25034A00E1D781 /* NSESubscriber.swift */,
|
||||
5CB346E82869E8BA001FD2EF /* PushEnvironment.swift */,
|
||||
5C93293E2928E0FD0090FFF9 /* AudioRecPlay.swift */,
|
||||
5CBD2859295711D700EC2CF4 /* ImageUtils.swift */,
|
||||
8CC956ED2BC0041000412A11 /* NetworkObserver.swift */,
|
||||
);
|
||||
path = Model;
|
||||
@@ -858,6 +859,7 @@
|
||||
5C9FD96A27A56D4D0075386C /* JSON.swift */,
|
||||
5CDCAD7D2818941F00503DA2 /* API.swift */,
|
||||
5CDCAD80281A7E2700503DA2 /* Notifications.swift */,
|
||||
5CBD2859295711D700EC2CF4 /* ImageUtils.swift */,
|
||||
64DAE1502809D9F5000DA960 /* FileUtils.swift */,
|
||||
5C9D81182AA7A4F1001D49FD /* CryptoFile.swift */,
|
||||
5C00168028C4FE760094D739 /* KeyChain.swift */,
|
||||
@@ -1068,6 +1070,7 @@
|
||||
name = SimpleXChat;
|
||||
packageProductDependencies = (
|
||||
E50581052C3DDD9D009C3F71 /* Yams */,
|
||||
CE38A29B2C3FCD72005ED185 /* SwiftyGif */,
|
||||
);
|
||||
productName = SimpleXChat;
|
||||
productReference = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */;
|
||||
@@ -1205,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 */,
|
||||
@@ -1376,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 */,
|
||||
@@ -2023,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" */;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
+2
-2
@@ -20,11 +20,11 @@ actual fun ChatListNavLinkLayout(
|
||||
disabled: Boolean,
|
||||
selectedChat: State<Boolean>,
|
||||
nextChatSelected: State<Boolean>,
|
||||
oneHandUI: State<Boolean>
|
||||
oneHandUI: State<Boolean>?
|
||||
) {
|
||||
var modifier = Modifier.fillMaxWidth()
|
||||
|
||||
if (oneHandUI.value) {
|
||||
if (oneHandUI != null && oneHandUI.value) {
|
||||
modifier = modifier.scale(scaleX = 1f, scaleY = -1f)
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ fun MainScreen() {
|
||||
laUnavailableInstructionAlert()
|
||||
}
|
||||
}
|
||||
platform.desktopShowAppUpdateNotice()
|
||||
LaunchedEffect(chatModel.clearOverlays.value) {
|
||||
if (chatModel.clearOverlays.value) {
|
||||
ModalManager.closeAllModalsEverywhere()
|
||||
|
||||
+25
-3
@@ -28,6 +28,7 @@ import kotlinx.serialization.descriptors.*
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.*
|
||||
import java.io.Closeable
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.time.format.DateTimeFormatter
|
||||
@@ -65,6 +66,7 @@ object ChatModel {
|
||||
val deletedChats = mutableStateOf<List<Pair<Long?, String>>>(emptyList())
|
||||
val chatItemStatuses = mutableMapOf<Long, CIStatus>()
|
||||
val groupMembers = mutableStateListOf<GroupMember>()
|
||||
val groupMembersIndexes = mutableStateMapOf<Long, Int>()
|
||||
|
||||
val terminalItems = mutableStateOf<List<TerminalItem>>(listOf())
|
||||
val userAddress = mutableStateOf<UserContactLinkRec?>(null)
|
||||
@@ -121,6 +123,9 @@ object ChatModel {
|
||||
val clipboardHasText = mutableStateOf(false)
|
||||
val networkInfo = mutableStateOf(UserNetworkInfo(networkType = UserNetworkType.OTHER, online = true))
|
||||
|
||||
val updatingProgress = mutableStateOf(null as Float?)
|
||||
var updatingRequest: Closeable? = null
|
||||
|
||||
val updatingChatsMutex: Mutex = Mutex()
|
||||
val changingActiveUserMutex: Mutex = Mutex()
|
||||
|
||||
@@ -170,7 +175,23 @@ object ChatModel {
|
||||
fun getChat(id: String): Chat? = chats.toList().firstOrNull { it.id == id }
|
||||
fun getContactChat(contactId: Long): Chat? = chats.toList().firstOrNull { it.chatInfo is ChatInfo.Direct && it.chatInfo.apiId == contactId }
|
||||
fun getGroupChat(groupId: Long): Chat? = chats.toList().firstOrNull { it.chatInfo is ChatInfo.Group && it.chatInfo.apiId == groupId }
|
||||
fun getGroupMember(groupMemberId: Long): GroupMember? = groupMembers.firstOrNull { it.groupMemberId == groupMemberId }
|
||||
|
||||
fun populateGroupMembersIndexes() {
|
||||
groupMembersIndexes.clear()
|
||||
groupMembers.forEachIndexed { i, member ->
|
||||
groupMembersIndexes[member.groupMemberId] = i
|
||||
}
|
||||
}
|
||||
|
||||
fun getGroupMember(groupMemberId: Long): GroupMember? {
|
||||
val memberIndex = groupMembersIndexes[groupMemberId]
|
||||
return if (memberIndex != null) {
|
||||
groupMembers[memberIndex]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getChatIndex(rhId: Long?, id: String): Int = chats.toList().indexOfFirst { it.id == id && it.remoteHostId == rhId }
|
||||
fun addChat(chat: Chat) = chats.add(index = 0, chat)
|
||||
|
||||
@@ -620,12 +641,13 @@ object ChatModel {
|
||||
}
|
||||
// update current chat
|
||||
return if (chatId.value == groupInfo.id) {
|
||||
val memberIndex = groupMembers.indexOfFirst { it.groupMemberId == member.groupMemberId }
|
||||
if (memberIndex >= 0) {
|
||||
val memberIndex = groupMembersIndexes[member.groupMemberId]
|
||||
if (memberIndex != null) {
|
||||
groupMembers[memberIndex] = member
|
||||
false
|
||||
} else {
|
||||
groupMembers.add(member)
|
||||
groupMembersIndexes[member.groupMemberId] = groupMembers.size - 1
|
||||
true
|
||||
}
|
||||
} else {
|
||||
|
||||
+122
-13
@@ -160,6 +160,9 @@ class AppPreferences {
|
||||
val showHiddenProfilesNotice = mkBoolPreference(SHARED_PREFS_SHOW_HIDDEN_PROFILES_NOTICE, true)
|
||||
val showMuteProfileAlert = mkBoolPreference(SHARED_PREFS_SHOW_MUTE_PROFILE_ALERT, true)
|
||||
val appLanguage = mkStrPreference(SHARED_PREFS_APP_LANGUAGE, null)
|
||||
val appUpdateChannel = mkEnumPreference(SHARED_PREFS_APP_UPDATE_CHANNEL, AppUpdatesChannel.DISABLED) { AppUpdatesChannel.entries.firstOrNull { it.name == this } }
|
||||
val appSkippedUpdate = mkStrPreference(SHARED_PREFS_APP_SKIPPED_UPDATE, "")
|
||||
val appUpdateNoticeShown = mkBoolPreference(SHARED_PREFS_APP_UPDATE_NOTICE_SHOWN, false)
|
||||
|
||||
val onboardingStage = mkEnumPreference(SHARED_PREFS_ONBOARDING_STAGE, OnboardingStage.OnboardingComplete) { OnboardingStage.values().firstOrNull { it.name == this } }
|
||||
val migrationToStage = mkStrPreference(SHARED_PREFS_MIGRATION_TO_STAGE, null)
|
||||
@@ -334,6 +337,9 @@ class AppPreferences {
|
||||
private const val SHARED_PREFS_CHAT_ARCHIVE_NAME = "ChatArchiveName"
|
||||
private const val SHARED_PREFS_CHAT_ARCHIVE_TIME = "ChatArchiveTime"
|
||||
private const val SHARED_PREFS_APP_LANGUAGE = "AppLanguage"
|
||||
private const val SHARED_PREFS_APP_UPDATE_CHANNEL = "AppUpdateChannel"
|
||||
private const val SHARED_PREFS_APP_SKIPPED_UPDATE = "AppSkippedUpdate"
|
||||
private const val SHARED_PREFS_APP_UPDATE_NOTICE_SHOWN = "AppUpdateNoticeShown"
|
||||
private const val SHARED_PREFS_ONBOARDING_STAGE = "OnboardingStage"
|
||||
const val SHARED_PREFS_MIGRATION_TO_STAGE = "MigrationToStage"
|
||||
const val SHARED_PREFS_MIGRATION_FROM_STAGE = "MigrationFromStage"
|
||||
@@ -1831,6 +1837,80 @@ object ChatController {
|
||||
)
|
||||
true
|
||||
}
|
||||
r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorAgent
|
||||
&& r.chatError.agentError is AgentErrorType.BROKER
|
||||
&& r.chatError.agentError.brokerErr is BrokerErrorType.HOST -> {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.connection_error),
|
||||
String.format(generalGetString(MR.strings.network_error_broker_host_desc), serverHostname(r.chatError.agentError.brokerAddress))
|
||||
)
|
||||
true
|
||||
}
|
||||
r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorAgent
|
||||
&& r.chatError.agentError is AgentErrorType.BROKER
|
||||
&& r.chatError.agentError.brokerErr is BrokerErrorType.TRANSPORT
|
||||
&& r.chatError.agentError.brokerErr.transportErr is SMPTransportError.Version -> {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.connection_error),
|
||||
String.format(generalGetString(MR.strings.network_error_broker_version_desc), serverHostname(r.chatError.agentError.brokerAddress))
|
||||
)
|
||||
true
|
||||
}
|
||||
r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorAgent
|
||||
&& r.chatError.agentError is AgentErrorType.SMP
|
||||
&& r.chatError.agentError.smpErr is SMPErrorType.PROXY ->
|
||||
proxyErrorAlert(r.chatError.agentError.smpErr.proxyErr)
|
||||
r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorAgent
|
||||
&& r.chatError.agentError is AgentErrorType.PROXY
|
||||
&& r.chatError.agentError.proxyErr is ProxyClientError.ProxyProtocolError
|
||||
&& r.chatError.agentError.proxyErr.protocolErr is SMPErrorType.PROXY ->
|
||||
proxyErrorAlert(r.chatError.agentError.proxyErr.protocolErr.proxyErr)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun proxyErrorAlert(pe: ProxyError): Boolean {
|
||||
return when {
|
||||
pe is ProxyError.BROKER
|
||||
&& pe.brokerErr is BrokerErrorType.TIMEOUT -> {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.private_routing_error),
|
||||
generalGetString(MR.strings.please_try_later)
|
||||
)
|
||||
true
|
||||
}
|
||||
pe is ProxyError.BROKER
|
||||
&& pe.brokerErr is BrokerErrorType.NETWORK -> {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.private_routing_error),
|
||||
generalGetString(MR.strings.please_try_later)
|
||||
)
|
||||
true
|
||||
}
|
||||
pe is ProxyError.NO_SESSION -> {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.private_routing_error),
|
||||
generalGetString(MR.strings.please_try_later)
|
||||
)
|
||||
true
|
||||
}
|
||||
pe is ProxyError.BROKER
|
||||
&& pe.brokerErr is BrokerErrorType.HOST -> {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.private_routing_error),
|
||||
generalGetString(MR.strings.srv_error_host)
|
||||
)
|
||||
true
|
||||
}
|
||||
pe is ProxyError.BROKER
|
||||
&& pe.brokerErr is BrokerErrorType.TRANSPORT
|
||||
&& pe.brokerErr.transportErr is SMPTransportError.Version -> {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.private_routing_error),
|
||||
generalGetString(MR.strings.srv_error_version)
|
||||
)
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@@ -3086,7 +3166,7 @@ data class ProtoServersConfig(
|
||||
data class UserProtocolServers(
|
||||
val serverProtocol: ServerProtocol,
|
||||
val protoServers: List<ServerCfg>,
|
||||
val presetServers: List<String>,
|
||||
val presetServers: List<ServerCfg>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
@@ -3095,7 +3175,7 @@ data class ServerCfg(
|
||||
val server: String,
|
||||
val preset: Boolean,
|
||||
val tested: Boolean? = null,
|
||||
val enabled: ServerEnabled
|
||||
val enabled: Boolean
|
||||
) {
|
||||
@Transient
|
||||
private val createdAt: Date = Date()
|
||||
@@ -3109,7 +3189,7 @@ data class ServerCfg(
|
||||
get() = server.isBlank()
|
||||
|
||||
companion object {
|
||||
val empty = ServerCfg(remoteHostId = null, server = "", preset = false, tested = null, enabled = ServerEnabled.Enabled)
|
||||
val empty = ServerCfg(remoteHostId = null, server = "", preset = false, tested = null, enabled = false)
|
||||
|
||||
class SampleData(
|
||||
val preset: ServerCfg,
|
||||
@@ -3123,33 +3203,26 @@ data class ServerCfg(
|
||||
server = "smp://abcd@smp8.simplex.im",
|
||||
preset = true,
|
||||
tested = true,
|
||||
enabled = ServerEnabled.Enabled
|
||||
enabled = true
|
||||
),
|
||||
custom = ServerCfg(
|
||||
remoteHostId = null,
|
||||
server = "smp://abcd@smp9.simplex.im",
|
||||
preset = false,
|
||||
tested = false,
|
||||
enabled = ServerEnabled.Disabled
|
||||
enabled = false
|
||||
),
|
||||
untested = ServerCfg(
|
||||
remoteHostId = null,
|
||||
server = "smp://abcd@smp10.simplex.im",
|
||||
preset = false,
|
||||
tested = null,
|
||||
enabled = ServerEnabled.Enabled
|
||||
enabled = true
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class ServerEnabled {
|
||||
@SerialName("disabled") Disabled,
|
||||
@SerialName("enabled") Enabled,
|
||||
@SerialName("known") Known;
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class ProtocolTestStep {
|
||||
@SerialName("connect") Connect,
|
||||
@@ -5535,6 +5608,7 @@ sealed class AgentErrorType {
|
||||
is SMP -> "SMP ${smpErr.string}"
|
||||
// is NTF -> "NTF ${ntfErr.string}"
|
||||
is XFTP -> "XFTP ${xftpErr.string}"
|
||||
is PROXY -> "PROXY $proxyServer $relayServer ${proxyErr.string}"
|
||||
is RCP -> "RCP ${rcpErr.string}"
|
||||
is BROKER -> "BROKER ${brokerErr.string}"
|
||||
is AGENT -> "AGENT ${agentErr.string}"
|
||||
@@ -5547,6 +5621,7 @@ sealed class AgentErrorType {
|
||||
@Serializable @SerialName("SMP") class SMP(val smpErr: SMPErrorType): AgentErrorType()
|
||||
// @Serializable @SerialName("NTF") class NTF(val ntfErr: SMPErrorType): AgentErrorType()
|
||||
@Serializable @SerialName("XFTP") class XFTP(val xftpErr: XFTPErrorType): AgentErrorType()
|
||||
@Serializable @SerialName("PROXY") class PROXY(val proxyServer: String, val relayServer: String, val proxyErr: ProxyClientError): AgentErrorType()
|
||||
@Serializable @SerialName("RCP") class RCP(val rcpErr: RCErrorType): AgentErrorType()
|
||||
@Serializable @SerialName("BROKER") class BROKER(val brokerAddress: String, val brokerErr: BrokerErrorType): AgentErrorType()
|
||||
@Serializable @SerialName("AGENT") class AGENT(val agentErr: SMPAgentError): AgentErrorType()
|
||||
@@ -5611,22 +5686,42 @@ sealed class SMPErrorType {
|
||||
is BLOCK -> "BLOCK"
|
||||
is SESSION -> "SESSION"
|
||||
is CMD -> "CMD ${cmdErr.string}"
|
||||
is PROXY -> "PROXY ${proxyErr.string}"
|
||||
is AUTH -> "AUTH"
|
||||
is CRYPTO -> "CRYPTO"
|
||||
is QUOTA -> "QUOTA"
|
||||
is NO_MSG -> "NO_MSG"
|
||||
is LARGE_MSG -> "LARGE_MSG"
|
||||
is EXPIRED -> "EXPIRED"
|
||||
is INTERNAL -> "INTERNAL"
|
||||
}
|
||||
@Serializable @SerialName("BLOCK") class BLOCK: SMPErrorType()
|
||||
@Serializable @SerialName("SESSION") class SESSION: SMPErrorType()
|
||||
@Serializable @SerialName("CMD") class CMD(val cmdErr: ProtocolCommandError): SMPErrorType()
|
||||
@Serializable @SerialName("PROXY") class PROXY(val proxyErr: ProxyError): SMPErrorType()
|
||||
@Serializable @SerialName("AUTH") class AUTH: SMPErrorType()
|
||||
@Serializable @SerialName("CRYPTO") class CRYPTO: SMPErrorType()
|
||||
@Serializable @SerialName("QUOTA") class QUOTA: SMPErrorType()
|
||||
@Serializable @SerialName("NO_MSG") class NO_MSG: SMPErrorType()
|
||||
@Serializable @SerialName("LARGE_MSG") class LARGE_MSG: SMPErrorType()
|
||||
@Serializable @SerialName("EXPIRED") class EXPIRED: SMPErrorType()
|
||||
@Serializable @SerialName("INTERNAL") class INTERNAL: SMPErrorType()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
sealed class ProxyError {
|
||||
val string: String get() = when (this) {
|
||||
is PROTOCOL -> "PROTOCOL ${protocolErr.string}"
|
||||
is BROKER -> "BROKER ${brokerErr.string}"
|
||||
is BASIC_AUTH -> "BASIC_AUTH"
|
||||
is NO_SESSION -> "NO_SESSION"
|
||||
}
|
||||
@Serializable @SerialName("PROTOCOL") class PROTOCOL(val protocolErr: SMPErrorType): ProxyError()
|
||||
@Serializable @SerialName("BROKER") class BROKER(val brokerErr: BrokerErrorType): ProxyError()
|
||||
@Serializable @SerialName("BASIC_AUTH") class BASIC_AUTH: ProxyError()
|
||||
@Serializable @SerialName("NO_SESSION") class NO_SESSION: ProxyError()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
sealed class ProtocolCommandError {
|
||||
val string: String get() = when (this) {
|
||||
@@ -5649,12 +5744,14 @@ sealed class ProtocolCommandError {
|
||||
sealed class SMPTransportError {
|
||||
val string: String get() = when (this) {
|
||||
is BadBlock -> "badBlock"
|
||||
is Version -> "version"
|
||||
is LargeMsg -> "largeMsg"
|
||||
is BadSession -> "badSession"
|
||||
is NoServerAuth -> "noServerAuth"
|
||||
is Handshake -> "handshake ${handshakeErr.string}"
|
||||
}
|
||||
@Serializable @SerialName("badBlock") class BadBlock: SMPTransportError()
|
||||
@Serializable @SerialName("version") class Version: SMPTransportError()
|
||||
@Serializable @SerialName("largeMsg") class LargeMsg: SMPTransportError()
|
||||
@Serializable @SerialName("badSession") class BadSession: SMPTransportError()
|
||||
@Serializable @SerialName("noServerAuth") class NoServerAuth: SMPTransportError()
|
||||
@@ -5727,6 +5824,18 @@ sealed class XFTPErrorType {
|
||||
@Serializable @SerialName("INTERNAL") object INTERNAL: XFTPErrorType()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
sealed class ProxyClientError {
|
||||
val string: String get() = when (this) {
|
||||
is ProxyProtocolError -> "ProxyProtocolError $protocolErr"
|
||||
is ProxyUnexpectedResponse -> "ProxyUnexpectedResponse $responseStr"
|
||||
is ProxyResponseError -> "ProxyResponseError $responseErr"
|
||||
}
|
||||
@Serializable @SerialName("protocolError") class ProxyProtocolError(val protocolErr: SMPErrorType): ProxyClientError()
|
||||
@Serializable @SerialName("unexpectedResponse") class ProxyUnexpectedResponse(val responseStr: String): ProxyClientError()
|
||||
@Serializable @SerialName("responseError") class ProxyResponseError(val responseErr: SMPErrorType): ProxyClientError()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
sealed class RCErrorType {
|
||||
val string: String get() = when (this) {
|
||||
|
||||
+17
-1
@@ -3,7 +3,8 @@ package chat.simplex.common.platform
|
||||
import chat.simplex.common.BuildConfigCommon
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.ui.theme.DefaultTheme
|
||||
import java.io.File
|
||||
import chat.simplex.common.views.helpers.generalGetString
|
||||
import chat.simplex.res.MR
|
||||
import java.util.*
|
||||
|
||||
enum class AppPlatform {
|
||||
@@ -20,6 +21,8 @@ expect val appPlatform: AppPlatform
|
||||
|
||||
expect val deviceName: String
|
||||
|
||||
expect fun isAppVisibleAndFocused(): Boolean
|
||||
|
||||
val appVersionInfo: Pair<String, Int?> = if (appPlatform == AppPlatform.ANDROID)
|
||||
BuildConfigCommon.ANDROID_VERSION_NAME to BuildConfigCommon.ANDROID_VERSION_CODE
|
||||
else
|
||||
@@ -55,3 +58,16 @@ fun runMigrations() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class AppUpdatesChannel {
|
||||
DISABLED,
|
||||
STABLE,
|
||||
BETA;
|
||||
|
||||
val text: String
|
||||
get() = when (this) {
|
||||
DISABLED -> generalGetString(MR.strings.app_check_for_updates_disabled)
|
||||
STABLE -> generalGetString(MR.strings.app_check_for_updates_stable)
|
||||
BETA -> generalGetString(MR.strings.app_check_for_updates_beta)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ expect val remoteHostsDir: File
|
||||
|
||||
expect fun desktopOpenDatabaseDir()
|
||||
|
||||
expect fun desktopOpenDir(dir: File)
|
||||
|
||||
fun createURIFromPath(absolutePath: String): URI = URI.create(URLEncoder.encode(absolutePath, "UTF-8"))
|
||||
|
||||
fun URI.toFile(): File = File(URLDecoder.decode(rawPath, "UTF-8").removePrefix("file:"))
|
||||
|
||||
+1
@@ -29,6 +29,7 @@ interface PlatformInterface {
|
||||
@Composable fun desktopScrollBarComponents(): Triple<Animatable<Float, AnimationVector1D>, Modifier, MutableState<Job>> = remember { Triple(Animatable(0f), Modifier, mutableStateOf(Job())) }
|
||||
@Composable fun desktopScrollBar(state: LazyListState, modifier: Modifier, scrollBarAlpha: Animatable<Float, AnimationVector1D>, scrollJob: MutableState<Job>, reversed: Boolean) {}
|
||||
@Composable fun desktopScrollBar(state: ScrollState, modifier: Modifier, scrollBarAlpha: Animatable<Float, AnimationVector1D>, scrollJob: MutableState<Job>, reversed: Boolean) {}
|
||||
@Composable fun desktopShowAppUpdateNotice() {}
|
||||
}
|
||||
/**
|
||||
* Multiplatform project has separate directories per platform + common directory that contains directories per platform + common for all of them.
|
||||
|
||||
+1
@@ -159,6 +159,7 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId:
|
||||
AudioPlayer.stop()
|
||||
chatModel.chatId.value = null
|
||||
chatModel.groupMembers.clear()
|
||||
chatModel.groupMembersIndexes.clear()
|
||||
},
|
||||
info = {
|
||||
if (ModalManager.end.hasModalsOpen()) {
|
||||
|
||||
+31
-29
@@ -128,30 +128,6 @@ fun CIFileView(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun progressIndicator() {
|
||||
CircularProgressIndicator(
|
||||
Modifier.size(32.dp),
|
||||
color = if (isInDarkTheme()) FileDark else FileLight,
|
||||
strokeWidth = 3.dp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun progressCircle(progress: Long, total: Long) {
|
||||
val angle = 360f * (progress.toDouble() / total.toDouble()).toFloat()
|
||||
val strokeWidth = with(LocalDensity.current) { 3.dp.toPx() }
|
||||
val strokeColor = if (isInDarkTheme()) FileDark else FileLight
|
||||
Surface(
|
||||
Modifier.drawRingModifier(angle, strokeColor, strokeWidth),
|
||||
color = Color.Transparent,
|
||||
shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
|
||||
contentColor = LocalContentColor.current
|
||||
) {
|
||||
Box(Modifier.size(32.dp))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun fileIndicator() {
|
||||
Box(
|
||||
@@ -164,14 +140,14 @@ fun CIFileView(
|
||||
when (file.fileStatus) {
|
||||
is CIFileStatus.SndStored ->
|
||||
when (file.fileProtocol) {
|
||||
FileProtocol.XFTP -> progressIndicator()
|
||||
FileProtocol.XFTP -> CIFileViewScope.progressIndicator()
|
||||
FileProtocol.SMP -> fileIcon()
|
||||
FileProtocol.LOCAL -> fileIcon()
|
||||
}
|
||||
is CIFileStatus.SndTransfer ->
|
||||
when (file.fileProtocol) {
|
||||
FileProtocol.XFTP -> progressCircle(file.fileStatus.sndProgress, file.fileStatus.sndTotal)
|
||||
FileProtocol.SMP -> progressIndicator()
|
||||
FileProtocol.XFTP -> CIFileViewScope.progressCircle(file.fileStatus.sndProgress, file.fileStatus.sndTotal)
|
||||
FileProtocol.SMP -> CIFileViewScope.progressIndicator()
|
||||
FileProtocol.LOCAL -> {}
|
||||
}
|
||||
is CIFileStatus.SndComplete -> fileIcon(innerIcon = painterResource(MR.images.ic_check_filled))
|
||||
@@ -186,9 +162,9 @@ fun CIFileView(
|
||||
is CIFileStatus.RcvAccepted -> fileIcon(innerIcon = painterResource(MR.images.ic_more_horiz))
|
||||
is CIFileStatus.RcvTransfer ->
|
||||
if (file.fileProtocol == FileProtocol.XFTP && file.fileStatus.rcvProgress < file.fileStatus.rcvTotal) {
|
||||
progressCircle(file.fileStatus.rcvProgress, file.fileStatus.rcvTotal)
|
||||
CIFileViewScope.progressCircle(file.fileStatus.rcvProgress, file.fileStatus.rcvTotal)
|
||||
} else {
|
||||
progressIndicator()
|
||||
CIFileViewScope.progressIndicator()
|
||||
}
|
||||
is CIFileStatus.RcvAborted ->
|
||||
fileIcon(innerIcon = painterResource(MR.images.ic_sync_problem), color = MaterialTheme.colors.primary)
|
||||
@@ -265,6 +241,32 @@ fun rememberSaveFileLauncher(ciFile: CIFile?): FileChooserLauncher =
|
||||
}
|
||||
}
|
||||
|
||||
object CIFileViewScope {
|
||||
@Composable
|
||||
fun progressIndicator() {
|
||||
CircularProgressIndicator(
|
||||
Modifier.size(32.dp),
|
||||
color = if (isInDarkTheme()) FileDark else FileLight,
|
||||
strokeWidth = 3.dp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun progressCircle(progress: Long, total: Long) {
|
||||
val angle = 360f * (progress.toDouble() / total.toDouble()).toFloat()
|
||||
val strokeWidth = with(LocalDensity.current) { 3.dp.toPx() }
|
||||
val strokeColor = if (isInDarkTheme()) FileDark else FileLight
|
||||
Surface(
|
||||
Modifier.drawRingModifier(angle, strokeColor, strokeWidth),
|
||||
color = Color.Transparent,
|
||||
shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
|
||||
contentColor = LocalContentColor.current
|
||||
) {
|
||||
Box(Modifier.size(32.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
class ChatItemProvider: PreviewParameterProvider<ChatItem> {
|
||||
private val sentFile = ChatItem(
|
||||
|
||||
+6
-2
@@ -261,7 +261,9 @@ suspend fun setGroupMembers(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatMo
|
||||
}
|
||||
}
|
||||
chatModel.groupMembers.clear()
|
||||
chatModel.groupMembersIndexes.clear()
|
||||
chatModel.groupMembers.addAll(newMembers)
|
||||
chatModel.populateGroupMembersIndexes()
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -660,7 +662,7 @@ fun markChatUnread(chat: Chat, chatModel: ChatModel) {
|
||||
}
|
||||
}
|
||||
|
||||
fun contactRequestAlertDialog(rhId: Long?, contactRequest: ChatInfo.ContactRequest, chatModel: ChatModel) {
|
||||
fun contactRequestAlertDialog(rhId: Long?, contactRequest: ChatInfo.ContactRequest, chatModel: ChatModel, onSuccess: () -> Unit = {}) {
|
||||
AlertManager.shared.showAlertDialogButtonsColumn(
|
||||
title = generalGetString(MR.strings.accept_connection_request__question),
|
||||
text = AnnotatedString(generalGetString(MR.strings.if_you_choose_to_reject_the_sender_will_not_be_notified)),
|
||||
@@ -669,12 +671,14 @@ fun contactRequestAlertDialog(rhId: Long?, contactRequest: ChatInfo.ContactReque
|
||||
SectionItemView({
|
||||
AlertManager.shared.hideAlert()
|
||||
acceptContactRequest(rhId, incognito = false, contactRequest.apiId, contactRequest, true, chatModel)
|
||||
onSuccess()
|
||||
}) {
|
||||
Text(generalGetString(MR.strings.accept_contact_button), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
|
||||
}
|
||||
SectionItemView({
|
||||
AlertManager.shared.hideAlert()
|
||||
acceptContactRequest(rhId, incognito = true, contactRequest.apiId, contactRequest, true, chatModel)
|
||||
onSuccess()
|
||||
}) {
|
||||
Text(generalGetString(MR.strings.accept_contact_incognito_button), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
|
||||
}
|
||||
@@ -911,7 +915,7 @@ expect fun ChatListNavLinkLayout(
|
||||
disabled: Boolean,
|
||||
selectedChat: State<Boolean>,
|
||||
nextChatSelected: State<Boolean>,
|
||||
oneHandUI: State<Boolean>
|
||||
oneHandUI: State<Boolean>? = null
|
||||
)
|
||||
|
||||
@Preview/*(
|
||||
|
||||
+110
-152
@@ -1,8 +1,10 @@
|
||||
package chat.simplex.common.views.chatlist
|
||||
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsHoveredAsState
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.BoxScope.*
|
||||
import androidx.compose.foundation.lazy.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
@@ -14,7 +16,6 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.focus.*
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.platform.*
|
||||
import androidx.compose.ui.text.TextRange
|
||||
@@ -33,6 +34,7 @@ import chat.simplex.common.views.onboarding.shouldShowWhatsNew
|
||||
import chat.simplex.common.views.usersettings.SettingsView
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.views.call.Call
|
||||
import chat.simplex.common.views.chat.item.CIFileViewScope
|
||||
import chat.simplex.common.views.newchat.*
|
||||
import chat.simplex.res.MR
|
||||
import kotlinx.coroutines.*
|
||||
@@ -40,7 +42,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.net.URI
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@Composable
|
||||
@@ -77,8 +78,29 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf
|
||||
val searchText = rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) }
|
||||
val scope = rememberCoroutineScope()
|
||||
val (userPickerState, scaffoldState ) = settingsState
|
||||
Scaffold(topBar = { Box(Modifier.padding(end = endPadding)) { ChatListTopBar(stopped) } },
|
||||
bottomBar = { Box(Modifier.padding(end = endPadding)) { ChatListBottomToolbar(scaffoldState.drawerState, userPickerState) } },
|
||||
Scaffold(
|
||||
topBar = {
|
||||
if (!oneHandUI.state.value) {
|
||||
Box(Modifier.padding(end = endPadding)) {
|
||||
ChatListToolbar(
|
||||
scaffoldState.drawerState,
|
||||
userPickerState,
|
||||
stopped
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
bottomBar = {
|
||||
if (oneHandUI.state.value) {
|
||||
Box(Modifier.padding(end = endPadding)) {
|
||||
ChatListToolbar(
|
||||
scaffoldState.drawerState,
|
||||
userPickerState,
|
||||
stopped
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
scaffoldState = scaffoldState,
|
||||
drawerContent = {
|
||||
tryOrShowError("Settings", error = { ErrorSettingsView() }) {
|
||||
@@ -101,7 +123,10 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf
|
||||
FloatingActionButton(
|
||||
onClick = {
|
||||
if (!stopped) {
|
||||
if (newChatSheetState.value.isVisible()) hideNewChatSheet(true) else showNewChatSheet()
|
||||
ModalManager.start.closeModals()
|
||||
ModalManager.start.showModalCloseable{
|
||||
NewChatView(rh = chatModel.currentRemoteHost.value)
|
||||
}
|
||||
}
|
||||
},
|
||||
Modifier.padding(end = DEFAULT_PADDING - 16.dp + endPadding, bottom = bottom).size(AppBarHeight * fontSizeSqrtMultiplier),
|
||||
@@ -156,7 +181,12 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf
|
||||
}
|
||||
if (appPlatform.isAndroid) {
|
||||
tryOrShowError("UserPicker", error = {}) {
|
||||
UserPicker(chatModel, userPickerState) {
|
||||
|
||||
UserPicker(
|
||||
chatModel = chatModel,
|
||||
userPickerState = userPickerState,
|
||||
containerModifier = Modifier.padding(bottom = AppBarHeight),
|
||||
contentAlignment = if (oneHandUI.state.value) Alignment.BottomStart else Alignment.TopStart) {
|
||||
scope.launch { if (scaffoldState.drawerState.isOpen) scaffoldState.drawerState.close() else scaffoldState.drawerState.open() }
|
||||
userPickerState.value = AnimatedViewState.GONE
|
||||
}
|
||||
@@ -202,11 +232,27 @@ private fun ConnectButton(text: String, onClick: () -> Unit) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ChatListTopBar(stopped: Boolean) {
|
||||
private fun ChatListToolbar(drawerState: DrawerState, userPickerState: MutableStateFlow<AnimatedViewState>, stopped: Boolean) {
|
||||
val serversSummary: MutableState<PresentedServersSummary?> = remember { mutableStateOf(null) }
|
||||
|
||||
val barButtons = arrayListOf<@Composable RowScope.() -> Unit>()
|
||||
if (stopped) {
|
||||
val updatingProgress = remember { chatModel.updatingProgress }.value
|
||||
if (updatingProgress != null) {
|
||||
barButtons.add {
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
val hovered = interactionSource.collectIsHoveredAsState().value
|
||||
IconButton(onClick = {
|
||||
chatModel.updatingRequest?.close()
|
||||
}, Modifier.hoverable(interactionSource)) {
|
||||
if (hovered) {
|
||||
Icon(painterResource(MR.images.ic_close), null, tint = WarningOrange)
|
||||
} else if (updatingProgress == -1f) {
|
||||
CIFileViewScope.progressIndicator()
|
||||
} else {
|
||||
CIFileViewScope.progressCircle((updatingProgress * 100).toLong(), 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (stopped) {
|
||||
barButtons.add {
|
||||
IconButton(onClick = {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
@@ -222,10 +268,26 @@ private fun ChatListTopBar(stopped: Boolean) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
val clipboard = LocalClipboardManager.current
|
||||
|
||||
DefaultTopAppBar(
|
||||
navigationButton = {
|
||||
if (chatModel.users.isEmpty() && !chatModel.desktopNoUserNoRemote) {
|
||||
NavigationButtonMenu { scope.launch { if (drawerState.isOpen) drawerState.close() else drawerState.open() } }
|
||||
} else {
|
||||
val users by remember { derivedStateOf { chatModel.users.filter { u -> u.user.activeUser || !u.user.hidden } } }
|
||||
val allRead = users
|
||||
.filter { u -> !u.user.activeUser && !u.user.hidden }
|
||||
.all { u -> u.unreadCount == 0 }
|
||||
UserProfileButton(chatModel.currentUser.value?.profile?.image, allRead) {
|
||||
if (users.size == 1 && chatModel.remoteHosts.isEmpty()) {
|
||||
scope.launch { drawerState.open() }
|
||||
} else {
|
||||
userPickerState.value = AnimatedViewState.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
title = {
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(DEFAULT_SPACE_AFTER_ICON)) {
|
||||
Text(
|
||||
@@ -261,133 +323,36 @@ private fun ChatListTopBar(stopped: Boolean) {
|
||||
onSearchValueChanged = {},
|
||||
buttons = barButtons
|
||||
)
|
||||
Divider(Modifier.padding(top = AppBarHeight))
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SettingsButton(drawerState: DrawerState, userPickerState: MutableStateFlow<AnimatedViewState>) {
|
||||
val scope = rememberCoroutineScope()
|
||||
if (chatModel.users.isEmpty() && !chatModel.desktopNoUserNoRemote) {
|
||||
NavigationButtonMenu { scope.launch { if (drawerState.isOpen) drawerState.close() else drawerState.open() } }
|
||||
} else {
|
||||
val users by remember { derivedStateOf { chatModel.users.filter { u -> u.user.activeUser || !u.user.hidden } } }
|
||||
val allRead = users
|
||||
.filter { u -> !u.user.activeUser && !u.user.hidden }
|
||||
.all { u -> u.unreadCount == 0 }
|
||||
|
||||
UserProfileButton(chatModel.currentUser.value?.profile?.image, allRead) {
|
||||
if (users.size == 1 && chatModel.remoteHosts.isEmpty()) {
|
||||
scope.launch { drawerState.open() }
|
||||
} else {
|
||||
userPickerState.value = AnimatedViewState.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun toolbarIcon(icon: Painter) {
|
||||
Icon(
|
||||
icon,
|
||||
contentDescription = null,
|
||||
Modifier.size(24.dp * fontSizeSqrtMultiplier),
|
||||
tint = MaterialTheme.colors.secondary
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ChatListToolbarButton(icon: @Composable () -> Unit, title: String, onClick: () -> Unit) {
|
||||
Surface(
|
||||
Modifier
|
||||
.size(56.dp * fontSizeSqrtMultiplier),
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
color = Color.Transparent,
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.clickable { onClick () },
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
icon()
|
||||
Text(
|
||||
title,
|
||||
style = MaterialTheme.typography.subtitle2.copy(fontWeight = FontWeight.Normal, fontSize = 12.sp * fontSizeSqrtMultiplier),
|
||||
color = MaterialTheme.colors.secondary
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ChatListBottomToolbar(drawerState: DrawerState, userPickerState: MutableStateFlow<AnimatedViewState>) {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.height(BottomAppBarHeight)
|
||||
.background(MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, 0.97f))
|
||||
) {
|
||||
Divider()
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxHeight()
|
||||
.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
SettingsButton(drawerState, userPickerState)
|
||||
|
||||
ChatListToolbarButton(
|
||||
icon = { toolbarIcon(painterResource(MR.images.ic_chat_bubble_filled)) },
|
||||
title = generalGetString(MR.strings.your_chats),
|
||||
onClick = { }
|
||||
)
|
||||
}
|
||||
}
|
||||
Divider(Modifier.padding(top = AppBarHeight * fontSizeSqrtMultiplier))
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SubscriptionStatusIndicator(serversSummary: MutableState<PresentedServersSummary?>, click: (() -> Unit)) {
|
||||
var subs by remember { mutableStateOf(SMPServerSubs.newSMPServerSubs) }
|
||||
var sess by remember { mutableStateOf(ServerSessions.newServerSessions) }
|
||||
var timer: Job? by remember { mutableStateOf(null) }
|
||||
|
||||
val fetchInterval: Duration = 1.seconds
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
fun setServersSummary() {
|
||||
withBGApi {
|
||||
serversSummary.value = chatModel.controller.getAgentServersSummary(chatModel.remoteHostId())
|
||||
suspend fun setServersSummary() {
|
||||
serversSummary.value = chatModel.controller.getAgentServersSummary(chatModel.remoteHostId())
|
||||
|
||||
serversSummary.value?.let {
|
||||
subs = it.allUsersSMP.smpTotals.subs
|
||||
sess = it.allUsersSMP.smpTotals.sessions
|
||||
}
|
||||
serversSummary.value?.let {
|
||||
subs = it.allUsersSMP.smpTotals.subs
|
||||
sess = it.allUsersSMP.smpTotals.sessions
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
setServersSummary()
|
||||
timer = timer ?: scope.launch {
|
||||
while (true) {
|
||||
delay(fetchInterval.inWholeMilliseconds)
|
||||
setServersSummary()
|
||||
scope.launch {
|
||||
while (isActive) {
|
||||
delay(1.seconds)
|
||||
if ((appPlatform.isDesktop || chatModel.chatId.value == null) && !ModalManager.start.hasModalsOpen() && !ModalManager.fullscreen.hasModalsOpen() && isAppVisibleAndFocused()) {
|
||||
setServersSummary()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun stopTimer() {
|
||||
timer?.cancel()
|
||||
timer = null
|
||||
}
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
onDispose {
|
||||
stopTimer()
|
||||
}
|
||||
}
|
||||
|
||||
SimpleButtonFrame(click = click) {
|
||||
SubscriptionStatusIndicatorView(subs = subs, sess = sess)
|
||||
}
|
||||
@@ -395,38 +360,32 @@ fun SubscriptionStatusIndicator(serversSummary: MutableState<PresentedServersSum
|
||||
|
||||
@Composable
|
||||
fun UserProfileButton(image: String?, allRead: Boolean, onButtonClicked: () -> Unit) {
|
||||
ChatListToolbarButton(
|
||||
icon = {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
IconButton(onClick = onButtonClicked) {
|
||||
Box {
|
||||
ProfileImage(
|
||||
image = image,
|
||||
size = 24.dp * fontSizeSqrtMultiplier,
|
||||
color = MaterialTheme.colors.secondaryVariant.mixWith(
|
||||
MaterialTheme.colors.onBackground,
|
||||
0.97f
|
||||
)
|
||||
size = 37.dp * fontSizeSqrtMultiplier,
|
||||
color = MaterialTheme.colors.secondaryVariant.mixWith(MaterialTheme.colors.onBackground, 0.97f)
|
||||
)
|
||||
if (!allRead) {
|
||||
unreadBadge()
|
||||
}
|
||||
}
|
||||
},
|
||||
onClick = onButtonClicked,
|
||||
title = generalGetString(MR.strings.toolbar_settings),
|
||||
|
||||
)
|
||||
|
||||
if (appPlatform.isDesktop) {
|
||||
val h by remember { chatModel.currentRemoteHost }
|
||||
if (h != null) {
|
||||
Spacer(Modifier.width(12.dp))
|
||||
HostDisconnectButton {
|
||||
stopRemoteHostAndReloadHosts(h!!, true)
|
||||
}
|
||||
if (appPlatform.isDesktop) {
|
||||
val h by remember { chatModel.currentRemoteHost }
|
||||
if (h != null) {
|
||||
Spacer(Modifier.width(12.dp))
|
||||
HostDisconnectButton {
|
||||
stopRemoteHostAndReloadHosts(h!!, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
private fun BoxScope.unreadBadge(text: String? = "") {
|
||||
Text(
|
||||
@@ -507,7 +466,7 @@ private fun ChatListSearchBar(listState: LazyListState, searchText: MutableState
|
||||
} else {
|
||||
val padding = if (appPlatform.isDesktop) 0.dp else 7.dp
|
||||
if (chatModel.chats.size > 0) {
|
||||
ToggleFilterEnabledButton()
|
||||
ToggleFilterEnabledButton()
|
||||
}
|
||||
Spacer(Modifier.width(padding))
|
||||
}
|
||||
@@ -668,18 +627,17 @@ private fun filteredChats(
|
||||
} else {
|
||||
val s = if (searchShowingSimplexLink.value) "" else searchText.trim().lowercase()
|
||||
if (s.isEmpty() && !showUnreadAndFavorites)
|
||||
chats.filter { chat -> !chat.chatInfo.chatDeleted }
|
||||
chats
|
||||
else {
|
||||
chats.filter { chat ->
|
||||
when (val cInfo = chat.chatInfo) {
|
||||
is ChatInfo.Direct -> !chat.chatInfo.chatDeleted && (
|
||||
if (s.isEmpty()) {
|
||||
chat.id == chatModel.chatId.value || filtered(chat)
|
||||
} else {
|
||||
(viewNameContains(cInfo, s) ||
|
||||
cInfo.contact.profile.displayName.lowercase().contains(s) ||
|
||||
cInfo.contact.fullName.lowercase().contains(s))
|
||||
})
|
||||
is ChatInfo.Direct -> if (s.isEmpty()) {
|
||||
chat.id == chatModel.chatId.value || filtered(chat)
|
||||
} else {
|
||||
(viewNameContains(cInfo, s) ||
|
||||
cInfo.contact.profile.displayName.lowercase().contains(s) ||
|
||||
cInfo.contact.fullName.lowercase().contains(s))
|
||||
}
|
||||
is ChatInfo.Group -> if (s.isEmpty()) {
|
||||
chat.id == chatModel.chatId.value || filtered(chat) || cInfo.groupInfo.membership.memberStatus == GroupMemberStatus.MemInvited
|
||||
} else {
|
||||
@@ -697,8 +655,8 @@ private fun filteredChats(
|
||||
|
||||
private fun filtered(chat: Chat): Boolean =
|
||||
(chat.chatInfo.chatSettings?.favorite ?: false) ||
|
||||
chat.chatStats.unreadChat ||
|
||||
(chat.chatInfo.ntfsEnabled && chat.chatStats.unreadCount > 0)
|
||||
chat.chatStats.unreadChat ||
|
||||
(chat.chatInfo.ntfsEnabled && chat.chatStats.unreadCount > 0)
|
||||
|
||||
private fun viewNameContains(cInfo: ChatInfo, s: String): Boolean =
|
||||
cInfo.chatViewName.lowercase().contains(s.lowercase())
|
||||
|
||||
+7
-6
@@ -39,11 +39,13 @@ import kotlin.math.roundToInt
|
||||
fun UserPicker(
|
||||
chatModel: ChatModel,
|
||||
userPickerState: MutableStateFlow<AnimatedViewState>,
|
||||
containerModifier: Modifier = Modifier,
|
||||
contentAlignment: Alignment = Alignment.TopStart,
|
||||
showSettings: Boolean = true,
|
||||
showCancel: Boolean = false,
|
||||
cancelClicked: () -> Unit = {},
|
||||
useFromDesktopClicked: () -> Unit = {},
|
||||
settingsClicked: () -> Unit = {},
|
||||
settingsClicked: () -> Unit = {}
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
var newChat by remember { mutableStateOf(userPickerState.value) }
|
||||
@@ -149,18 +151,17 @@ fun UserPicker(
|
||||
.graphicsLayer {
|
||||
alpha = animatedFloat.value
|
||||
translationY = (animatedFloat.value - 1) * xOffset
|
||||
}
|
||||
},
|
||||
contentAlignment = contentAlignment
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.align(Alignment.BottomStart)
|
||||
.padding(bottom = BottomAppBarHeight)
|
||||
containerModifier
|
||||
.widthIn(min = 260.dp)
|
||||
.width(IntrinsicSize.Min)
|
||||
.height(IntrinsicSize.Min)
|
||||
.shadow(8.dp, RoundedCornerShape(corner = CornerSize(25.dp)), clip = true)
|
||||
.background(MaterialTheme.colors.surface, RoundedCornerShape(corner = CornerSize(25.dp)))
|
||||
.clip(RoundedCornerShape(corner = CornerSize(25.dp)))
|
||||
.clip(RoundedCornerShape(corner = CornerSize(25.dp))),
|
||||
) {
|
||||
val currentRemoteHost = remember { chatModel.currentRemoteHost }.value
|
||||
Column(Modifier.weight(1f).verticalScroll(rememberScrollState())) {
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
package chat.simplex.common.views.contacts
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.views.chat.*
|
||||
import chat.simplex.common.views.chat.item.ItemAction
|
||||
import chat.simplex.common.views.chatlist.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.res.MR
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@Composable
|
||||
fun ContactListNavLinkView(chat: Chat, nextChatSelected: State<Boolean>) {
|
||||
val showMenu = remember { mutableStateOf(false) }
|
||||
val disabled = chatModel.chatRunning.value == false || chatModel.deletedChats.value.contains(chat.remoteHostId to chat.chatInfo.id)
|
||||
LaunchedEffect(chat.id) {
|
||||
showMenu.value = false
|
||||
delay(500L)
|
||||
}
|
||||
val selectedChat = remember(chat.id) { derivedStateOf { chat.id == chatModel.chatId.value } }
|
||||
|
||||
when (chat.chatInfo) {
|
||||
is ChatInfo.Direct -> {
|
||||
ChatListNavLinkLayout(
|
||||
chatLinkPreview = {
|
||||
tryOrShowError("${chat.id}ContactListNavLink", error = { ErrorChatListItem() }) {
|
||||
ContactPreviewView(chat, disabled)
|
||||
}
|
||||
},
|
||||
click = {
|
||||
directChatAction(chat.remoteHostId, chat.chatInfo.contact, chatModel)
|
||||
ModalManager.start.closeModals()
|
||||
},
|
||||
dropdownMenuItems = {
|
||||
tryOrShowError("${chat.id}ContactListNavLinkDropdown", error = {}) {
|
||||
ContactMenuItems(chat, chat.chatInfo.contact, chatModel, showMenu)
|
||||
}
|
||||
},
|
||||
showMenu,
|
||||
disabled,
|
||||
selectedChat,
|
||||
nextChatSelected,
|
||||
)
|
||||
}
|
||||
is ChatInfo.ContactRequest -> {
|
||||
ChatListNavLinkLayout(
|
||||
chatLinkPreview = {
|
||||
tryOrShowError("${chat.id}ContactListNavLink", error = { ErrorChatListItem() }) {
|
||||
ContactPreviewView(chat, disabled)
|
||||
}
|
||||
},
|
||||
click = {
|
||||
contactRequestAlertDialog(
|
||||
chat.remoteHostId,
|
||||
chat.chatInfo,
|
||||
chatModel,
|
||||
onSuccess = {
|
||||
ModalManager.start.closeModals()
|
||||
}
|
||||
)
|
||||
},
|
||||
dropdownMenuItems = {
|
||||
tryOrShowError("${chat.id}ContactListNavLinkDropdown", error = {}) {
|
||||
ContactRequestMenuItems(chat.remoteHostId, chat.chatInfo, chatModel, showMenu)
|
||||
}
|
||||
},
|
||||
showMenu,
|
||||
disabled,
|
||||
selectedChat,
|
||||
nextChatSelected,
|
||||
)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ContactMenuItems(chat: Chat, contact: Contact, chatModel: ChatModel, showMenu: MutableState<Boolean>) {
|
||||
if (contact.activeConn != null) {
|
||||
ToggleFavoritesChatAction(chat, chatModel, chat.chatInfo.chatSettings?.favorite == true, showMenu)
|
||||
}
|
||||
DeleteContactAction(chat, chatModel, showMenu)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ToggleFavoritesChatAction(chat: Chat, chatModel: ChatModel, favorite: Boolean, showMenu: MutableState<Boolean>) {
|
||||
ItemAction(
|
||||
if (favorite) stringResource(MR.strings.unfavorite_chat) else stringResource(MR.strings.favorite_chat),
|
||||
if (favorite) painterResource(MR.images.ic_star_off) else painterResource(MR.images.ic_star),
|
||||
onClick = {
|
||||
toggleChatFavorite(chat, !favorite, chatModel)
|
||||
showMenu.value = false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DeleteContactAction(chat: Chat, chatModel: ChatModel, showMenu: MutableState<Boolean>) {
|
||||
ItemAction(
|
||||
stringResource(MR.strings.delete_contact_menu_action),
|
||||
painterResource(MR.images.ic_delete),
|
||||
onClick = {
|
||||
deleteContactDialog(chat, chatModel)
|
||||
showMenu.value = false
|
||||
},
|
||||
color = Color.Red
|
||||
)
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
package chat.simplex.common.views.contacts
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.chatModel
|
||||
import chat.simplex.common.ui.theme.DEFAULT_SPACE_AFTER_ICON
|
||||
import chat.simplex.res.MR
|
||||
|
||||
@Composable
|
||||
fun ContactPreviewView(
|
||||
chat: Chat,
|
||||
disabled: Boolean,
|
||||
) {
|
||||
val cInfo = chat.chatInfo
|
||||
|
||||
@Composable
|
||||
fun VerifiedIcon() {
|
||||
Icon(painterResource(MR.images.ic_verified_user), null, Modifier.size(19.dp).padding(end = 3.dp, top = 1.dp), tint = MaterialTheme.colors.secondary)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun chatPreviewTitle() {
|
||||
val deleting by remember(disabled, chat.id) { mutableStateOf(chatModel.deletedChats.value.contains(chat.remoteHostId to chat.chatInfo.id)) }
|
||||
when (cInfo) {
|
||||
is ChatInfo.Direct ->
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
if (cInfo.contact.verified) {
|
||||
VerifiedIcon()
|
||||
}
|
||||
Text(
|
||||
cInfo.chatViewName,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = if (deleting) MaterialTheme.colors.secondary else Color.Unspecified
|
||||
)
|
||||
}
|
||||
is ChatInfo.ContactRequest ->
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(
|
||||
cInfo.chatViewName,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = Color.Unspecified
|
||||
)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Box(contentAlignment = Alignment.BottomEnd) {
|
||||
ChatInfoImage(cInfo, size = 42.dp)
|
||||
}
|
||||
|
||||
Spacer(Modifier.width(DEFAULT_SPACE_AFTER_ICON))
|
||||
|
||||
Box(modifier = Modifier.weight(10f, fill = true)) {
|
||||
chatPreviewTitle()
|
||||
}
|
||||
|
||||
Spacer(Modifier.fillMaxWidth().weight(1f))
|
||||
|
||||
if (chat.chatInfo is ChatInfo.ContactRequest) {
|
||||
Text(
|
||||
text = generalGetString(MR.strings.contact_type_new).uppercase(),
|
||||
color = MaterialTheme.colors.onPrimary,
|
||||
fontSize = 10.sp * fontSizeMultiplier,
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colors.primary, shape = CircleShape)
|
||||
.badgeLayout()
|
||||
.padding(horizontal = 4.dp)
|
||||
.padding(vertical = 2.dp)
|
||||
)
|
||||
}
|
||||
|
||||
if (chat.chatInfo.chatSettings?.favorite == true) {
|
||||
Icon(
|
||||
painterResource(MR.images.ic_star_filled),
|
||||
contentDescription = generalGetString(MR.strings.favorite_chat),
|
||||
tint = MaterialTheme.colors.secondary,
|
||||
modifier = Modifier
|
||||
.size(17.dp)
|
||||
)
|
||||
if (chat.chatInfo.incognito) {
|
||||
Spacer(Modifier.width(DEFAULT_SPACE_AFTER_ICON))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (chat.chatInfo.incognito) {
|
||||
Icon(
|
||||
painterResource(MR.images.ic_theater_comedy),
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colors.secondary,
|
||||
modifier = Modifier
|
||||
.size(21.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+385
@@ -0,0 +1,385 @@
|
||||
package chat.simplex.common.views.contacts
|
||||
|
||||
import SectionItemView
|
||||
import SectionView
|
||||
import TextIconSpaced
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Divider
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.model.Chat
|
||||
import chat.simplex.common.model.ChatController
|
||||
import chat.simplex.common.model.ChatInfo
|
||||
import chat.simplex.common.model.ContactStatus
|
||||
import chat.simplex.common.model.RemoteHostInfo
|
||||
import chat.simplex.common.platform.BackHandler
|
||||
import chat.simplex.common.platform.appPlatform
|
||||
import chat.simplex.common.platform.chatModel
|
||||
import chat.simplex.common.platform.getKeyboardState
|
||||
import chat.simplex.common.ui.theme.DEFAULT_PADDING
|
||||
import chat.simplex.common.ui.theme.DEFAULT_PADDING_HALF
|
||||
import chat.simplex.common.views.helpers.AppBarTitle
|
||||
import chat.simplex.common.views.helpers.KeyChangeEffect
|
||||
import chat.simplex.common.views.helpers.KeyboardState
|
||||
import chat.simplex.common.views.helpers.ModalData
|
||||
import chat.simplex.common.views.helpers.ModalManager
|
||||
import chat.simplex.common.views.helpers.ModalView
|
||||
import chat.simplex.common.views.helpers.SearchTextField
|
||||
import chat.simplex.common.views.helpers.generalGetString
|
||||
import chat.simplex.common.views.helpers.hostDevice
|
||||
import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
|
||||
enum class ContactType {
|
||||
CARD, REQUEST, RECENT, REMOVED, UNKNOWN
|
||||
}
|
||||
|
||||
private fun contactChats(c: List<Chat>, contactTypes: List<ContactType>): List<Chat> {
|
||||
return c.filter { chat -> contactTypes.contains(getContactType(chat)) }
|
||||
}
|
||||
|
||||
private fun getContactType(chat: Chat): ContactType {
|
||||
return when (val cInfo = chat.chatInfo) {
|
||||
is ChatInfo.ContactRequest -> ContactType.REQUEST
|
||||
is ChatInfo.Direct -> {
|
||||
val contact = cInfo.contact;
|
||||
|
||||
when {
|
||||
contact.activeConn == null && contact.profile.contactLink != null -> ContactType.CARD
|
||||
contact.chatDeleted -> ContactType.REMOVED
|
||||
contact.contactStatus != ContactStatus.DeletedByUser && contact.contactStatus != ContactStatus.Deleted -> ContactType.RECENT
|
||||
else -> ContactType.UNKNOWN
|
||||
}
|
||||
}
|
||||
else -> ContactType.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
private val chatsByTypeComparator = Comparator<Chat> { chat1, chat2 ->
|
||||
val chat1Type = getContactType(chat1)
|
||||
val chat2Type = getContactType(chat2)
|
||||
|
||||
when {
|
||||
chat1Type.ordinal < chat2Type.ordinal -> -1
|
||||
chat1Type.ordinal > chat2Type.ordinal -> 1
|
||||
|
||||
else -> chat2.chatInfo.chatTs.compareTo(chat1.chatInfo.chatTs)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ModalData.DeletedContactsView(rh: RemoteHostInfo?, close: () -> Unit) {
|
||||
ModalView(
|
||||
close = close
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxSize(),
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
val bottomPadding = DEFAULT_PADDING
|
||||
AppBarTitle(
|
||||
stringResource(MR.strings.chat_deleted),
|
||||
hostDevice(rh?.remoteHostId),
|
||||
bottomPadding = bottomPadding
|
||||
)
|
||||
}
|
||||
|
||||
ContactsLayout(
|
||||
contactActions = {},
|
||||
contactTypes = listOf(ContactType.REMOVED),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ContactActionsSection(contactActions: @Composable () -> Unit, rh: RemoteHostInfo?) {
|
||||
contactActions()
|
||||
Spacer(Modifier.height(DEFAULT_PADDING))
|
||||
|
||||
val archived = remember { contactChats(chatModel.chats, listOf(ContactType.REMOVED)) }
|
||||
|
||||
if (archived.isNotEmpty()) {
|
||||
SectionView {
|
||||
SectionItemView(
|
||||
click = {
|
||||
ModalManager.start.showCustomModal { close -> DeletedContactsView(
|
||||
rh = rh,
|
||||
close = close)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painterResource(MR.images.ic_folder_open),
|
||||
contentDescription = stringResource(MR.strings.chat_deleted),
|
||||
tint = MaterialTheme.colors.secondary,
|
||||
)
|
||||
TextIconSpaced(extraPadding = true)
|
||||
Text(text = stringResource(MR.strings.chat_deleted), color = MaterialTheme.colors.onBackground)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ContactsLayout(
|
||||
contactActions: @Composable () -> Unit,
|
||||
contactTypes: List<ContactType>,
|
||||
contactListTitle: String? = null) {
|
||||
|
||||
SectionView {
|
||||
ContactsList(
|
||||
contactTypes = contactTypes,
|
||||
contactActions = contactActions,
|
||||
contactListTitle = contactListTitle
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ContactsView(
|
||||
contactActions: @Composable () -> Unit,
|
||||
rh: RemoteHostInfo?
|
||||
) {
|
||||
ContactsLayout(
|
||||
contactActions = { ContactActionsSection(contactActions, rh) },
|
||||
contactTypes = listOf(ContactType.CARD, ContactType.RECENT, ContactType.REQUEST),
|
||||
contactListTitle = stringResource(MR.strings.contact_list_header_title).uppercase()
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ContactsSearchBar(listState: LazyListState, searchText: MutableState<TextFieldValue>, focused: Boolean, onFocusChanged: (hasFocus: Boolean) -> Unit) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
Icon(painterResource(MR.images.ic_search), null, Modifier.padding(horizontal = DEFAULT_PADDING_HALF), tint = MaterialTheme.colors.secondary)
|
||||
SearchTextField(
|
||||
Modifier.weight(1f).onFocusChanged { onFocusChanged(it.hasFocus) }.focusRequester(focusRequester),
|
||||
placeholder = stringResource(MR.strings.search_verb),
|
||||
alwaysVisible = true,
|
||||
searchText = searchText,
|
||||
trailingContent = null,
|
||||
) {
|
||||
searchText.value = searchText.value.copy(it)
|
||||
}
|
||||
val hasText = remember { derivedStateOf { searchText.value.text.isNotEmpty() } }
|
||||
if (hasText.value) {
|
||||
val hideSearchOnBack: () -> Unit = { searchText.value = TextFieldValue() }
|
||||
BackHandler(onBack = hideSearchOnBack)
|
||||
KeyChangeEffect(chatModel.currentRemoteHost.value) {
|
||||
hideSearchOnBack()
|
||||
}
|
||||
} else {
|
||||
Row {
|
||||
val padding = if (appPlatform.isDesktop) 0.dp else 7.dp
|
||||
if (chatModel.chats.size > 0) {
|
||||
ToggleFilterButton()
|
||||
}
|
||||
Spacer(Modifier.width(padding))
|
||||
}
|
||||
}
|
||||
val focusManager = LocalFocusManager.current
|
||||
val keyboardState = getKeyboardState()
|
||||
LaunchedEffect(keyboardState.value) {
|
||||
if (keyboardState.value == KeyboardState.Closed && focused) {
|
||||
focusManager.clearFocus()
|
||||
}
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
snapshotFlow { searchText.value.text }
|
||||
.distinctUntilChanged()
|
||||
.collect {
|
||||
if (it.isNotEmpty()) {
|
||||
focusRequester.requestFocus()
|
||||
} else if (listState.layoutInfo.totalItemsCount > 0) {
|
||||
listState.scrollToItem(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ToggleFilterButton() {
|
||||
val pref = remember { ChatController.appPrefs.showUnreadAndFavorites }
|
||||
IconButton(onClick = { pref.set(!pref.get()) }) {
|
||||
val sp16 = with(LocalDensity.current) { 16.sp.toDp() }
|
||||
Icon(
|
||||
painterResource(MR.images.ic_filter_list),
|
||||
null,
|
||||
tint = if (pref.state.value) MaterialTheme.colors.background else MaterialTheme.colors.secondary,
|
||||
modifier = Modifier
|
||||
.padding(3.dp)
|
||||
.background(color = if (pref.state.value) MaterialTheme.colors.primary else Color.Unspecified, shape = RoundedCornerShape(50))
|
||||
.border(width = 1.dp, color = if (pref.state.value) MaterialTheme.colors.primary else Color.Unspecified, shape = RoundedCornerShape(50))
|
||||
.padding(3.dp)
|
||||
.size(sp16)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private var lazyListState = 0 to 0
|
||||
|
||||
@Composable
|
||||
private fun ContactsList(
|
||||
contactActions: @Composable () -> Unit,
|
||||
contactTypes: List<ContactType>,
|
||||
contactListTitle: String ? = null
|
||||
) {
|
||||
val listState = rememberLazyListState(lazyListState.first, lazyListState.second)
|
||||
val searchText = rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(
|
||||
TextFieldValue("")
|
||||
) }
|
||||
|
||||
var searchFocused by remember { mutableStateOf(false) }
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
onDispose {
|
||||
lazyListState =
|
||||
listState.firstVisibleItemIndex to listState.firstVisibleItemScrollOffset
|
||||
}
|
||||
}
|
||||
val showUnreadAndFavorites =
|
||||
remember { ChatController.appPrefs.showUnreadAndFavorites.state }.value
|
||||
|
||||
val allChats by remember(chatModel.chats, contactTypes) {
|
||||
derivedStateOf { contactChats(chatModel.chats, contactTypes) }
|
||||
}
|
||||
|
||||
val filteredContactChats = filteredContactChats(
|
||||
showUnreadAndFavorites = showUnreadAndFavorites,
|
||||
searchText = searchText.value.text,
|
||||
contactChats = allChats
|
||||
)
|
||||
|
||||
LazyColumn(
|
||||
Modifier.fillMaxWidth(),
|
||||
listState
|
||||
) {
|
||||
item {
|
||||
SectionView {
|
||||
Divider()
|
||||
ContactsSearchBar(
|
||||
listState = listState,
|
||||
searchText = searchText,
|
||||
focused = searchFocused,
|
||||
onFocusChanged = {
|
||||
searchFocused = it
|
||||
}
|
||||
)
|
||||
Divider()
|
||||
}
|
||||
|
||||
if (!searchFocused) {
|
||||
contactActions()
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(DEFAULT_PADDING))
|
||||
|
||||
if (contactListTitle != null && filteredContactChats.isNotEmpty()) {
|
||||
Text(
|
||||
contactListTitle, color = MaterialTheme.colors.secondary, style = MaterialTheme.typography.body2,
|
||||
modifier = Modifier.padding(start = DEFAULT_PADDING, bottom = 5.dp), fontSize = 12.sp
|
||||
)
|
||||
}
|
||||
}
|
||||
itemsIndexed(filteredContactChats) { index, chat ->
|
||||
val nextChatSelected = remember(chat.id, filteredContactChats) {
|
||||
derivedStateOf {
|
||||
chatModel.chatId.value != null && filteredContactChats.getOrNull(index + 1)?.id == chatModel.chatId.value
|
||||
}
|
||||
}
|
||||
SectionItemView(padding = PaddingValues(horizontal = DEFAULT_PADDING)) {
|
||||
ContactListNavLinkView(chat, nextChatSelected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredContactChats.isEmpty() && allChats.isNotEmpty()) {
|
||||
Column(Modifier.fillMaxSize().padding(DEFAULT_PADDING)) {
|
||||
Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
|
||||
Text(
|
||||
generalGetString(MR.strings.no_filtered_contacts),
|
||||
color = MaterialTheme.colors.secondary
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun filterChat(chat: Chat, searchText: String, showUnreadAndFavorites: Boolean): Boolean {
|
||||
var meetsPredicate = true;
|
||||
val s = searchText.trim().lowercase()
|
||||
val cInfo = chat.chatInfo
|
||||
|
||||
if (searchText.isNotEmpty()) {
|
||||
meetsPredicate = viewNameContains(cInfo, s) ||
|
||||
if (cInfo is ChatInfo.Direct) (cInfo.contact.profile.displayName.lowercase().contains(s) ||
|
||||
cInfo.contact.fullName.lowercase().contains(s)) else false
|
||||
}
|
||||
|
||||
if (showUnreadAndFavorites) {
|
||||
meetsPredicate = meetsPredicate && (cInfo.chatSettings?.favorite ?: false)
|
||||
}
|
||||
|
||||
return meetsPredicate;
|
||||
}
|
||||
|
||||
private fun filteredContactChats(
|
||||
showUnreadAndFavorites: Boolean,
|
||||
searchText: String,
|
||||
contactChats: List<Chat>
|
||||
): List<Chat> {
|
||||
return contactChats
|
||||
.filter { chat -> filterChat(
|
||||
chat = chat,
|
||||
searchText = searchText,
|
||||
showUnreadAndFavorites = showUnreadAndFavorites) }
|
||||
.sortedWith(chatsByTypeComparator)
|
||||
}
|
||||
|
||||
private fun viewNameContains(cInfo: ChatInfo, s: String): Boolean =
|
||||
cInfo.chatViewName.lowercase().contains(s.lowercase())
|
||||
+18
-5
@@ -69,16 +69,19 @@ class AlertManager {
|
||||
fun showAlertDialogButtonsColumn(
|
||||
title: String,
|
||||
text: String? = null,
|
||||
textAlign: TextAlign = TextAlign.Center,
|
||||
dismissible: Boolean = true,
|
||||
onDismissRequest: (() -> Unit)? = null,
|
||||
hostDevice: Pair<Long?, String>? = null,
|
||||
belowTextContent: @Composable (() -> Unit) = {},
|
||||
buttons: @Composable () -> Unit,
|
||||
) {
|
||||
showAlert {
|
||||
AlertDialog(
|
||||
onDismissRequest = { onDismissRequest?.invoke(); hideAlert() },
|
||||
onDismissRequest = { onDismissRequest?.invoke(); if (dismissible) hideAlert() },
|
||||
title = alertTitle(title),
|
||||
buttons = {
|
||||
AlertContent(text, hostDevice, extraPadding = true) {
|
||||
AlertContent(text, hostDevice, extraPadding = true, textAlign = textAlign, belowTextContent = belowTextContent) {
|
||||
buttons()
|
||||
}
|
||||
},
|
||||
@@ -286,7 +289,14 @@ private fun alertTitle(title: String): (@Composable () -> Unit)? {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AlertContent(text: String?, hostDevice: Pair<Long?, String>?, extraPadding: Boolean = false, content: @Composable (() -> Unit)) {
|
||||
private fun AlertContent(
|
||||
text: String?,
|
||||
hostDevice: Pair<Long?, String>?,
|
||||
extraPadding: Boolean = false,
|
||||
textAlign: TextAlign = TextAlign.Center,
|
||||
belowTextContent: @Composable (() -> Unit) = {},
|
||||
content: @Composable (() -> Unit)
|
||||
) {
|
||||
BoxWithConstraints {
|
||||
Column(
|
||||
Modifier
|
||||
@@ -300,17 +310,20 @@ private fun AlertContent(text: String?, hostDevice: Pair<Long?, String>?, extraP
|
||||
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
|
||||
if (text != null) {
|
||||
Column(Modifier.heightIn(max = this@BoxWithConstraints.maxHeight * 0.7f)
|
||||
.padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING)
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
SelectionContainer {
|
||||
Text(
|
||||
escapedHtmlToAnnotatedString(text, LocalDensity.current),
|
||||
Modifier.fillMaxWidth().padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, bottom = DEFAULT_PADDING * 1.5f),
|
||||
Modifier.fillMaxWidth(),
|
||||
fontSize = 16.sp,
|
||||
textAlign = TextAlign.Center,
|
||||
textAlign = textAlign,
|
||||
color = MaterialTheme.colors.secondary
|
||||
)
|
||||
}
|
||||
belowTextContent()
|
||||
Spacer(Modifier.height(DEFAULT_PADDING * 1.5f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -126,6 +126,5 @@ private fun TopAppBar(
|
||||
|
||||
val AppBarHeight = 56.dp
|
||||
val AppBarHorizontalPadding = 4.dp
|
||||
val BottomAppBarHeight = 60.dp
|
||||
private val TitleInsetWithoutIcon = DEFAULT_PADDING - AppBarHorizontalPadding
|
||||
val TitleInsetWithIcon = 72.dp
|
||||
|
||||
+69
-3
@@ -1,5 +1,8 @@
|
||||
package chat.simplex.common.views.newchat
|
||||
|
||||
import SectionItemView
|
||||
import SectionView
|
||||
import TextIconSpaced
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.core.*
|
||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
@@ -10,6 +13,7 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.drawBehind
|
||||
@@ -19,12 +23,16 @@ import androidx.compose.ui.platform.*
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.model.RemoteHostInfo
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.contacts.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.res.MR
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -32,10 +40,69 @@ import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@Composable
|
||||
fun ModalData.NewChatView(rh: RemoteHostInfo?) {
|
||||
Column(
|
||||
Modifier.fillMaxSize(),
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
val bottomPadding = DEFAULT_PADDING
|
||||
AppBarTitle(
|
||||
stringResource(MR.strings.new_chat),
|
||||
hostDevice(rh?.remoteHostId),
|
||||
bottomPadding = bottomPadding
|
||||
)
|
||||
}
|
||||
|
||||
ContactsView(
|
||||
contactActions = {
|
||||
NewChatOptions(
|
||||
addContact = {
|
||||
ModalManager.center.closeModals()
|
||||
ModalManager.center.showModalCloseable { close -> NewChatView(chatModel.currentRemoteHost.value, NewChatOption.INVITE, close = close) }
|
||||
},
|
||||
scanPaste = {
|
||||
ModalManager.center.closeModals()
|
||||
ModalManager.center.showModalCloseable { close -> NewChatView(chatModel.currentRemoteHost.value, NewChatOption.CONNECT, showQRCodeScanner = true, close = close) }
|
||||
},
|
||||
createGroup = {
|
||||
ModalManager.center.closeModals()
|
||||
ModalManager.center.showCustomModal { close -> AddGroupView(chatModel, chatModel.currentRemoteHost.value, close) }
|
||||
}
|
||||
)
|
||||
},
|
||||
rh = rh
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NewChatButton(icon: Painter, text: String, click: () -> Unit, textColor: Color = Color.Unspecified, iconColor: Color = MaterialTheme.colors.secondary, disabled: Boolean = false, extraPadding: Boolean = false) {
|
||||
SectionItemView(click, disabled = disabled) {
|
||||
Icon(icon, text, tint = if (disabled) MaterialTheme.colors.secondary else iconColor)
|
||||
TextIconSpaced(extraPadding)
|
||||
Text(text, color = if (disabled) MaterialTheme.colors.secondary else textColor)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NewChatOptions(addContact: () -> Unit, scanPaste: () -> Unit, createGroup: () -> Unit) {
|
||||
val actions = remember { listOf(addContact, scanPaste, createGroup) }
|
||||
|
||||
Column {
|
||||
actions.forEachIndexed { index, _ ->
|
||||
NewChatButton(
|
||||
icon = painterResource(icons[index]),
|
||||
text = stringResource(titles[index]),
|
||||
click = actions[index],
|
||||
extraPadding = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NewChatSheet(chatModel: ChatModel, newChatSheetState: StateFlow<AnimatedViewState>, stopped: Boolean, closeNewChatSheet: (animated: Boolean) -> Unit) {
|
||||
// TODO close new chat if remote host changes in model
|
||||
if (newChatSheetState.collectAsState().value.isVisible()) BackHandler { closeNewChatSheet(true) }
|
||||
NewChatSheetLayout(
|
||||
newChatSheetState,
|
||||
stopped,
|
||||
@@ -50,7 +117,6 @@ fun NewChatSheet(chatModel: ChatModel, newChatSheetState: StateFlow<AnimatedView
|
||||
ModalManager.center.showModalCloseable { close -> NewChatView(chatModel.currentRemoteHost.value, NewChatOption.CONNECT, showQRCodeScanner = true, close = close) }
|
||||
},
|
||||
createGroup = {
|
||||
closeNewChatSheet(false)
|
||||
ModalManager.center.closeModals()
|
||||
ModalManager.center.showCustomModal { close -> AddGroupView(chatModel, chatModel.currentRemoteHost.value, close) }
|
||||
},
|
||||
@@ -152,7 +218,7 @@ private fun NewChatSheetLayout(
|
||||
}
|
||||
FloatingActionButton(
|
||||
onClick = { if (!stopped) closeNewChatSheet(true) },
|
||||
Modifier.padding(end = DEFAULT_PADDING, bottom = DEFAULT_PADDING + BottomAppBarHeight).size(AppBarHeight * fontSizeSqrtMultiplier),
|
||||
Modifier.padding(end = DEFAULT_PADDING, bottom = DEFAULT_PADDING).size(AppBarHeight * fontSizeSqrtMultiplier),
|
||||
elevation = FloatingActionButtonDefaults.elevation(
|
||||
defaultElevation = 0.dp,
|
||||
pressedElevation = 0.dp,
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ private fun LinkAMobileLayout(
|
||||
SectionView(generalGetString(MR.strings.this_device_name).uppercase()) {
|
||||
DeviceNameField(deviceName.value ?: "") { updateDeviceName(it) }
|
||||
SectionTextFooter(generalGetString(MR.strings.this_device_name_shared_with_mobile))
|
||||
PreferenceToggle(stringResource(MR.strings.multicast_discoverable_via_local_network), remember { ChatModel.controller.appPrefs.offerRemoteMulticast.state }.value) {
|
||||
PreferenceToggle(stringResource(MR.strings.multicast_discoverable_via_local_network), checked = remember { ChatModel.controller.appPrefs.offerRemoteMulticast.state }.value) {
|
||||
ChatModel.controller.appPrefs.offerRemoteMulticast.set(it)
|
||||
}
|
||||
}
|
||||
|
||||
+11
-6
@@ -118,13 +118,8 @@ fun WhatsNewView(viaSettings: Boolean = false, close: () -> Unit) {
|
||||
featureDescription(painterResource(feature.icon), feature.titleId, feature.descrId, feature.link)
|
||||
}
|
||||
|
||||
val uriHandler = LocalUriHandler.current
|
||||
if (v.post != null) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.padding(top = DEFAULT_PADDING.div(4))) {
|
||||
Text(stringResource(MR.strings.whats_new_read_more), color = MaterialTheme.colors.primary,
|
||||
modifier = Modifier.clickable { uriHandler.openUriCatching(v.post) })
|
||||
Icon(painterResource(MR.images.ic_open_in_new), stringResource(MR.strings.whats_new_read_more), tint = MaterialTheme.colors.primary)
|
||||
}
|
||||
ReadMoreButton(v.post)
|
||||
}
|
||||
|
||||
if (!viaSettings) {
|
||||
@@ -149,6 +144,16 @@ fun WhatsNewView(viaSettings: Boolean = false, close: () -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ReadMoreButton(url: String) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.padding(top = DEFAULT_PADDING.div(4))) {
|
||||
Text(stringResource(MR.strings.whats_new_read_more), color = MaterialTheme.colors.primary,
|
||||
modifier = Modifier.clickable { uriHandler.openUriCatching(url) })
|
||||
Icon(painterResource(MR.images.ic_open_in_new), stringResource(MR.strings.whats_new_read_more), tint = MaterialTheme.colors.primary)
|
||||
}
|
||||
}
|
||||
|
||||
private data class FeatureDescription(
|
||||
val icon: ImageResource,
|
||||
val titleId: StringResource,
|
||||
|
||||
+3
-3
@@ -432,14 +432,14 @@ private fun LinkedDesktopsView(remoteCtrls: SnapshotStateList<RemoteCtrlInfo>) {
|
||||
SectionDividerSpaced()
|
||||
|
||||
SectionView(stringResource(MR.strings.linked_desktop_options).uppercase()) {
|
||||
PreferenceToggle(stringResource(MR.strings.verify_connections), remember { controller.appPrefs.confirmRemoteSessions.state }.value) {
|
||||
PreferenceToggle(stringResource(MR.strings.verify_connections), checked = remember { controller.appPrefs.confirmRemoteSessions.state }.value) {
|
||||
controller.appPrefs.confirmRemoteSessions.set(it)
|
||||
}
|
||||
PreferenceToggle(stringResource(MR.strings.discover_on_network), remember { controller.appPrefs.connectRemoteViaMulticast.state }.value) {
|
||||
PreferenceToggle(stringResource(MR.strings.discover_on_network), checked = remember { controller.appPrefs.connectRemoteViaMulticast.state }.value) {
|
||||
controller.appPrefs.connectRemoteViaMulticast.set(it)
|
||||
}
|
||||
if (remember { controller.appPrefs.connectRemoteViaMulticast.state }.value) {
|
||||
PreferenceToggle(stringResource(MR.strings.multicast_connect_automatically), remember { controller.appPrefs.connectRemoteViaMulticastAuto.state }.value) {
|
||||
PreferenceToggle(stringResource(MR.strings.multicast_connect_automatically), checked = remember { controller.appPrefs.connectRemoteViaMulticastAuto.state }.value) {
|
||||
controller.appPrefs.connectRemoteViaMulticastAuto.set(it)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ fun ConnectMobileLayout(
|
||||
SectionView(generalGetString(MR.strings.this_device_name).uppercase()) {
|
||||
DeviceNameField(deviceName.value ?: "") { updateDeviceName(it) }
|
||||
SectionTextFooter(generalGetString(MR.strings.this_device_name_shared_with_mobile))
|
||||
PreferenceToggle(stringResource(MR.strings.multicast_discoverable_via_local_network), remember { controller.appPrefs.offerRemoteMulticast.state }.value) {
|
||||
PreferenceToggle(stringResource(MR.strings.multicast_discoverable_via_local_network), checked = remember { controller.appPrefs.offerRemoteMulticast.state }.value) {
|
||||
controller.appPrefs.offerRemoteMulticast.set(it)
|
||||
}
|
||||
SectionDividerSpaced(maxBottomPadding = false)
|
||||
|
||||
+9
-3
@@ -175,10 +175,16 @@ private fun UseServerSection(
|
||||
Text(stringResource(MR.strings.smp_servers_test_server), color = if (valid && !testing) MaterialTheme.colors.onBackground else MaterialTheme.colors.secondary)
|
||||
ShowTestStatus(server)
|
||||
}
|
||||
val enabled = rememberUpdatedState(server.enabled == ServerEnabled.Enabled)
|
||||
PreferenceToggle(stringResource(MR.strings.smp_servers_use_server_for_new_conn), enabled.value) { enable ->
|
||||
onUpdate(server.copy(enabled = if (enable) ServerEnabled.Enabled else ServerEnabled.Disabled))
|
||||
|
||||
val enabled = rememberUpdatedState(server.enabled)
|
||||
PreferenceToggle(
|
||||
stringResource(MR.strings.smp_servers_use_server_for_new_conn),
|
||||
disabled = server.tested != true && !server.preset,
|
||||
checked = enabled.value
|
||||
) {
|
||||
onUpdate(server.copy(enabled = it))
|
||||
}
|
||||
|
||||
SectionItemView(onDelete, disabled = testing) {
|
||||
Text(stringResource(MR.strings.smp_servers_delete_server), color = if (testing) MaterialTheme.colors.secondary else MaterialTheme.colors.error)
|
||||
}
|
||||
|
||||
+47
-27
@@ -28,13 +28,13 @@ import chat.simplex.res.MR
|
||||
|
||||
@Composable
|
||||
fun ModalData.ProtocolServersView(m: ChatModel, rhId: Long?, serverProtocol: ServerProtocol, close: () -> Unit) {
|
||||
var presetServers by remember(rhId) { mutableStateOf(emptyList<String>()) }
|
||||
var presetServers by remember(rhId) { mutableStateOf(emptyList<ServerCfg>()) }
|
||||
var servers by remember { stateGetOrPut("servers") { emptyList<ServerCfg>() } }
|
||||
var serversAlreadyLoaded by remember { stateGetOrPut("serversAlreadyLoaded") { false } }
|
||||
val currServers = remember(rhId) { mutableStateOf(servers) }
|
||||
val testing = rememberSaveable(rhId) { mutableStateOf(false) }
|
||||
val serversUnchanged = remember(servers) { derivedStateOf { servers == currServers.value || testing.value } }
|
||||
val allServersDisabled = remember { derivedStateOf { servers.none { it.enabled == ServerEnabled.Enabled } } }
|
||||
val allServersDisabled = remember { derivedStateOf { servers.none { it.enabled } } }
|
||||
val saveDisabled = remember(servers) {
|
||||
derivedStateOf {
|
||||
servers.isEmpty() ||
|
||||
@@ -198,12 +198,42 @@ private fun ProtocolServersLayout(
|
||||
) {
|
||||
AppBarTitle(stringResource(if (serverProtocol == ServerProtocol.SMP) MR.strings.your_SMP_servers else MR.strings.your_XFTP_servers))
|
||||
|
||||
SectionView(stringResource(if (serverProtocol == ServerProtocol.SMP) MR.strings.smp_servers else MR.strings.xftp_servers).uppercase()) {
|
||||
for (srv in servers) {
|
||||
SectionItemView({ showServer(srv) }, disabled = testing) {
|
||||
ProtocolServerView(serverProtocol, srv, servers, testing)
|
||||
val configuredServers = servers.filter { it.preset || it.enabled }
|
||||
val otherServers = servers.filter { !(it.preset || it.enabled) }
|
||||
|
||||
if (configuredServers.isNotEmpty()) {
|
||||
SectionView(stringResource(if (serverProtocol == ServerProtocol.SMP) MR.strings.smp_servers_configured else MR.strings.xftp_servers_configured).uppercase()) {
|
||||
for (srv in configuredServers) {
|
||||
SectionItemView({ showServer(srv) }, disabled = testing) {
|
||||
ProtocolServerView(serverProtocol, srv, servers, testing)
|
||||
}
|
||||
}
|
||||
}
|
||||
SectionTextFooter(
|
||||
remember(currentUser?.displayName) {
|
||||
buildAnnotatedString {
|
||||
append(generalGetString(MR.strings.smp_servers_per_user) + " ")
|
||||
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(currentUser?.displayName ?: "")
|
||||
}
|
||||
append(".")
|
||||
}
|
||||
}
|
||||
)
|
||||
SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false)
|
||||
}
|
||||
|
||||
if (otherServers.isNotEmpty()) {
|
||||
SectionView(stringResource(if (serverProtocol == ServerProtocol.SMP) MR.strings.smp_servers_other else MR.strings.xftp_servers_other).uppercase()) {
|
||||
for (srv in otherServers.filter { !(it.preset || it.enabled) }) {
|
||||
SectionItemView({ showServer(srv) }, disabled = testing) {
|
||||
ProtocolServerView(serverProtocol, srv, servers, testing)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SectionView {
|
||||
SettingsActionItem(
|
||||
painterResource(MR.images.ic_add),
|
||||
stringResource(MR.strings.smp_servers_add),
|
||||
@@ -212,19 +242,9 @@ private fun ProtocolServersLayout(
|
||||
textColor = if (testing) MaterialTheme.colors.secondary else MaterialTheme.colors.primary,
|
||||
iconColor = if (testing) MaterialTheme.colors.secondary else MaterialTheme.colors.primary
|
||||
)
|
||||
SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false)
|
||||
}
|
||||
SectionTextFooter(
|
||||
remember(currentUser?.displayName) {
|
||||
buildAnnotatedString {
|
||||
append(generalGetString(MR.strings.smp_servers_per_user) + " ")
|
||||
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(currentUser?.displayName ?: "")
|
||||
}
|
||||
append(".")
|
||||
}
|
||||
}
|
||||
)
|
||||
SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false)
|
||||
|
||||
SectionView {
|
||||
SectionItemView(resetServers, disabled = serversUnchanged) {
|
||||
Text(stringResource(MR.strings.reset_verb), color = if (!serversUnchanged) MaterialTheme.colors.onBackground else MaterialTheme.colors.secondary)
|
||||
@@ -250,12 +270,12 @@ private fun ProtocolServerView(serverProtocol: ServerProtocol, srv: ServerCfg, s
|
||||
val address = parseServerAddress(srv.server)
|
||||
when {
|
||||
address == null || !address.valid || address.serverProtocol != serverProtocol || !uniqueAddress(srv, address, servers) -> InvalidServer()
|
||||
srv.enabled != ServerEnabled.Enabled -> Icon(painterResource(MR.images.ic_do_not_disturb_on), null, tint = MaterialTheme.colors.secondary)
|
||||
!srv.enabled -> Icon(painterResource(MR.images.ic_do_not_disturb_on), null, tint = MaterialTheme.colors.secondary)
|
||||
else -> ShowTestStatus(srv)
|
||||
}
|
||||
Spacer(Modifier.padding(horizontal = 4.dp))
|
||||
val text = address?.hostnames?.firstOrNull() ?: srv.server
|
||||
if (srv.enabled == ServerEnabled.Enabled) {
|
||||
if (srv.enabled) {
|
||||
Text(text, color = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.onBackground, maxLines = 1)
|
||||
} else {
|
||||
Text(text, maxLines = 1, color = MaterialTheme.colors.secondary)
|
||||
@@ -285,21 +305,21 @@ private fun uniqueAddress(s: ServerCfg, address: ServerAddress, servers: List<Se
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasAllPresets(presetServers: List<String>, servers: List<ServerCfg>, m: ChatModel): Boolean =
|
||||
private fun hasAllPresets(presetServers: List<ServerCfg>, servers: List<ServerCfg>, m: ChatModel): Boolean =
|
||||
presetServers.all { hasPreset(it, servers) } ?: true
|
||||
|
||||
private fun addAllPresets(rhId: Long?, presetServers: List<String>, servers: List<ServerCfg>, m: ChatModel): List<ServerCfg> {
|
||||
private fun addAllPresets(rhId: Long?, presetServers: List<ServerCfg>, servers: List<ServerCfg>, m: ChatModel): List<ServerCfg> {
|
||||
val toAdd = ArrayList<ServerCfg>()
|
||||
for (srv in presetServers) {
|
||||
if (!hasPreset(srv, servers)) {
|
||||
toAdd.add(ServerCfg(remoteHostId = rhId, srv, preset = true, tested = null, enabled = ServerEnabled.Enabled))
|
||||
toAdd.add(srv)
|
||||
}
|
||||
}
|
||||
return toAdd
|
||||
}
|
||||
|
||||
private fun hasPreset(srv: String, servers: List<ServerCfg>): Boolean =
|
||||
servers.any { it.server == srv }
|
||||
private fun hasPreset(srv: ServerCfg, servers: List<ServerCfg>): Boolean =
|
||||
servers.any { it.server == srv.server }
|
||||
|
||||
private suspend fun testServers(testing: MutableState<Boolean>, servers: List<ServerCfg>, m: ChatModel, onUpdated: (List<ServerCfg>) -> Unit) {
|
||||
val resetStatus = resetTestStatus(servers)
|
||||
@@ -319,7 +339,7 @@ private suspend fun testServers(testing: MutableState<Boolean>, servers: List<Se
|
||||
private fun resetTestStatus(servers: List<ServerCfg>): List<ServerCfg> {
|
||||
val copy = ArrayList(servers)
|
||||
for ((index, server) in servers.withIndex()) {
|
||||
if (server.enabled == ServerEnabled.Enabled) {
|
||||
if (server.enabled) {
|
||||
copy.removeAt(index)
|
||||
copy.add(index, server.copy(tested = null))
|
||||
}
|
||||
@@ -331,7 +351,7 @@ private suspend fun runServersTest(servers: List<ServerCfg>, m: ChatModel, onUpd
|
||||
val fs: MutableMap<String, ProtocolTestFailure> = mutableMapOf()
|
||||
val updatedServers = ArrayList<ServerCfg>(servers)
|
||||
for ((index, server) in servers.withIndex()) {
|
||||
if (server.enabled == ServerEnabled.Enabled) {
|
||||
if (server.enabled) {
|
||||
interruptIfCancelled()
|
||||
val (updatedServer, f) = testServerConnection(server, m)
|
||||
updatedServers.removeAt(index)
|
||||
|
||||
+1
-2
@@ -7,7 +7,6 @@ import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.model.ServerAddress.Companion.parseServerAddress
|
||||
import chat.simplex.common.model.ServerCfg
|
||||
import chat.simplex.common.model.ServerEnabled
|
||||
import chat.simplex.common.ui.theme.DEFAULT_PADDING
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.newchat.QRCodeScanner
|
||||
@@ -26,7 +25,7 @@ fun ScanProtocolServerLayout(rhId: Long?, onNext: (ServerCfg) -> Unit) {
|
||||
QRCodeScanner { text ->
|
||||
val res = parseServerAddress(text)
|
||||
if (res != null) {
|
||||
onNext(ServerCfg(remoteHostId = rhId, text, false, null, ServerEnabled.Enabled))
|
||||
onNext(ServerCfg(remoteHostId = rhId, text, false, null, false))
|
||||
} else {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.smp_servers_invalid_address),
|
||||
|
||||
+6
-1
@@ -73,6 +73,9 @@ fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit, drawerSt
|
||||
withAuth = ::doWithAuth,
|
||||
drawerState = drawerState,
|
||||
)
|
||||
KeyChangeEffect(chatModel.updatingProgress.value != null) {
|
||||
drawerState.close()
|
||||
}
|
||||
}
|
||||
|
||||
val simplexTeamUri =
|
||||
@@ -416,13 +419,15 @@ fun SettingsPreferenceItem(
|
||||
@Composable
|
||||
fun PreferenceToggle(
|
||||
text: String,
|
||||
disabled: Boolean = false,
|
||||
checked: Boolean,
|
||||
onChange: (Boolean) -> Unit = {},
|
||||
) {
|
||||
SettingsActionItemWithContent(null, text, extraPadding = true,) {
|
||||
SettingsActionItemWithContent(null, text, disabled = disabled, extraPadding = true,) {
|
||||
DefaultSwitch(
|
||||
checked = checked,
|
||||
onCheckedChange = onChange,
|
||||
enabled = !disabled
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<string name="smp_servers_add_to_another_device">أضِف إلى جهاز آخر</string>
|
||||
<string name="users_delete_all_chats_deleted">سيتم حذف جميع الدردشات والرسائل - لا يمكن التراجع عن هذا!</string>
|
||||
<string name="network_enable_socks_info">الوصول إلى الخوادم عبر بروكسي SOCKS على المنفذ %d؟ يجب بدء تشغيل الوكيل قبل تمكين هذا الخيار.</string>
|
||||
<string name="smp_servers_add">أضِف خادم…</string>
|
||||
<string name="smp_servers_add">أضِف خادم</string>
|
||||
<string name="network_settings">إعدادات الشبكة المتقدمة</string>
|
||||
<string name="all_group_members_will_remain_connected">سيبقى جميع أعضاء المجموعة على اتصال.</string>
|
||||
<string name="allow_disappearing_messages_only_if">السماح باختفاء الرسائل فقط إذا سمحت جهة اتصالك بذلك.</string>
|
||||
@@ -1856,4 +1856,19 @@
|
||||
\nError: %s</string>
|
||||
<string name="v5_8_message_delivery">تحسين تسليم الرسائل</string>
|
||||
<string name="v5_8_message_delivery_descr">مع انخفاض استخدام البطارية.</string>
|
||||
<string name="file_error_auth">مفتاح خاطئ أو عنوان مجموعة الملف غير معروف - على الأرجح حُذف الملف.</string>
|
||||
<string name="file_error_relay">خطأ في خادم الملفات: %1$s</string>
|
||||
<string name="file_error">خطأ في الملف</string>
|
||||
<string name="temporary_file_error">خطأ في الملف مؤقت</string>
|
||||
<string name="info_row_message_status">حالة الرسالة</string>
|
||||
<string name="file_error_no_file">لم يتم العثور على الملف - على الأرجح حُذف الملف أو إلغاؤه.</string>
|
||||
<string name="info_row_file_status">حالة الملف</string>
|
||||
<string name="share_text_file_status">حالة الملف: %s</string>
|
||||
<string name="share_text_message_status">حالة الرسالة: %s</string>
|
||||
<string name="copy_error">خطأ في النسخ</string>
|
||||
<string name="remote_ctrl_connection_stopped_identity_desc">تم استخدام هذا الرابط مع جهاز محمول آخر، يُرجى إنشاء رابط جديد على سطح المكتب.</string>
|
||||
<string name="remote_ctrl_connection_stopped_desc">يُرجى التحقق من اتصال الهاتف المحمول وسطح المكتب بنفس الشبكة المحلية، وأن جدار حماية سطح المكتب يسمح بالاتصال.
|
||||
\nيُرجى مشاركة أي مشاكل أُخرى مع المطورين.</string>
|
||||
<string name="cannot_share_message_alert_title">لا يمكن إرسال الرسالة</string>
|
||||
<string name="cannot_share_message_alert_text">تفضيلات الدردشة المحدّدة تحظر هذه الرسالة.</string>
|
||||
</resources>
|
||||
@@ -112,6 +112,10 @@
|
||||
<string name="connection_timeout">Connection timeout</string>
|
||||
<string name="connection_error">Connection error</string>
|
||||
<string name="network_error_desc">Please check your network connection with %1$s and try again.</string>
|
||||
<string name="network_error_broker_host_desc">Server address is incompatible with network settings: %1$s.</string>
|
||||
<string name="network_error_broker_version_desc">Server version is incompatible with your app: %1$s.</string>
|
||||
<string name="private_routing_error">Private routing error</string>
|
||||
<string name="please_try_later">Please try later.</string>
|
||||
<string name="error_sending_message">Error sending message</string>
|
||||
<string name="error_creating_message">Error creating message</string>
|
||||
<string name="error_loading_details">Error loading details</string>
|
||||
@@ -688,9 +692,11 @@
|
||||
<string name="chat_lock">SimpleX Lock</string>
|
||||
<string name="chat_console">Chat console</string>
|
||||
<string name="smp_servers">SMP servers</string>
|
||||
<string name="smp_servers_configured">Configured SMP servers</string>
|
||||
<string name="smp_servers_other">Other SMP servers</string>
|
||||
<string name="smp_servers_preset_address">Preset server address</string>
|
||||
<string name="smp_servers_preset_add">Add preset servers</string>
|
||||
<string name="smp_servers_add">Add server…</string>
|
||||
<string name="smp_servers_add">Add server</string>
|
||||
<string name="smp_servers_test_server">Test server</string>
|
||||
<string name="smp_servers_test_servers">Test servers</string>
|
||||
<string name="smp_servers_save">Save servers</string>
|
||||
@@ -710,6 +716,8 @@
|
||||
<string name="smp_servers_per_user">The servers for new connections of your current chat profile</string>
|
||||
<string name="smp_save_servers_question">Save servers?</string>
|
||||
<string name="xftp_servers">XFTP servers</string>
|
||||
<string name="xftp_servers_configured">Configured XFTP servers</string>
|
||||
<string name="xftp_servers_other">Other XFTP servers</string>
|
||||
<string name="subscription_percentage">Subscription percentage</string>
|
||||
<string name="install_simplex_chat_for_terminal">Install SimpleX Chat for terminal</string>
|
||||
<string name="star_on_github">Star on GitHub</string>
|
||||
@@ -787,6 +795,25 @@
|
||||
<string name="app_version_code">App build: %s</string>
|
||||
<string name="core_version">Core version: v%s</string>
|
||||
<string name="core_simplexmq_version">simplexmq: v%s (%2s)</string>
|
||||
<string name="app_check_for_updates">Check for updates</string>
|
||||
<string name="app_check_for_updates_disabled">Disabled</string>
|
||||
<string name="app_check_for_updates_stable">Stable</string>
|
||||
<string name="app_check_for_updates_beta">Beta</string>
|
||||
<string name="app_check_for_updates_update_available">Update available: %s</string>
|
||||
<string name="app_check_for_updates_button_download">Download %s (%s)</string>
|
||||
<string name="app_check_for_updates_button_skip">Skip this version</string>
|
||||
<string name="app_check_for_updates_download_started">Downloading app update, don\'t close the app</string>
|
||||
<string name="app_check_for_updates_download_completed_title">App update is downloaded</string>
|
||||
<string name="app_check_for_updates_button_open">Open file location</string>
|
||||
<string name="app_check_for_updates_button_install">Install update</string>
|
||||
<string name="app_check_for_updates_installed_successfully_title">Installed successfully</string>
|
||||
<string name="app_check_for_updates_installed_successfully_desc">Please restart the app.</string>
|
||||
<string name="app_check_for_updates_canceled">Update download canceled</string>
|
||||
<string name="app_check_for_updates_button_remind_later">Remind later</string>
|
||||
<string name="app_check_for_updates_notice_title">Check for updates</string>
|
||||
<string name="app_check_for_updates_notice_desc">To be notified about the new releases, turn on periodic check for Stable or Beta versions.</string>
|
||||
<string name="app_check_for_updates_notice_disable">Disable</string>
|
||||
|
||||
<string name="show_dev_options">Show:</string>
|
||||
<string name="hide_dev_options">Hide:</string>
|
||||
<string name="show_developer_options">Show developer options</string>
|
||||
@@ -2187,4 +2214,13 @@
|
||||
<string name="download_errors">Download errors</string>
|
||||
<string name="server_address">Server address</string>
|
||||
<string name="open_server_settings_button">Open server settings</string>
|
||||
|
||||
<!-- ContactsView.kt -->
|
||||
<string name="contact_type_new">New</string>
|
||||
<string name="contact_type_deleted">Deleted contacts</string>
|
||||
<string name="chat_deleted">Deleted chats</string>
|
||||
<string name="contact_type_recent">Recent</string>
|
||||
<string name="no_filtered_contacts">No filtered contacts</string>
|
||||
<string name="contact_list_header_title">Your contacts</string>
|
||||
<string name="icon_descr_pending_contact_connection">Pending contact connection</string>
|
||||
</resources>
|
||||
@@ -4,7 +4,7 @@
|
||||
<string name="contact_wants_to_connect_via_call">%1$s иска да се свърже с вас чрез</string>
|
||||
<string name="send_disappearing_message_1_minute">1 минута</string>
|
||||
<string name="v4_3_improved_server_configuration_desc">Добави сървъри чрез сканиране на QR кодове.</string>
|
||||
<string name="smp_servers_add">Добави сървър…</string>
|
||||
<string name="smp_servers_add">Добави сървър</string>
|
||||
<string name="group_member_role_admin">админ</string>
|
||||
<string name="button_add_welcome_message">Добави съобщение при посрещане</string>
|
||||
<string name="v5_1_self_destruct_passcode_descr">Всички данни се изтриват при въвеждане.</string>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<string name="color_secondary_variant">আনুষঙ্গিক রং</string>
|
||||
<string name="v4_2_group_links_desc">অ্যাডমিনরা গ্রুপে যোগদানের সংযোগ-সূত্র তৈরি করতে পারবেন।</string>
|
||||
<string name="v4_3_improved_server_configuration_desc">QR কোড স্ক্যান করে সার্ভার যুক্ত করুন।</string>
|
||||
<string name="smp_servers_add">সার্ভার যুক্ত করুন…</string>
|
||||
<string name="smp_servers_add">সার্ভার যুক্ত করুন</string>
|
||||
<string name="address_section_title">ঠিকানা</string>
|
||||
<string name="abort_switch_receiving_address_desc">ঠিকানা পরিবর্তন বাতিল করা হবে। বার্তা গ্রহণের পুরনো ঠিকানা ব্যবহার করা হবে।</string>
|
||||
<string name="all_app_data_will_be_cleared">অ্যাপের সকল তথ্য মুছে ফেলা হয়েছে।</string>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<string name="smp_servers_preset_add">Přidat přednastavené servery</string>
|
||||
<string name="network_settings">Pokročilá nastavení sítě</string>
|
||||
<string name="accept">Přijmout</string>
|
||||
<string name="smp_servers_add">Přidat server…</string>
|
||||
<string name="smp_servers_add">Přidat server</string>
|
||||
<string name="network_enable_socks_info">Přistupovat k serverům přes SOCKS proxy na portu %d\? Před povolením této možnosti musí být spuštěna proxy.</string>
|
||||
<string name="accept_feature">Přijmout</string>
|
||||
<string name="allow_your_contacts_to_send_disappearing_messages">Povolit svým kontaktům odesílat mizící zprávy.</string>
|
||||
@@ -1771,4 +1771,87 @@
|
||||
<string name="e2ee_info_no_pq"><![CDATA[Zprávy, soubory a hovory jsou chráněny <b>koncovým</b> šifrováním s dokonalým dopředným utajením, odmítnutím a obnovením po vloupání.]]></string>
|
||||
<string name="wallpaper_advanced_settings">Pokročilé nastavení</string>
|
||||
<string name="chat_theme_apply_to_all_modes">Všechny barevné režimy</string>
|
||||
<string name="snd_error_quota">Překročená kapacita - příjemci neobdrží dříve poslané zprávy.</string>
|
||||
<string name="network_smp_proxy_mode_always">Vždy</string>
|
||||
<string name="chat_theme_apply_to_mode">Použít na</string>
|
||||
<string name="v5_8_safe_files_descr">Potvrdit soubory z neznámých serverů.</string>
|
||||
<string name="chat_theme_apply_to_dark_mode">Tmavý mód</string>
|
||||
<string name="theme_destination_app_theme">Téma aplikace</string>
|
||||
<string name="network_smp_proxy_mode_always_description">Vždy užít soukromé směrování.</string>
|
||||
<string name="network_smp_proxy_fallback_allow_downgrade">Povolit downgrade</string>
|
||||
<string name="copy_error">Kopírovat chybu</string>
|
||||
<string name="settings_section_title_chat_colors">Barvy chatu</string>
|
||||
<string name="settings_section_title_chat_theme">Téma chatu</string>
|
||||
<string name="color_primary_variant2">Další zbarvení 2</string>
|
||||
<string name="theme_black">Černé</string>
|
||||
<string name="color_mode">Mód barvy</string>
|
||||
<string name="color_mode_dark">Tmavé</string>
|
||||
<string name="dark_mode_colors">Mód tmavých barev</string>
|
||||
<string name="message_queue_info">Informace o frontě zpráv</string>
|
||||
<string name="chat_theme_apply_to_light_mode">Světlý mód</string>
|
||||
<string name="v5_8_chat_themes_descr">Upravtesi svůj chat, aby vypadal jinak!</string>
|
||||
<string name="snd_error_relay">Chyba cílového serveru: %1$s</string>
|
||||
<string name="ci_status_other_error">Chyba: %1$s</string>
|
||||
<string name="snd_error_proxy_relay">Předávací server: %1$s
|
||||
\nChyba cílového serveru: %2$s</string>
|
||||
<string name="snd_error_proxy">Předávací server: %1$s
|
||||
\nChyba: %2$s</string>
|
||||
<string name="message_delivery_warning_title">Upozornění doručování zpráv</string>
|
||||
<string name="snd_error_expired">Problémy se sítí - zpráva vypršela po mnoha pokusech o odeslání.</string>
|
||||
<string name="network_smp_proxy_mode_private_routing">Soukromé směrování</string>
|
||||
<string name="file_error_no_file">Soubor nebyl nalezen - s největší pravděpodobností byl soubor odstraněn nebo zrušen.</string>
|
||||
<string name="file_error_relay">Chyba souboru serveru: %1$s</string>
|
||||
<string name="cannot_share_message_alert_title">Nelze odeslat zprávu</string>
|
||||
<string name="file_error">Chyba souboru</string>
|
||||
<string name="network_smp_proxy_mode_never_description">NEpoužívat soukromé směrování.</string>
|
||||
<string name="update_network_smp_proxy_fallback_question">Záložní směrování zpráv</string>
|
||||
<string name="update_network_smp_proxy_mode_question">Režim přeposílání zpráv</string>
|
||||
<string name="network_smp_proxy_mode_never">Nikdy</string>
|
||||
<string name="error_initializing_web_view">Chyba inicializace WebView. Aktualizujte systém na novou verzi. Prosím kontaktujte vývojáře.
|
||||
\nChyba: %s</string>
|
||||
<string name="protect_ip_address">Ochrana IP adresy</string>
|
||||
<string name="info_row_file_status">Status souboru</string>
|
||||
<string name="info_row_message_status">Status zprávy</string>
|
||||
<string name="share_text_file_status">Status souboru: %s</string>
|
||||
<string name="share_text_message_status">Stav zprávy: %s</string>
|
||||
<string name="message_queue_info_none">žádné</string>
|
||||
<string name="wallpaper_scale_fill">Vyplnit</string>
|
||||
<string name="wallpaper_scale_repeat">Opakovat</string>
|
||||
<string name="chat_theme_reset_to_user_theme">Obnovit uživatelské téma</string>
|
||||
<string name="chat_theme_reset_to_app_theme">Obnovit téma aplikace</string>
|
||||
<string name="v5_8_safe_files">Bezpečné přijímání souborů</string>
|
||||
<string name="v5_8_chat_themes">Nové motivy chatu</string>
|
||||
<string name="v5_8_private_routing">Soukromé směrování zpráv 🚀</string>
|
||||
<string name="v5_8_private_routing_descr">Chraňte vaši IP adresu před relé zpráv, které jste si vybrali.
|
||||
\nPovolit v nastavení *Síť & servery*.</string>
|
||||
<string name="v5_8_message_delivery">Vylepšené doručování zpráv</string>
|
||||
<string name="v5_8_persian_ui">Perské UI</string>
|
||||
<string name="remote_ctrl_connection_stopped_desc">Prosím zkontrolujte, že mobil a desktop jsou připojeny ke stejné místní síti, a že stolní firewall umožňuje připojení.
|
||||
\nProsím sdělte jakékoli další problémy vývojářům.</string>
|
||||
<string name="network_smp_proxy_fallback_prohibit">Ne</string>
|
||||
<string name="network_smp_proxy_fallback_prohibit_description">NEposílejte zprávy přímo, i když váš nebo cílový server nepodporuje soukromé směrování.</string>
|
||||
<string name="settings_section_title_files">SOUBORY</string>
|
||||
<string name="settings_section_title_private_message_routing">SOUKROMÉ SMĚROVÁNÍ ZPRÁV</string>
|
||||
<string name="settings_section_title_user_theme">Téma profilu</string>
|
||||
<string name="color_received_quote">Přijata odpověď</string>
|
||||
<string name="reset_single_color">Obnovit barvu</string>
|
||||
<string name="wallpaper_preview_hello_alice">Dobré odpoledne!</string>
|
||||
<string name="theme_remove_image">Odebrat obrázek</string>
|
||||
<string name="wallpaper_preview_hello_bob">Dobré ráno!</string>
|
||||
<string name="color_mode_light">Světlé</string>
|
||||
<string name="snd_error_auth">Špatný klíč nebo neznámé spojení - pravděpodobně je spojení smazáno.</string>
|
||||
<string name="file_error_auth">Špatný klíč nebo neznámá adresa části souboru - soubor je pravděpodobně odstraněn.</string>
|
||||
<string name="network_smp_proxy_mode_unprotected">Nechráněno</string>
|
||||
<string name="network_smp_proxy_mode_unknown_description">Použít soukromé směrování s neznámými servery.</string>
|
||||
<string name="network_smp_proxy_mode_unprotected_description">Použit soukromé směrování s neznámými servery, když IP adresa není chráněna.</string>
|
||||
<string name="without_tor_or_vpn_ip_address_will_be_visible_to_file_servers">Bez Tor nebo VPN bude vaše IP adresa viditelná souborovým serverům.</string>
|
||||
<string name="info_row_debug_delivery">Ladit doručování</string>
|
||||
<string name="v5_8_message_delivery_descr">Snížena spotřeba baterie.</string>
|
||||
<string name="file_not_approved_title">Neznámé servery!</string>
|
||||
<string name="file_not_approved_descr">Bez Tor nebo VPN bude vaše IP adresa viditelná pro tyto XFTP relé:
|
||||
\n%1$s.</string>
|
||||
<string name="network_smp_proxy_fallback_allow_protected">Když je IP adresa skryta</string>
|
||||
<string name="network_smp_proxy_fallback_allow">Ano</string>
|
||||
<string name="color_wallpaper_tint">Zbarvení tapety</string>
|
||||
<string name="color_wallpaper_background">Pozadí tapety</string>
|
||||
</resources>
|
||||
@@ -355,7 +355,7 @@
|
||||
<string name="smp_servers">SMP-Server</string>
|
||||
<string name="smp_servers_preset_address">Voreingestellte Serveradresse</string>
|
||||
<string name="smp_servers_preset_add">Füge voreingestellte Server hinzu</string>
|
||||
<string name="smp_servers_add">Füge Server hinzu…</string>
|
||||
<string name="smp_servers_add">Füge Server hinzu</string>
|
||||
<string name="smp_servers_test_server">Teste Server</string>
|
||||
<string name="smp_servers_test_servers">Teste alle Server</string>
|
||||
<string name="smp_servers_save">Alle Server speichern</string>
|
||||
@@ -1807,7 +1807,7 @@
|
||||
<string name="forwarded_description">weitergeleitet</string>
|
||||
<string name="settings_section_title_network_connection">Netzwerkverbindung</string>
|
||||
<string name="network_type_no_network_connection">Keine Netzwerkverbindung</string>
|
||||
<string name="network_type_cellular">Zellulär</string>
|
||||
<string name="network_type_cellular">Mobilfunknetz</string>
|
||||
<string name="network_type_other">Andere</string>
|
||||
<string name="network_type_network_wifi">WiFi</string>
|
||||
<string name="network_type_ethernet">Kabelgebundenes Netzwerk</string>
|
||||
@@ -1939,4 +1939,19 @@
|
||||
<string name="message_queue_info_server_info">Server-Warteschlangen-Information: %1$s
|
||||
\n
|
||||
\nZuletzt empfangene Nachricht: %2$s</string>
|
||||
<string name="file_error_no_file">Datei nicht gefunden - höchstwahrscheinlich wurde die Datei gelöscht oder der Transfer abgebrochen.</string>
|
||||
<string name="file_error_relay">Datei-Server-Fehler: %1$s</string>
|
||||
<string name="file_error_auth">Falscher Schlüssel oder unbekannte Datei-Chunk-Adresse - höchstwahrscheinlich wurde die Datei gelöscht.</string>
|
||||
<string name="file_error">Datei-Fehler</string>
|
||||
<string name="info_row_message_status">Nachrichten-Status</string>
|
||||
<string name="share_text_message_status">Nachrichten-Status: %s</string>
|
||||
<string name="info_row_file_status">Datei-Status</string>
|
||||
<string name="share_text_file_status">Datei-Status: %s</string>
|
||||
<string name="temporary_file_error">Temporärer Datei-Fehler</string>
|
||||
<string name="copy_error">Fehlermeldung kopieren</string>
|
||||
<string name="remote_ctrl_connection_stopped_identity_desc">Dieser Link wurde schon mit einem anderen Mobiltelefon genutzt. Bitte erstellen sie einen neuen Link in der Desktop-App.</string>
|
||||
<string name="remote_ctrl_connection_stopped_desc">Bitte überprüfen Sie, ob sich das Mobiltelefon und die Desktop-App im gleichen lokalen Netzwerk befinden, und die Desktop-Firewall die Verbindung erlaubt.
|
||||
\nBitte teilen Sie weitere mögliche Probleme den Entwicklern mit.</string>
|
||||
<string name="cannot_share_message_alert_title">Nachricht wurde nicht gesendet</string>
|
||||
<string name="cannot_share_message_alert_text">Diese Nachricht ist wegen der gewählten Chat-Einstellungen nicht erlaubt.</string>
|
||||
</resources>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user