Merge branch 'master' into lp/time-grouped-messages

This commit is contained in:
Levitating Pineapple
2024-08-23 19:07:05 +03:00
67 changed files with 4036 additions and 732 deletions
+50 -33
View File
@@ -357,17 +357,17 @@ func apiGetChatItemInfo(type: ChatType, id: Int64, itemId: Int64) async throws -
throw r
}
func apiForwardChatItem(toChatType: ChatType, toChatId: Int64, fromChatType: ChatType, fromChatId: Int64, itemId: Int64, ttl: Int?) async -> ChatItem? {
let cmd: ChatCommand = .apiForwardChatItem(toChatType: toChatType, toChatId: toChatId, fromChatType: fromChatType, fromChatId: fromChatId, itemId: itemId, ttl: ttl)
func apiForwardChatItems(toChatType: ChatType, toChatId: Int64, fromChatType: ChatType, fromChatId: Int64, itemIds: [Int64], ttl: Int?) async -> [ChatItem]? {
let cmd: ChatCommand = .apiForwardChatItems(toChatType: toChatType, toChatId: toChatId, fromChatType: fromChatType, fromChatId: fromChatId, itemIds: itemIds, ttl: ttl)
return await processSendMessageCmd(toChatType: toChatType, cmd: cmd)
}
func apiSendMessage(type: ChatType, id: Int64, file: CryptoFile?, quotedItemId: Int64?, msg: MsgContent, live: Bool = false, ttl: Int? = nil) async -> ChatItem? {
let cmd: ChatCommand = .apiSendMessage(type: type, id: id, file: file, quotedItemId: quotedItemId, msg: msg, live: live, ttl: ttl)
func apiSendMessages(type: ChatType, id: Int64, live: Bool = false, ttl: Int? = nil, composedMessages: [ComposedMessage]) async -> [ChatItem]? {
let cmd: ChatCommand = .apiSendMessages(type: type, id: id, live: live, ttl: ttl, composedMessages: composedMessages)
return await processSendMessageCmd(toChatType: type, cmd: cmd)
}
private func processSendMessageCmd(toChatType: ChatType, cmd: ChatCommand) async -> ChatItem? {
private func processSendMessageCmd(toChatType: ChatType, cmd: ChatCommand) async -> [ChatItem]? {
let chatModel = ChatModel.shared
let r: ChatResponse
if toChatType == .direct {
@@ -380,10 +380,13 @@ private func processSendMessageCmd(toChatType: ChatType, cmd: ChatCommand) async
}
})
r = await chatSendCmd(cmd, bgTask: false)
if case let .newChatItem(_, aChatItem) = r {
cItem = aChatItem.chatItem
chatModel.messageDelivery[aChatItem.chatItem.id] = endTask
return cItem
if case let .newChatItems(_, aChatItems) = r {
let cItems = aChatItems.map { $0.chatItem }
if let cItemLast = cItems.last {
cItem = cItemLast
chatModel.messageDelivery[cItemLast.id] = endTask
}
return cItems
}
if let networkErrorAlert = networkErrorAlert(r) {
AlertManager.shared.showAlert(networkErrorAlert)
@@ -394,18 +397,18 @@ private func processSendMessageCmd(toChatType: ChatType, cmd: ChatCommand) async
return nil
} else {
r = await chatSendCmd(cmd, bgDelay: msgDelay)
if case let .newChatItem(_, aChatItem) = r {
return aChatItem.chatItem
if case let .newChatItems(_, aChatItems) = r {
return aChatItems.map { $0.chatItem }
}
sendMessageErrorAlert(r)
return nil
}
}
func apiCreateChatItem(noteFolderId: Int64, file: CryptoFile?, msg: MsgContent) async -> ChatItem? {
let r = await chatSendCmd(.apiCreateChatItem(noteFolderId: noteFolderId, file: file, msg: msg))
if case let .newChatItem(_, aChatItem) = r { return aChatItem.chatItem }
createChatItemErrorAlert(r)
func apiCreateChatItems(noteFolderId: Int64, composedMessages: [ComposedMessage]) async -> [ChatItem]? {
let r = await chatSendCmd(.apiCreateChatItems(noteFolderId: noteFolderId, composedMessages: composedMessages))
if case let .newChatItems(_, aChatItems) = r { return aChatItems.map { $0.chatItem } }
createChatItemsErrorAlert(r)
return nil
}
@@ -417,8 +420,8 @@ private func sendMessageErrorAlert(_ r: ChatResponse) {
)
}
private func createChatItemErrorAlert(_ r: ChatResponse) {
logger.error("apiCreateChatItem error: \(String(describing: r))")
private func createChatItemsErrorAlert(_ r: ChatResponse) {
logger.error("apiCreateChatItems error: \(String(describing: r))")
AlertManager.shared.showAlertMsg(
title: "Error creating message",
message: "Error: \(responseError(r))"
@@ -673,6 +676,13 @@ func apiSetConnectionIncognito(connId: Int64, incognito: Bool) async throws -> P
throw r
}
func apiChangeConnectionUser(connId: Int64, userId: Int64) async throws -> PendingContactConnection? {
let r = await chatSendCmd(.apiChangeConnectionUser(connId: connId, userId: userId))
if case let .connectionUserChanged(_, _, toConnection, _) = r {return toConnection}
throw r
}
func apiConnectPlan(connReq: String) async throws -> ConnectionPlan {
let userId = try currentUserId("apiConnectPlan")
let r = await chatSendCmd(.apiConnectPlan(userId: userId, connReq: connReq))
@@ -1775,23 +1785,25 @@ func processReceivedMsg(_ res: ChatResponse) async {
n.networkStatuses = ns
}
}
case let .newChatItem(user, aChatItem):
let cInfo = aChatItem.chatInfo
let cItem = aChatItem.chatItem
await MainActor.run {
if active(user) {
m.addChatItem(cInfo, cItem)
} else if cItem.isRcvNew && cInfo.ntfsEnabled {
m.increaseUnreadCounter(user: user)
case let .newChatItems(user, chatItems):
for chatItem in chatItems {
let cInfo = chatItem.chatInfo
let cItem = chatItem.chatItem
await MainActor.run {
if active(user) {
m.addChatItem(cInfo, cItem)
} else if cItem.isRcvNew && cInfo.ntfsEnabled {
m.increaseUnreadCounter(user: user)
}
}
}
if let file = cItem.autoReceiveFile() {
Task {
await receiveFile(user: user, fileId: file.fileId, auto: true)
if let file = cItem.autoReceiveFile() {
Task {
await receiveFile(user: user, fileId: file.fileId, auto: true)
}
}
if cItem.showNotification {
NtfManager.shared.notifyMessageReceived(user, cInfo, cItem)
}
}
if cItem.showNotification {
NtfManager.shared.notifyMessageReceived(user, cInfo, cItem)
}
case let .chatItemStatusUpdated(user, aChatItem):
let cInfo = aChatItem.chatInfo
@@ -1801,10 +1813,15 @@ func processReceivedMsg(_ res: ChatResponse) async {
}
if let endTask = m.messageDelivery[cItem.id] {
switch cItem.meta.itemStatus {
case .sndNew: ()
case .sndSent: endTask()
case .sndRcvd: endTask()
case .sndErrorAuth: endTask()
case .sndError: endTask()
default: ()
case .sndWarning: endTask()
case .rcvNew: ()
case .rcvRead: ()
case .invalid: ()
}
}
case let .chatItemUpdated(user, aChatItem):
@@ -751,6 +751,7 @@ struct ComposeView: View {
case .linkPreview:
sent = await send(checkLinkPreview(), quoted: quoted, live: live, ttl: ttl)
case let .mediaPreviews(mediaPreviews: media):
// TODO batch send: batch media previews
let last = media.count - 1
if last >= 0 {
for i in 0..<last {
@@ -887,22 +888,26 @@ struct ComposeView: View {
}
func send(_ mc: MsgContent, quoted: Int64?, file: CryptoFile? = nil, live: Bool = false, ttl: Int?) async -> ChatItem? {
if let chatItem = chat.chatInfo.chatType == .local
? await apiCreateChatItem(noteFolderId: chat.chatInfo.apiId, file: file, msg: mc)
: await apiSendMessage(
if let chatItems = chat.chatInfo.chatType == .local
? await apiCreateChatItems(
noteFolderId: chat.chatInfo.apiId,
composedMessages: [ComposedMessage(fileSource: file, msgContent: mc)]
)
: await apiSendMessages(
type: chat.chatInfo.chatType,
id: chat.chatInfo.apiId,
file: file,
quotedItemId: quoted,
msg: mc,
live: live,
ttl: ttl
ttl: ttl,
composedMessages: [ComposedMessage(fileSource: file, quotedItemId: quoted, msgContent: mc)]
) {
await MainActor.run {
chatModel.removeLiveDummy(animated: false)
chatModel.addChatItem(chat.chatInfo, chatItem)
for chatItem in chatItems {
chatModel.addChatItem(chat.chatInfo, chatItem)
}
}
return chatItem
// UI only supports sending one item at a time
return chatItems.first
}
if let file = file {
removeFile(file.filePath)
@@ -911,18 +916,21 @@ struct ComposeView: View {
}
func forwardItem(_ forwardedItem: ChatItem, _ fromChatInfo: ChatInfo, _ ttl: Int?) async -> ChatItem? {
if let chatItem = await apiForwardChatItem(
if let chatItems = await apiForwardChatItems(
toChatType: chat.chatInfo.chatType,
toChatId: chat.chatInfo.apiId,
fromChatType: fromChatInfo.chatType,
fromChatId: fromChatInfo.apiId,
itemId: forwardedItem.id,
itemIds: [forwardedItem.id],
ttl: ttl
) {
await MainActor.run {
chatModel.addChatItem(chat.chatInfo, chatItem)
for chatItem in chatItems {
chatModel.addChatItem(chat.chatInfo, chatItem)
}
}
return chatItem
// TODO batch send: forward multiple messages
return chatItems.first
}
return nil
}
@@ -28,7 +28,9 @@ struct AddContactLearnMore: View {
Text("If you can't meet in person, show QR code in a video call, or share the link.")
Text("Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends).")
}
.frame(maxWidth: .infinity, alignment: .leading)
.listRowBackground(Color.clear)
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
}
.modifier(ThemedBackground(grouped: true))
}
@@ -14,9 +14,10 @@ enum ContactType: Int {
}
struct NewChatMenuButton: View {
@EnvironmentObject var chatModel: ChatModel
@State private var showNewChatSheet = false
@State private var alert: SomeAlert? = nil
@State private var globalAlert: SomeAlert? = nil
@State private var pendingConnection: PendingContactConnection? = nil
var body: some View {
Button {
@@ -28,22 +29,14 @@ struct NewChatMenuButton: View {
.frame(width: 24, height: 24)
}
.appSheet(isPresented: $showNewChatSheet) {
NewChatSheet(alert: $alert)
NewChatSheet(pendingConnection: $pendingConnection)
.environment(\EnvironmentValues.refresh as! WritableKeyPath<EnvironmentValues, RefreshAction?>, nil)
.alert(item: $alert) { a in
return a.alert
.onDisappear {
alert = cleanupPendingConnection(chatModel: chatModel, contactConnection: pendingConnection)
pendingConnection = nil
}
}
// This is a workaround to show "Keep unused invitation" alert in both following cases:
// - on going back from NewChatView to NewChatSheet,
// - on dismissing NewChatMenuButton sheet while on NewChatView (skipping NewChatSheet)
.onChange(of: alert?.id) { a in
if !showNewChatSheet && alert != nil {
globalAlert = alert
alert = nil
}
}
.alert(item: $globalAlert) { a in
.alert(item: $alert) { a in
return a.alert
}
}
@@ -60,7 +53,8 @@ struct NewChatSheet: View {
@State private var searchText = ""
@State private var searchShowingSimplexLink = false
@State private var searchChatFilteredBySimplexLink: String? = nil
@Binding var alert: SomeAlert?
@State private var alert: SomeAlert?
@Binding var pendingConnection: PendingContactConnection?
// Sheet height management
@State private var isAddContactActive = false
@@ -78,6 +72,9 @@ struct NewChatSheet: View {
.navigationBarTitleDisplayMode(.large)
.navigationBarHidden(searchMode)
.modifier(ThemedBackground(grouped: true))
.alert(item: $alert) { a in
return a.alert
}
}
if #available(iOS 16.0, *), oneHandUI {
let sheetHeight: CGFloat = showArchive ? 575 : 500
@@ -112,7 +109,7 @@ struct NewChatSheet: View {
if (searchText.isEmpty) {
Section {
NavigationLink(isActive: $isAddContactActive) {
NewChatView(selection: .invite, parentAlert: $alert)
NewChatView(selection: .invite, parentAlert: $alert, contactConnection: $pendingConnection)
.navigationTitle("New chat")
.modifier(ThemedBackground(grouped: true))
.navigationBarTitleDisplayMode(.large)
@@ -122,7 +119,7 @@ struct NewChatSheet: View {
}
}
NavigationLink(isActive: $isScanPasteLinkActive) {
NewChatView(selection: .connect, showQRCodeScanner: true, parentAlert: $alert)
NewChatView(selection: .connect, showQRCodeScanner: true, parentAlert: $alert, contactConnection: $pendingConnection)
.navigationTitle("New chat")
.modifier(ThemedBackground(grouped: true))
.navigationBarTitleDisplayMode(.large)
+325 -42
View File
@@ -45,18 +45,47 @@ enum NewChatOption: Identifiable {
var id: Self { self }
}
func cleanupPendingConnection(chatModel: ChatModel, contactConnection: PendingContactConnection?) -> SomeAlert? {
var alert: SomeAlert? = nil
if !(chatModel.showingInvitation?.connChatUsed ?? true),
let conn = contactConnection {
alert = SomeAlert(
alert: Alert(
title: Text("Keep unused invitation?"),
message: Text("You can view invitation link again in connection details."),
primaryButton: .default(Text("Keep")) {},
secondaryButton: .destructive(Text("Delete")) {
Task {
await deleteChat(Chat(
chatInfo: .contactConnection(contactConnection: conn),
chatItems: []
))
}
}
),
id: "keepUnusedInvitation"
)
}
chatModel.showingInvitation = nil
return alert
}
struct NewChatView: View {
@EnvironmentObject var m: ChatModel
@EnvironmentObject var theme: AppTheme
@State var selection: NewChatOption
@State var showQRCodeScanner = false
@State private var invitationUsed: Bool = false
@State private var contactConnection: PendingContactConnection? = nil
@State private var connReqInvitation: String = ""
@State private var creatingConnReq = false
@State var choosingProfile = false
@State private var pastedLink: String = ""
@State private var alert: NewChatViewAlert?
@Binding var parentAlert: SomeAlert?
@Binding var contactConnection: PendingContactConnection?
var body: some View {
VStack(alignment: .leading) {
@@ -122,26 +151,10 @@ struct NewChatView: View {
}
}
.onDisappear {
if !(m.showingInvitation?.connChatUsed ?? true),
let conn = contactConnection {
parentAlert = SomeAlert(
alert: Alert(
title: Text("Keep unused invitation?"),
message: Text("You can view invitation link again in connection details."),
primaryButton: .default(Text("Keep")) {},
secondaryButton: .destructive(Text("Delete")) {
Task {
await deleteChat(Chat(
chatInfo: .contactConnection(contactConnection: conn),
chatItems: []
))
}
}
),
id: "keepUnusedInvitation"
)
if !choosingProfile {
parentAlert = cleanupPendingConnection(chatModel: m, contactConnection: contactConnection)
contactConnection = nil
}
m.showingInvitation = nil
}
.alert(item: $alert) { a in
switch(a) {
@@ -159,7 +172,8 @@ struct NewChatView: View {
InviteView(
invitationUsed: $invitationUsed,
contactConnection: $contactConnection,
connReqInvitation: connReqInvitation
connReqInvitation: $connReqInvitation,
choosingProfile: $choosingProfile
)
} else if creatingConnReq {
creatingLinkProgressView()
@@ -210,13 +224,24 @@ struct NewChatView: View {
}
}
private func incognitoProfileImage() -> some View {
Image(systemName: "theatermasks.fill")
.resizable()
.scaledToFit()
.frame(width: 30)
.foregroundColor(.indigo)
}
private struct InviteView: View {
@EnvironmentObject var chatModel: ChatModel
@EnvironmentObject var theme: AppTheme
@Binding var invitationUsed: Bool
@Binding var contactConnection: PendingContactConnection?
var connReqInvitation: String
@Binding var connReqInvitation: String
@Binding var choosingProfile: Bool
@AppStorage(GROUP_DEFAULT_INCOGNITO, store: groupDefaults) private var incognitoDefault = false
@State private var showSettings: Bool = false
var body: some View {
List {
@@ -226,28 +251,40 @@ private struct InviteView: View {
.listRowInsets(EdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 10))
qrCodeView()
Section {
IncognitoToggle(incognitoEnabled: $incognitoDefault)
} footer: {
sharedProfileInfo(incognitoDefault)
.foregroundColor(theme.colors.secondary)
if let selectedProfile = chatModel.currentUser {
Section {
NavigationLink {
ActiveProfilePicker(
contactConnection: $contactConnection,
connReqInvitation: $connReqInvitation,
incognitoEnabled: $incognitoDefault,
choosingProfile: $choosingProfile,
selectedProfile: selectedProfile
)
} label: {
HStack {
if incognitoDefault {
incognitoProfileImage()
Text("Incognito")
} else {
ProfileImage(imageStr: chatModel.currentUser?.image, size: 30)
Text(chatModel.currentUser?.chatViewName ?? "")
}
}
}
} header: {
Text("Share profile").foregroundColor(theme.colors.secondary)
} footer: {
if incognitoDefault {
Text("A new random profile will be shared.")
}
}
}
}
.onChange(of: incognitoDefault) { incognito in
Task {
do {
if let contactConn = contactConnection,
let conn = try await apiSetConnectionIncognito(connId: contactConn.pccConnId, incognito: incognito) {
await MainActor.run {
contactConnection = conn
chatModel.updateContactConnection(conn)
}
}
} catch {
logger.error("apiSetConnectionIncognito error: \(responseError(error))")
}
}
setInvitationUsed()
}
.onChange(of: chatModel.currentUser) { u in
setInvitationUsed()
}
}
@@ -270,6 +307,7 @@ private struct InviteView: View {
private func qrCodeView() -> some View {
Section(header: Text("Or show this code").foregroundColor(theme.colors.secondary)) {
SimpleXLinkQRCode(uri: connReqInvitation, onShare: setInvitationUsed)
.id("simplex-qrcode-view-for-\(connReqInvitation)")
.padding()
.background(
RoundedRectangle(cornerRadius: 12, style: .continuous)
@@ -289,6 +327,249 @@ private struct InviteView: View {
}
}
private struct ActiveProfilePicker: View {
@Environment(\.dismiss) var dismiss
@EnvironmentObject var chatModel: ChatModel
@EnvironmentObject var theme: AppTheme
@Binding var contactConnection: PendingContactConnection?
@Binding var connReqInvitation: String
@Binding var incognitoEnabled: Bool
@Binding var choosingProfile: Bool
@State private var alert: SomeAlert?
@State private var switchingProfile = false
@State private var switchingProfileByTimeout = false
@State private var lastSwitchingProfileByTimeoutCall: Double?
@State private var profiles: [User] = []
@State private var searchTextOrPassword = ""
@State private var showIncognitoSheet = false
@State private var incognitoFirst: Bool = false
@State var selectedProfile: User
var trimmedSearchTextOrPassword: String { searchTextOrPassword.trimmingCharacters(in: .whitespaces)}
var body: some View {
viewBody()
.navigationTitle("Select chat profile")
.searchable(text: $searchTextOrPassword, placement: .navigationBarDrawer(displayMode: .always))
.autocorrectionDisabled(true)
.navigationBarTitleDisplayMode(.large)
.onAppear {
profiles = chatModel.users
.map { $0.user }
.sorted { u, _ in u.activeUser }
}
.onChange(of: incognitoEnabled) { incognito in
if !switchingProfile {
return
}
Task {
do {
if let contactConn = contactConnection,
let conn = try await apiSetConnectionIncognito(connId: contactConn.pccConnId, incognito: incognito) {
await MainActor.run {
contactConnection = conn
chatModel.updateContactConnection(conn)
switchingProfile = false
dismiss()
}
}
} catch {
switchingProfile = false
incognitoEnabled = !incognito
logger.error("apiSetConnectionIncognito error: \(responseError(error))")
let err = getErrorAlert(error, "Error changing to incognito!")
alert = SomeAlert(
alert: Alert(
title: Text(err.title),
message: Text(err.message ?? "Error: \(responseError(error))")
),
id: "setConnectionIncognitoError"
)
}
}
}
.onChange(of: switchingProfile) { sp in
if sp {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
switchingProfileByTimeout = switchingProfile
}
} else {
switchingProfileByTimeout = false
}
}
.onChange(of: selectedProfile) { profile in
if (profile == chatModel.currentUser) {
return
}
Task {
do {
switchingProfile = true
if let contactConn = contactConnection,
let conn = try await apiChangeConnectionUser(connId: contactConn.pccConnId, userId: profile.userId) {
await MainActor.run {
contactConnection = conn
connReqInvitation = conn.connReqInv ?? ""
chatModel.updateContactConnection(conn)
}
do {
try await changeActiveUserAsync_(profile.userId, viewPwd: profile.hidden ? trimmedSearchTextOrPassword : nil )
await MainActor.run {
switchingProfile = false
dismiss()
}
} catch {
await MainActor.run {
switchingProfile = false
alert = SomeAlert(
alert: Alert(
title: Text("Error switching profile"),
message: Text("Your connection was moved to \(profile.chatViewName) but an unexpected error occurred while redirecting you to the profile.")
),
id: "switchingProfileError"
)
}
}
}
} catch {
await MainActor.run {
switchingProfile = false
if let currentUser = chatModel.currentUser {
selectedProfile = currentUser
}
let err = getErrorAlert(error, "Error changing connection profile")
alert = SomeAlert(
alert: Alert(
title: Text(err.title),
message: Text(err.message ?? "Error: \(responseError(error))")
),
id: "changeConnectionUserError"
)
}
}
}
}
.alert(item: $alert) { a in
a.alert
}
.onAppear {
incognitoFirst = incognitoEnabled
choosingProfile = true
}
.onDisappear {
choosingProfile = false
}
.sheet(isPresented: $showIncognitoSheet) {
IncognitoHelp()
}
}
@ViewBuilder private func viewBody() -> some View {
profilePicker()
.allowsHitTesting(!switchingProfileByTimeout)
.modifier(ThemedBackground(grouped: true))
.overlay {
if switchingProfileByTimeout {
ProgressView()
.scaleEffect(2)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
private func filteredProfiles() -> [User] {
let s = trimmedSearchTextOrPassword
let lower = s.localizedLowercase
return profiles.filter { u in
if (u.activeUser || !u.hidden) && (s == "" || u.chatViewName.localizedLowercase.contains(lower)) {
return true
}
return correctPassword(u, s)
}
}
@ViewBuilder private func profilerPickerUserOption(_ user: User) -> some View {
Button {
if selectedProfile != user || incognitoEnabled {
switchingProfile = true
incognitoEnabled = false
selectedProfile = user
}
} label: {
HStack {
ProfileImage(imageStr: user.image, size: 30)
.padding(.trailing, 2)
Text(user.chatViewName)
.foregroundColor(theme.colors.onBackground)
.lineLimit(1)
Spacer()
if selectedProfile == user, !incognitoEnabled {
Image(systemName: "checkmark")
.resizable().scaledToFit().frame(width: 16)
.foregroundColor(theme.colors.primary)
}
}
}
}
@ViewBuilder private func profilePicker() -> some View {
let incognitoOption = Button {
if !incognitoEnabled {
incognitoEnabled = true
switchingProfile = true
}
} label : {
HStack {
incognitoProfileImage()
Text("Incognito")
.foregroundColor(theme.colors.onBackground)
Image(systemName: "info.circle")
.foregroundColor(theme.colors.primary)
.font(.system(size: 14))
.onTapGesture {
showIncognitoSheet = true
}
Spacer()
if incognitoEnabled {
Image(systemName: "checkmark")
.resizable().scaledToFit().frame(width: 16)
.foregroundColor(theme.colors.primary)
}
}
}
List {
let filteredProfiles = filteredProfiles()
let activeProfile = filteredProfiles.first { u in u.activeUser }
if let selectedProfile = activeProfile {
let otherProfiles = filteredProfiles.filter { u in u.userId != activeProfile?.userId }
if incognitoFirst {
incognitoOption
profilerPickerUserOption(selectedProfile)
} else {
profilerPickerUserOption(selectedProfile)
incognitoOption
}
ForEach(otherProfiles) { p in
profilerPickerUserOption(p)
}
} else {
incognitoOption
ForEach(filteredProfiles) { p in
profilerPickerUserOption(p)
}
}
}
.opacity(switchingProfileByTimeout ? 0.4 : 1)
}
}
private struct ConnectView: View {
@Environment(\.dismiss) var dismiss: DismissAction
@EnvironmentObject var theme: AppTheme
@@ -975,10 +1256,12 @@ func connReqSentAlert(_ type: ConnReqType) -> Alert {
struct NewChatView_Previews: PreviewProvider {
static var previews: some View {
@State var parentAlert: SomeAlert?
@State var contactConnection: PendingContactConnection? = nil
NewChatView(
selection: .invite,
parentAlert: $parentAlert
parentAlert: $parentAlert,
contactConnection: $contactConnection
)
}
}
+1 -1
View File
@@ -160,7 +160,7 @@ struct TerminalView_Previews: PreviewProvider {
let chatModel = ChatModel()
chatModel.terminalItems = [
.resp(.now, ChatResponse.response(type: "contactSubscribed", json: "{}")),
.resp(.now, ChatResponse.response(type: "newChatItem", json: "{}"))
.resp(.now, ChatResponse.response(type: "newChatItems", json: "{}"))
]
return NavigationView {
TerminalView()
@@ -26,6 +26,7 @@ struct IncognitoHelp: View {
Text("Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode).")
}
.listRowBackground(Color.clear)
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
}
.modifier(ThemedBackground())
}
@@ -406,6 +406,13 @@ public func chatPasswordHash(_ pwd: String, _ salt: String) -> String {
return hash
}
public func correctPassword(_ user: User, _ pwd: String) -> Bool {
if let ph = user.viewPwdHash {
return pwd != "" && chatPasswordHash(pwd, ph.salt) == ph.hash
}
return false
}
struct UserProfilesView_Previews: PreviewProvider {
static var previews: some View {
UserProfilesView(showSettings: Binding.constant(true))
@@ -802,7 +802,7 @@
</trans-unit>
<trans-unit id="Allow to send SimpleX links." xml:space="preserve">
<source>Allow to send SimpleX links.</source>
<target>Permitir enviar enlaces SimpleX.</target>
<target>Se permite enviar enlaces SimpleX.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Allow to send files and media." xml:space="preserve">
@@ -2406,7 +2406,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Do not send history to new members." xml:space="preserve">
<source>Do not send history to new members.</source>
<target>No enviar historial a miembros nuevos.</target>
<target>No se envía el historial a los miembros nuevos.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
@@ -5068,7 +5068,7 @@ Error: %@</target>
</trans-unit>
<trans-unit id="Prohibit sending SimpleX links." xml:space="preserve">
<source>Prohibit sending SimpleX links.</source>
<target>No permitir el envío de enlaces SimpleX.</target>
<target>No se permite enviar enlaces SimpleX.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Prohibit sending direct messages to members." xml:space="preserve">
@@ -5841,7 +5841,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
</trans-unit>
<trans-unit id="Send up to 100 last messages to new members." xml:space="preserve">
<source>Send up to 100 last messages to new members.</source>
<target>Enviar hasta 100 últimos mensajes a los miembros nuevos.</target>
<target>Se envían hasta 100 mensajes más recientes a los miembros nuevos.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
@@ -7449,7 +7449,7 @@ Repeat join request?</source>
</trans-unit>
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
<source>You can change it in Appearance settings.</source>
<target>Puede cambiarlo desde el menú Apariencia.</target>
<target>Puedes cambiar la posición de la barra desde el menú Apariencia.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can create it later" xml:space="preserve">
@@ -1042,7 +1042,7 @@
</trans-unit>
<trans-unit id="Bad message hash" xml:space="preserve">
<source>Bad message hash</source>
<target>Téves üzenet hash</target>
<target>Hibás az üzenet ellenőrzőösszege</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
@@ -2131,7 +2131,7 @@ Ez az egyszer használatos hivatkozása!</target>
</trans-unit>
<trans-unit id="Delete member message?" xml:space="preserve">
<source>Delete member message?</source>
<target>Csoporttag üzenet törlése?</target>
<target>Csoporttag üzenetének törlése?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete message?" xml:space="preserve">
@@ -2221,7 +2221,7 @@ Ez az egyszer használatos hivatkozása!</target>
</trans-unit>
<trans-unit id="Delivery receipts!" xml:space="preserve">
<source>Delivery receipts!</source>
<target>Kézbesítési igazolások!</target>
<target>Üzenet kézbesítési jelentések!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Description" xml:space="preserve">
@@ -2681,12 +2681,12 @@ Ez az egyszer használatos hivatkozása!</target>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Üdvözlő üzenetet megadása…</target>
<target>Üdvözlő üzenet megadása…</target>
<note>placeholder</note>
</trans-unit>
<trans-unit id="Enter welcome message… (optional)" xml:space="preserve">
<source>Enter welcome message… (optional)</source>
<target>Üdvözlő üzenetet megadása… (opcionális)</target>
<target>Üdvözlő üzenet megadása… (opcionális)</target>
<note>placeholder</note>
</trans-unit>
<trans-unit id="Enter your name…" xml:space="preserve">
@@ -4131,7 +4131,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
</trans-unit>
<trans-unit id="Message delivery receipts!" xml:space="preserve">
<source>Message delivery receipts!</source>
<target>Üzenetkézbesítési bizonylatok!</target>
<target>Üzenet kézbesítési jelentések!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Message delivery warning" xml:space="preserve">
@@ -4176,7 +4176,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
</trans-unit>
<trans-unit id="Message reception" xml:space="preserve">
<source>Message reception</source>
<target>Üzenetjelentés</target>
<target>Üzenet kézbesítési jelentés</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Message servers" xml:space="preserve">
@@ -6573,7 +6573,7 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.</target>
</trans-unit>
<trans-unit id="The hash of the previous message is different." xml:space="preserve">
<source>The hash of the previous message is different.</source>
<target>Az előző üzenet hash-e más.</target>
<target>Az előző üzenet ellenőrzőösszege különbözik.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The message will be deleted for all members." xml:space="preserve">
@@ -7888,7 +7888,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
</trans-unit>
<trans-unit id="bad message hash" xml:space="preserve">
<source>bad message hash</source>
<target>téves üzenet hash</target>
<target>hibás az üzenet ellenőrzőösszege</target>
<note>integrity error chat item</note>
</trans-unit>
<trans-unit id="blocked" xml:space="preserve">
@@ -8490,7 +8490,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
</trans-unit>
<trans-unit id="removed %@" xml:space="preserve">
<source>removed %@</source>
<target>%@ eltávolítva</target>
<target>eltávolította őt: %@</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="removed contact address" xml:space="preserve">
@@ -1617,7 +1617,7 @@ Questo è il tuo link una tantum!</target>
</trans-unit>
<trans-unit id="Connection and servers status." xml:space="preserve">
<source>Connection and servers status.</source>
<target>Stato di connessione e server.</target>
<target>Stato della connessione e dei server.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection error" xml:space="preserve">
@@ -3906,7 +3906,7 @@ Dit is jouw link voor groep %@!</target>
</trans-unit>
<trans-unit id="Keep conversation" xml:space="preserve">
<source>Keep conversation</source>
<target>Blijf in gesprek</target>
<target>Behoud het gesprek</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
@@ -752,6 +752,7 @@
</trans-unit>
<trans-unit id="Allow calls?" xml:space="preserve">
<source>Allow calls?</source>
<target>Zezwolić na połączenia?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Allow disappearing messages only if your contact allows it to you." xml:space="preserve">
@@ -791,6 +792,7 @@
</trans-unit>
<trans-unit id="Allow sharing" xml:space="preserve">
<source>Allow sharing</source>
<target>Zezwól na udostępnianie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Allow to irreversibly delete sent messages. (24 hours)" xml:space="preserve">
@@ -945,10 +947,12 @@
</trans-unit>
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
<source>Archive contacts to chat later.</source>
<target>Archiwizuj kontakty aby porozmawiać później.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Archived contacts" xml:space="preserve">
<source>Archived contacts</source>
<target>Zarchiwizowane kontakty</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Archiving database" xml:space="preserve">
@@ -1053,6 +1057,7 @@
</trans-unit>
<trans-unit id="Better networking" xml:space="preserve">
<source>Better networking</source>
<target>Lepsze sieciowanie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Black" xml:space="preserve">
@@ -1097,10 +1102,12 @@
</trans-unit>
<trans-unit id="Blur for better privacy." xml:space="preserve">
<source>Blur for better privacy.</source>
<target>Rozmycie dla lepszej prywatności.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Blur media" xml:space="preserve">
<source>Blur media</source>
<target>Rozmycie mediów</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Both you and your contact can add message reactions." xml:space="preserve">
@@ -1150,6 +1157,7 @@
</trans-unit>
<trans-unit id="Calls prohibited!" xml:space="preserve">
<source>Calls prohibited!</source>
<target>Połączenia zakazane!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Camera not available" xml:space="preserve">
@@ -1159,10 +1167,12 @@
</trans-unit>
<trans-unit id="Can't call contact" xml:space="preserve">
<source>Can't call contact</source>
<target>Nie można zadzwonić do kontaktu</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Can't call member" xml:space="preserve">
<source>Can't call member</source>
<target>Nie można zadzwonić do członka</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Can't invite contact!" xml:space="preserve">
@@ -1177,6 +1187,7 @@
</trans-unit>
<trans-unit id="Can't message member" xml:space="preserve">
<source>Can't message member</source>
<target>Nie można wysłać wiadomości do członka</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Cancel" xml:space="preserve">
@@ -1292,6 +1303,7 @@
</trans-unit>
<trans-unit id="Chat database exported" xml:space="preserve">
<source>Chat database exported</source>
<target>Wyeksportowano bazę danych czatu</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Chat database imported" xml:space="preserve">
@@ -1316,6 +1328,7 @@
</trans-unit>
<trans-unit id="Chat list" xml:space="preserve">
<source>Chat list</source>
<target>Lista czatów</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Chat migrated!" xml:space="preserve">
@@ -1405,6 +1418,7 @@
</trans-unit>
<trans-unit id="Color chats with the new themes." xml:space="preserve">
<source>Color chats with the new themes.</source>
<target>Koloruj czaty z nowymi motywami.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Color mode" xml:space="preserve">
@@ -1449,6 +1463,7 @@
</trans-unit>
<trans-unit id="Confirm contact deletion?" xml:space="preserve">
<source>Confirm contact deletion?</source>
<target>Potwierdzić usunięcie kontaktu?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Confirm database upgrades" xml:space="preserve">
@@ -1508,6 +1523,7 @@
</trans-unit>
<trans-unit id="Connect to your friends faster." xml:space="preserve">
<source>Connect to your friends faster.</source>
<target>Szybciej łącz się ze znajomymi.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
@@ -1586,6 +1602,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Connecting to contact, please wait or check later!" xml:space="preserve">
<source>Connecting to contact, please wait or check later!</source>
<target>Łączenie z kontaktem, poczekaj lub sprawdź później!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
@@ -1600,6 +1617,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Connection and servers status." xml:space="preserve">
<source>Connection and servers status.</source>
<target>Stan połączenia i serwerów.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection error" xml:space="preserve">
@@ -1614,6 +1632,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Connection notifications" xml:space="preserve">
<source>Connection notifications</source>
<target>Powiadomienia o połączeniu</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection request sent!" xml:space="preserve">
@@ -1653,6 +1672,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Contact deleted!" xml:space="preserve">
<source>Contact deleted!</source>
<target>Kontakt usunięty!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Contact hidden:" xml:space="preserve">
@@ -1667,6 +1687,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Contact is deleted." xml:space="preserve">
<source>Contact is deleted.</source>
<target>Kontakt jest usunięty.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Contact name" xml:space="preserve">
@@ -1681,6 +1702,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Contact will be deleted - this cannot be undone!" xml:space="preserve">
<source>Contact will be deleted - this cannot be undone!</source>
<target>Kontakt zostanie usunięty nie można tego cofnąć!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Contacts" xml:space="preserve">
@@ -1700,6 +1722,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Conversation deleted!" xml:space="preserve">
<source>Conversation deleted!</source>
<target>Rozmowa usunięta!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Copy" xml:space="preserve">
@@ -1978,6 +2001,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
<source>Delete %lld messages of members?</source>
<target>Usunąć %lld wiadomości członków?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete %lld messages?" xml:space="preserve">
@@ -2042,6 +2066,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Delete contact?" xml:space="preserve">
<source>Delete contact?</source>
<target>Usunąć kontakt?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete database" xml:space="preserve">
@@ -2151,6 +2176,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Delete up to 20 messages at once." xml:space="preserve">
<source>Delete up to 20 messages at once.</source>
<target>Usuń do 20 wiadomości na raz.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete user profile?" xml:space="preserve">
@@ -2160,6 +2186,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Delete without notification" xml:space="preserve">
<source>Delete without notification</source>
<target>Usuń bez powiadomienia</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Deleted" xml:space="preserve">
@@ -2219,6 +2246,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Destination server address of %@ is incompatible with forwarding server %@ settings." xml:space="preserve">
<source>Destination server address of %@ is incompatible with forwarding server %@ settings.</source>
<target>Adres serwera docelowego %@ jest niekompatybilny z ustawieniami serwera przekazującego %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Destination server error: %@" xml:space="preserve">
@@ -2228,6 +2256,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Destination server version of %@ is incompatible with forwarding server %@." xml:space="preserve">
<source>Destination server version of %@ is incompatible with forwarding server %@.</source>
<target>Wersja serwera docelowego %@ jest niekompatybilna z serwerem przekierowującym %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Detailed statistics" xml:space="preserve">
@@ -2247,6 +2276,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Developer options" xml:space="preserve">
<source>Developer options</source>
<target>Opcje deweloperskie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Developer tools" xml:space="preserve">
@@ -2301,6 +2331,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Disabled" xml:space="preserve">
<source>Disabled</source>
<target>Wyłączony</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Disappearing message" xml:space="preserve">
@@ -2530,6 +2561,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Enabled" xml:space="preserve">
<source>Enabled</source>
<target>Włączony</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enabled for" xml:space="preserve">
@@ -2704,6 +2736,7 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
<source>Error connecting to forwarding server %@. Please try later.</source>
<target>Błąd połączenia z serwerem przekierowania %@. Spróbuj ponownie później.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error creating address" xml:space="preserve">
@@ -3209,14 +3242,17 @@ To jest twój jednorazowy link!</target>
</trans-unit>
<trans-unit id="Forwarding server %@ failed to connect to destination server %@. Please try later." xml:space="preserve">
<source>Forwarding server %@ failed to connect to destination server %@. Please try later.</source>
<target>Serwer przekazujący %@ nie mógł połączyć się z serwerem docelowym %@. Spróbuj ponownie później.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding server address is incompatible with network settings: %@." xml:space="preserve">
<source>Forwarding server address is incompatible with network settings: %@.</source>
<target>Adres serwera przekierowującego jest niekompatybilny z ustawieniami sieciowymi: %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding server version is incompatible with network settings: %@." xml:space="preserve">
<source>Forwarding server version is incompatible with network settings: %@.</source>
<target>Wersja serwera przekierowującego jest niekompatybilna z ustawieniami sieciowymi: %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding server: %@&#10;Destination server error: %@" xml:space="preserve">
@@ -3803,6 +3839,7 @@ Błąd: %2$@</target>
</trans-unit>
<trans-unit id="It protects your IP address and connections." xml:space="preserve">
<source>It protects your IP address and connections.</source>
<target>Chroni Twój adres IP i połączenia.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="It seems like you are already connected via this link. If it is not the case, there was an error (%@)." xml:space="preserve">
@@ -3869,6 +3906,7 @@ To jest twój link do grupy %@!</target>
</trans-unit>
<trans-unit id="Keep conversation" xml:space="preserve">
<source>Keep conversation</source>
<target>Zachowaj rozmowę</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
@@ -4048,10 +4086,12 @@ To jest twój link do grupy %@!</target>
</trans-unit>
<trans-unit id="Media &amp; file servers" xml:space="preserve">
<source>Media &amp; file servers</source>
<target>Serwery mediów i plików</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Medium" xml:space="preserve">
<source>Medium</source>
<target>Średni</target>
<note>blur media</note>
</trans-unit>
<trans-unit id="Member" xml:space="preserve">
@@ -4141,6 +4181,7 @@ To jest twój link do grupy %@!</target>
</trans-unit>
<trans-unit id="Message servers" xml:space="preserve">
<source>Message servers</source>
<target>Serwery wiadomości</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Message source remains private." xml:space="preserve">
@@ -4355,6 +4396,7 @@ To jest twój link do grupy %@!</target>
</trans-unit>
<trans-unit id="New chat experience 🎉" xml:space="preserve">
<source>New chat experience 🎉</source>
<target>Nowe możliwości czatu 🎉</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="New contact request" xml:space="preserve">
@@ -4389,6 +4431,7 @@ To jest twój link do grupy %@!</target>
</trans-unit>
<trans-unit id="New media options" xml:space="preserve">
<source>New media options</source>
<target>Nowe opcje mediów</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="New member role" xml:space="preserve">
@@ -4483,6 +4526,7 @@ To jest twój link do grupy %@!</target>
</trans-unit>
<trans-unit id="Nothing selected" xml:space="preserve">
<source>Nothing selected</source>
<target>Nic nie jest zaznaczone</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
@@ -4560,6 +4604,7 @@ Wymaga włączenia VPN.</target>
</trans-unit>
<trans-unit id="Only delete conversation" xml:space="preserve">
<source>Only delete conversation</source>
<target>Usuń tylko rozmowę</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Only group owners can change group preferences." xml:space="preserve">
@@ -4799,10 +4844,12 @@ Wymaga włączenia VPN.</target>
</trans-unit>
<trans-unit id="Play from the chat list." xml:space="preserve">
<source>Play from the chat list.</source>
<target>Odtwórz z listy czatów.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
<source>Please ask your contact to enable calls.</source>
<target>Poproś kontakt o włącznie połączeń.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please ask your contact to enable sending voice messages." xml:space="preserve">
@@ -5108,6 +5155,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
</trans-unit>
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
<source>Reachable chat toolbar</source>
<target>Osiągalny pasek narzędzi czatu</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="React…" xml:space="preserve">
@@ -5383,6 +5431,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
</trans-unit>
<trans-unit id="Reset all hints" xml:space="preserve">
<source>Reset all hints</source>
<target>Zresetuj wszystkie wskazówki</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Reset all statistics" xml:space="preserve">
@@ -5517,6 +5566,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
</trans-unit>
<trans-unit id="Save and reconnect" xml:space="preserve">
<source>Save and reconnect</source>
<target>Zapisz i połącz ponownie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Save and update group profile" xml:space="preserve">
@@ -5681,6 +5731,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
</trans-unit>
<trans-unit id="Selected %lld" xml:space="preserve">
<source>Selected %lld</source>
<target>Zaznaczono %lld</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Selected chat preferences prohibit this message." xml:space="preserve">
@@ -5750,6 +5801,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
</trans-unit>
<trans-unit id="Send message to enable calls." xml:space="preserve">
<source>Send message to enable calls.</source>
<target>Wyślij wiadomość aby włączyć połączenia.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Send messages directly when IP address is protected and your or destination server does not support private routing." xml:space="preserve">
@@ -6039,6 +6091,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
</trans-unit>
<trans-unit id="Share from other apps." xml:space="preserve">
<source>Share from other apps.</source>
<target>Udostępnij z innych aplikacji.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Share link" xml:space="preserve">
@@ -6053,6 +6106,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
</trans-unit>
<trans-unit id="Share to SimpleX" xml:space="preserve">
<source>Share to SimpleX</source>
<target>Udostępnij do SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Share with contacts" xml:space="preserve">
@@ -6207,10 +6261,12 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
</trans-unit>
<trans-unit id="Soft" xml:space="preserve">
<source>Soft</source>
<target>Łagodny</target>
<note>blur media</note>
</trans-unit>
<trans-unit id="Some file(s) were not exported:" xml:space="preserve">
<source>Some file(s) were not exported:</source>
<target>Niektóre plik(i) nie zostały wyeksportowane:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Some non-fatal errors occurred during import - you may see Chat console for more details." xml:space="preserve">
@@ -6220,6 +6276,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
</trans-unit>
<trans-unit id="Some non-fatal errors occurred during import:" xml:space="preserve">
<source>Some non-fatal errors occurred during import:</source>
<target>Podczas importu wystąpiły niekrytyczne błędy:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Somebody" xml:space="preserve">
@@ -6319,6 +6376,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
</trans-unit>
<trans-unit id="Strong" xml:space="preserve">
<source>Strong</source>
<target>Silne</target>
<note>blur media</note>
</trans-unit>
<trans-unit id="Submit" xml:space="preserve">
@@ -6358,6 +6416,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
</trans-unit>
<trans-unit id="TCP connection" xml:space="preserve">
<source>TCP connection</source>
<target>Połączenie TCP</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="TCP connection timeout" xml:space="preserve">
@@ -6529,10 +6588,12 @@ Może się to zdarzyć z powodu jakiegoś błędu lub gdy połączenie jest skom
</trans-unit>
<trans-unit id="The messages will be deleted for all members." xml:space="preserve">
<source>The messages will be deleted for all members.</source>
<target>Wiadomości zostaną usunięte dla wszystkich członków.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The messages will be marked as moderated for all members." xml:space="preserve">
<source>The messages will be marked as moderated for all members.</source>
<target>Wiadomości zostaną oznaczone jako moderowane dla wszystkich członków.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The next generation of private messaging" xml:space="preserve">
@@ -6719,6 +6780,7 @@ Przed włączeniem tej funkcji zostanie wyświetlony monit uwierzytelniania.</ta
</trans-unit>
<trans-unit id="Toggle chat list:" xml:space="preserve">
<source>Toggle chat list:</source>
<target>Przełącz listę czatów:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
@@ -6728,6 +6790,7 @@ Przed włączeniem tej funkcji zostanie wyświetlony monit uwierzytelniania.</ta
</trans-unit>
<trans-unit id="Toolbar opacity" xml:space="preserve">
<source>Toolbar opacity</source>
<target>Nieprzezroczystość paska narzędzi</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Total" xml:space="preserve">
@@ -6914,6 +6977,7 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
</trans-unit>
<trans-unit id="Update settings?" xml:space="preserve">
<source>Update settings?</source>
<target>Zaktualizować ustawienia?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Updating settings will re-connect the client to all servers." xml:space="preserve">
@@ -7023,6 +7087,7 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
</trans-unit>
<trans-unit id="Use the app with one hand." xml:space="preserve">
<source>Use the app with one hand.</source>
<target>Korzystaj z aplikacji jedną ręką.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="User profile" xml:space="preserve">
@@ -7384,6 +7449,7 @@ Powtórzyć prośbę dołączenia?</target>
</trans-unit>
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
<source>You can change it in Appearance settings.</source>
<target>Możesz to zmienić w ustawieniach wyglądu.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can create it later" xml:space="preserve">
@@ -7423,6 +7489,7 @@ Powtórzyć prośbę dołączenia?</target>
</trans-unit>
<trans-unit id="You can send messages to %@ from Archived contacts." xml:space="preserve">
<source>You can send messages to %@ from Archived contacts.</source>
<target>Możesz wysyłać wiadomości do %@ ze zarchiwizowanych kontaktów.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can set lock screen notification preview via settings." xml:space="preserve">
@@ -7452,6 +7519,7 @@ Powtórzyć prośbę dołączenia?</target>
</trans-unit>
<trans-unit id="You can still view conversation with %@ in the list of chats." xml:space="preserve">
<source>You can still view conversation with %@ in the list of chats.</source>
<target>Nadal możesz przeglądać rozmowę z %@ na liście czatów.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
@@ -7518,10 +7586,12 @@ Powtórzyć prośbę połączenia?</target>
</trans-unit>
<trans-unit id="You may migrate the exported database." xml:space="preserve">
<source>You may migrate the exported database.</source>
<target>Możesz zmigrować wyeksportowaną bazy danych.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You may save the exported archive." xml:space="preserve">
<source>You may save the exported archive.</source>
<target>Możesz zapisać wyeksportowane archiwum.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You must use the most recent version of your chat database on one device ONLY, otherwise you may stop receiving the messages from some contacts." xml:space="preserve">
@@ -7531,6 +7601,7 @@ Powtórzyć prośbę połączenia?</target>
</trans-unit>
<trans-unit id="You need to allow your contact to call to be able to call them." xml:space="preserve">
<source>You need to allow your contact to call to be able to call them.</source>
<target>Aby móc dzwonić, musisz zezwolić kontaktowi na połączenia.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You need to allow your contact to send voice messages to be able to send them." xml:space="preserve">
@@ -7842,6 +7913,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
</trans-unit>
<trans-unit id="call" xml:space="preserve">
<source>call</source>
<target>zadzwoń</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="call error" xml:space="preserve">
@@ -8216,6 +8288,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
</trans-unit>
<trans-unit id="invite" xml:space="preserve">
<source>invite</source>
<target>zaproś</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="invited" xml:space="preserve">
@@ -8275,6 +8348,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
</trans-unit>
<trans-unit id="message" xml:space="preserve">
<source>message</source>
<target>wiadomość</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="message received" xml:space="preserve">
@@ -8309,6 +8383,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
</trans-unit>
<trans-unit id="mute" xml:space="preserve">
<source>mute</source>
<target>wycisz</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="never" xml:space="preserve">
@@ -8445,6 +8520,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
</trans-unit>
<trans-unit id="search" xml:space="preserve">
<source>search</source>
<target>szukaj</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="sec" xml:space="preserve">
@@ -8533,6 +8609,7 @@ ostatnia otrzymana wiadomość: %2$@</target>
</trans-unit>
<trans-unit id="unmute" xml:space="preserve">
<source>unmute</source>
<target>wyłącz wyciszenie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="unprotected" xml:space="preserve">
@@ -8582,6 +8659,7 @@ ostatnia otrzymana wiadomość: %2$@</target>
</trans-unit>
<trans-unit id="video" xml:space="preserve">
<source>video</source>
<target>wideo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="video call (not e2e encrypted)" xml:space="preserve">
@@ -8762,14 +8840,17 @@ ostatnia otrzymana wiadomość: %2$@</target>
<body>
<trans-unit id="CFBundleDisplayName" xml:space="preserve">
<source>SimpleX SE</source>
<target>SimpleX SE</target>
<note>Bundle display name</note>
</trans-unit>
<trans-unit id="CFBundleName" xml:space="preserve">
<source>SimpleX SE</source>
<target>SimpleX SE</target>
<note>Bundle name</note>
</trans-unit>
<trans-unit id="NSHumanReadableCopyright" xml:space="preserve">
<source>Copyright © 2024 SimpleX Chat. All rights reserved.</source>
<target>Copyright © 2024 SimpleX Chat. Wszelkie prawa zastrzeżone.</target>
<note>Copyright (human-readable)</note>
</trans-unit>
</body>
@@ -8781,150 +8862,187 @@ ostatnia otrzymana wiadomość: %2$@</target>
<body>
<trans-unit id="%@" xml:space="preserve">
<source>%@</source>
<target>%@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="App is locked!" xml:space="preserve">
<source>App is locked!</source>
<target>Aplikacja zablokowana!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Cancel" xml:space="preserve">
<source>Cancel</source>
<target>Anuluj</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Cannot access keychain to save database password" xml:space="preserve">
<source>Cannot access keychain to save database password</source>
<target>Nie można uzyskać dostępu do pęku kluczy aby zapisać hasło do bazy danych</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Cannot forward message" xml:space="preserve">
<source>Cannot forward message</source>
<target>Nie można przekazać wiadomości</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Comment" xml:space="preserve">
<source>Comment</source>
<target>Komentarz</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Currently maximum supported file size is %@." xml:space="preserve">
<source>Currently maximum supported file size is %@.</source>
<target>Obecnie maksymalny obsługiwany rozmiar pliku to %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Database downgrade required" xml:space="preserve">
<source>Database downgrade required</source>
<target>Wymagane obniżenie wersji bazy danych</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Database encrypted!" xml:space="preserve">
<source>Database encrypted!</source>
<target>Baza danych zaszyfrowana!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Database error" xml:space="preserve">
<source>Database error</source>
<target>Błąd bazy danych</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Database passphrase is different from saved in the keychain." xml:space="preserve">
<source>Database passphrase is different from saved in the keychain.</source>
<target>Hasło bazy danych jest inne niż zapisane w pęku kluczy.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Database passphrase is required to open chat." xml:space="preserve">
<source>Database passphrase is required to open chat.</source>
<target>Hasło do bazy danych jest wymagane do otwarcia czatu.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Database upgrade required" xml:space="preserve">
<source>Database upgrade required</source>
<target>Wymagana aktualizacja bazy danych</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error preparing file" xml:space="preserve">
<source>Error preparing file</source>
<target>Błąd przygotowania pliku</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error preparing message" xml:space="preserve">
<source>Error preparing message</source>
<target>Błąd przygotowania wiadomości</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error: %@" xml:space="preserve">
<source>Error: %@</source>
<target>Błąd: %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File error" xml:space="preserve">
<source>File error</source>
<target>Błąd pliku</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible database version" xml:space="preserve">
<source>Incompatible database version</source>
<target>Niekompatybilna wersja bazy danych</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Invalid migration confirmation" xml:space="preserve">
<source>Invalid migration confirmation</source>
<target>Nieprawidłowe potwierdzenie migracji</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keychain error" xml:space="preserve">
<source>Keychain error</source>
<target>Błąd pęku kluczy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Large file!" xml:space="preserve">
<source>Large file!</source>
<target>Duży plik!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="No active profile" xml:space="preserve">
<source>No active profile</source>
<target>Brak aktywnego profilu</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Ok</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open the app to downgrade the database." xml:space="preserve">
<source>Open the app to downgrade the database.</source>
<target>Otwórz aplikację aby obniżyć wersję bazy danych.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open the app to upgrade the database." xml:space="preserve">
<source>Open the app to upgrade the database.</source>
<target>Otwórz aplikację aby zaktualizować bazę danych.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passphrase" xml:space="preserve">
<source>Passphrase</source>
<target>Hasło</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please create a profile in the SimpleX app" xml:space="preserve">
<source>Please create a profile in the SimpleX app</source>
<target>Proszę utworzyć profil w aplikacji SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Selected chat preferences prohibit this message." xml:space="preserve">
<source>Selected chat preferences prohibit this message.</source>
<target>Wybrane preferencje czatu zabraniają tej wiadomości.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sending a message takes longer than expected." xml:space="preserve">
<source>Sending a message takes longer than expected.</source>
<target>Wysłanie wiadomości trwa dłużej niż oczekiwano.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sending message…" xml:space="preserve">
<source>Sending message…</source>
<target>Wysyłanie wiadomości…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Share" xml:space="preserve">
<source>Share</source>
<target>Udostępnij</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Slow network?" xml:space="preserve">
<source>Slow network?</source>
<target>Wolna sieć?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unknown database error: %@" xml:space="preserve">
<source>Unknown database error: %@</source>
<target>Nieznany błąd bazy danych: %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unsupported format" xml:space="preserve">
<source>Unsupported format</source>
<target>Niewspierany format</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wait" xml:space="preserve">
<source>Wait</source>
<target>Czekaj</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
<target>Nieprawidłowe hasło bazy danych</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can allow sharing in Privacy &amp; Security / SimpleX Lock settings." xml:space="preserve">
<source>You can allow sharing in Privacy &amp; Security / SimpleX Lock settings.</source>
<target>Możesz zezwolić na udostępnianie w ustawieniach Prywatność i bezpieczeństwo / Blokada SimpleX.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
</body>
@@ -5234,6 +5234,274 @@ Isso pode acontecer por causa de algum bug ou quando a conexão está comprometi
<target state="translated">%1$@ em %2$@:</target>
<note>copied message info, &lt;sender&gt; at &lt;time&gt;</note>
</trans-unit>
<trans-unit id="Allow your contacts to irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
<source>Allow your contacts to irreversibly delete sent messages. (24 hours)</source>
<target state="translated">Permitir que seus contatos deletem mensagens enviadas de maneira irreversível. (24 horas)</target>
</trans-unit>
<trans-unit id="%@ downloaded" xml:space="preserve" approved="no">
<source>%@ downloaded</source>
<target state="translated">baixado</target>
</trans-unit>
<trans-unit id="%@ uploaded" xml:space="preserve" approved="no">
<source>%@ uploaded</source>
<target state="translated">transferido</target>
</trans-unit>
<trans-unit id="A new random profile will be shared." xml:space="preserve" approved="no">
<source>A new random profile will be shared.</source>
<target state="translated">Um novo perfil aleatório será compartilhado.</target>
</trans-unit>
<trans-unit id="Camera not available" xml:space="preserve" approved="no">
<source>Camera not available</source>
<target state="translated">Câmera indisponível</target>
</trans-unit>
<trans-unit id="Admins can block a member for all." xml:space="preserve" approved="no">
<source>Admins can block a member for all.</source>
<target state="translated">Administradores podem bloquear um membro para todos.</target>
</trans-unit>
<trans-unit id="Allow to irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
<source>Allow to irreversibly delete sent messages. (24 hours)</source>
<target state="translated">Permitir que mensagens enviadas sejam deletadas de maneira irreversível. (24 horas)</target>
</trans-unit>
<trans-unit id="Apply" xml:space="preserve" approved="no">
<source>Apply</source>
<target state="translated">Aplicar</target>
</trans-unit>
<trans-unit id="Accent" xml:space="preserve" approved="no">
<source>Accent</source>
<target state="translated">Esquema</target>
</trans-unit>
<trans-unit id="Accept connection request?" xml:space="preserve" approved="no">
<source>Accept connection request?</source>
<target state="translated">Aceitar solicitação de conexão?</target>
</trans-unit>
<trans-unit id="Active connections" xml:space="preserve" approved="no">
<source>Active connections</source>
<target state="translated">Conexões ativas</target>
</trans-unit>
<trans-unit id="Add contact" xml:space="preserve" approved="no">
<source>Add contact</source>
<target state="translated">Adicionar contato</target>
</trans-unit>
<trans-unit id="Additional accent" xml:space="preserve" approved="no">
<source>Additional accent</source>
<target state="translated">Esquema adicional</target>
</trans-unit>
<trans-unit id="All new messages from %@ will be hidden!" xml:space="preserve" approved="no">
<source>All new messages from %@ will be hidden!</source>
<target state="translated">Todas as novas mensagens de %@ serão ocultas!</target>
</trans-unit>
<trans-unit id="All profiles" xml:space="preserve" approved="no">
<source>All profiles</source>
<target state="translated">Todos perfis</target>
</trans-unit>
<trans-unit id="Allow calls?" xml:space="preserve" approved="no">
<source>Allow calls?</source>
<target state="translated">Permitir chamadas?</target>
</trans-unit>
<trans-unit id="Archive contacts to chat later." xml:space="preserve" approved="no">
<source>Archive contacts to chat later.</source>
<target state="translated">Arquivar contatos para conversar depois.</target>
</trans-unit>
<trans-unit id="Blur media" xml:space="preserve" approved="no">
<source>Blur media</source>
<target state="translated">Censurar mídia</target>
</trans-unit>
<trans-unit id="Calls prohibited!" xml:space="preserve" approved="no">
<source>Calls prohibited!</source>
<target state="translated">Chamadas proibidas!</target>
</trans-unit>
<trans-unit id="Can't call contact" xml:space="preserve" approved="no">
<source>Can't call contact</source>
<target state="translated">Não foi possível ligar para o contato</target>
</trans-unit>
<trans-unit id="%lld messages marked deleted" xml:space="preserve" approved="no">
<source>%lld messages marked deleted</source>
<target state="translated">mensagens deletadas</target>
</trans-unit>
<trans-unit id="0 sec" xml:space="preserve" approved="no">
<source>0 sec</source>
<target state="translated">0 seg</target>
</trans-unit>
<trans-unit id="%lld messages blocked" xml:space="preserve" approved="no">
<source>%lld messages blocked</source>
<target state="translated">mensagens bloqueadas</target>
</trans-unit>
<trans-unit id="%lld messages blocked by admin" xml:space="preserve" approved="no">
<source>%lld messages blocked by admin</source>
<target state="translated">mensagens bloqueadas pelo administrador</target>
</trans-unit>
<trans-unit id="**Please note**: using the same database on two devices will break the decryption of messages from your connections, as a security protection." xml:space="preserve" approved="no">
<source>**Please note**: using the same database on two devices will break the decryption of messages from your connections, as a security protection.</source>
<target state="translated">**Nota**: usar o mesmo banco de dados em dois dispositivos irá quebrar a desencriptação das mensagens de suas conexões como uma medida de segurança.</target>
</trans-unit>
<trans-unit id="- more stable message delivery.&#10;- a bit better groups.&#10;- and more!" xml:space="preserve" approved="no">
<source>- more stable message delivery.
- a bit better groups.
- and more!</source>
<target state="translated">- entrega de mensagens mais estável.
- grupos melhorados.
- e muito mais!</target>
</trans-unit>
<trans-unit id="All messages will be deleted - this cannot be undone!" xml:space="preserve" approved="no">
<source>All messages will be deleted - this cannot be undone!</source>
<target state="translated">Todas as mensagens serão deletadas - isto não pode ser desfeito!</target>
</trans-unit>
<trans-unit id="Allow to send files and media." xml:space="preserve" approved="no">
<source>Allow to send files and media.</source>
<target state="translated">Permitir o envio de arquivos e mídia.</target>
</trans-unit>
<trans-unit id="Allow to send SimpleX links." xml:space="preserve" approved="no">
<source>Allow to send SimpleX links.</source>
<target state="translated">Permitir envio de links SimpleX.</target>
</trans-unit>
<trans-unit id="Block for all" xml:space="preserve" approved="no">
<source>Block for all</source>
<target state="translated">Bloquear para todos</target>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve" approved="no">
<source>Block member</source>
<target state="translated">Bloquear membro</target>
</trans-unit>
<trans-unit id="Blocked by admin" xml:space="preserve" approved="no">
<source>Blocked by admin</source>
<target state="translated">Bloqueado por um administrador</target>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve" approved="no">
<source>Block group members</source>
<target state="translated">Bloquear membros de grupo</target>
</trans-unit>
<trans-unit id="Block member for all?" xml:space="preserve" approved="no">
<source>Block member for all?</source>
<target state="translated">Bloquear membro para todos?</target>
</trans-unit>
<trans-unit id="Block member?" xml:space="preserve" approved="no">
<source>Block member?</source>
<target state="translated">Bloquear membro?</target>
</trans-unit>
<trans-unit id="Both you and your contact can irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
<source>Both you and your contact can irreversibly delete sent messages. (24 hours)</source>
<target state="translated">Você e seu contato podem apagar mensagens enviadas de maneira irreversível. (24 horas)</target>
</trans-unit>
<trans-unit id="Can't call member" xml:space="preserve" approved="no">
<source>Can't call member</source>
<target state="translated">Não foi possível ligar para este membro</target>
</trans-unit>
<trans-unit id="Can't message member" xml:space="preserve" approved="no">
<source>Can't message member</source>
<target state="translated">Não foi possível enviar mensagem para este membro</target>
</trans-unit>
<trans-unit id="Cancel migration" xml:space="preserve" approved="no">
<source>Cancel migration</source>
<target state="translated">Cancelar migração</target>
</trans-unit>
<trans-unit id="Abort" xml:space="preserve" approved="no">
<source>Abort</source>
<target state="translated">Abortar</target>
</trans-unit>
<trans-unit id="Abort changing address" xml:space="preserve" approved="no">
<source>Abort changing address</source>
<target state="translated">Abortar troca de endereço</target>
</trans-unit>
<trans-unit id="Abort changing address?" xml:space="preserve" approved="no">
<source>Abort changing address?</source>
<target state="translated">Abortar troca de endereço?</target>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve" approved="no">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<target state="translated">- notificar contatos apagados de maneira opcional.
- nome de perfil com espaços.
- e muito mais!</target>
</trans-unit>
<trans-unit id="Allow sharing" xml:space="preserve" approved="no">
<source>Allow sharing</source>
<target state="translated">Permitir compartilhamento</target>
</trans-unit>
<trans-unit id="Block" xml:space="preserve" approved="no">
<source>Block</source>
<target state="translated">Bloquear</target>
</trans-unit>
<trans-unit id="Additional accent 2" xml:space="preserve" approved="no">
<source>Additional accent 2</source>
<target state="translated">Esquema adicional 2</target>
</trans-unit>
<trans-unit id="Address change will be aborted. Old receiving address will be used." xml:space="preserve" approved="no">
<source>Address change will be aborted. Old receiving address will be used.</source>
<target state="translated">Alteração de endereço será abortada. O endereço antigo será utilizado.</target>
</trans-unit>
<trans-unit id="Advanced settings" xml:space="preserve" approved="no">
<source>Advanced settings</source>
<target state="translated">Configurações avançadas</target>
</trans-unit>
<trans-unit id="All data is private to your device." xml:space="preserve" approved="no">
<source>All data is private to your device.</source>
<target state="translated">Toda informação é privada em seu dispositivo.</target>
</trans-unit>
<trans-unit id="All your contacts, conversations and files will be securely encrypted and uploaded in chunks to configured XFTP relays." xml:space="preserve" approved="no">
<source>All your contacts, conversations and files will be securely encrypted and uploaded in chunks to configured XFTP relays.</source>
<target state="translated">Todos os seus contatos, conversas e arquivos serão encriptados e enviados em pedaços para nós XFTP.</target>
</trans-unit>
<trans-unit id="Allow irreversible message deletion only if your contact allows it to you. (24 hours)" xml:space="preserve" approved="no">
<source>Allow irreversible message deletion only if your contact allows it to you. (24 hours)</source>
<target state="translated">Permitir deletar mensagens de maneira irreversível apenas se seu contato permitir para você. (24 horas)</target>
</trans-unit>
<trans-unit id="Already connecting!" xml:space="preserve" approved="no">
<source>Already connecting!</source>
<target state="translated">Já está conectando!</target>
</trans-unit>
<trans-unit id="Already joining the group!" xml:space="preserve" approved="no">
<source>Already joining the group!</source>
<target state="translated">Já está entrando no grupo!</target>
</trans-unit>
<trans-unit id="Always use private routing." xml:space="preserve" approved="no">
<source>Always use private routing.</source>
<target state="translated">Sempre use rotas privadas.</target>
</trans-unit>
<trans-unit id="Apply to" xml:space="preserve" approved="no">
<source>Apply to</source>
<target state="translated">Aplicar em</target>
</trans-unit>
<trans-unit id="Archiving database" xml:space="preserve" approved="no">
<source>Archiving database</source>
<target state="translated">Arquivando banco de dados</target>
</trans-unit>
<trans-unit id="Black" xml:space="preserve" approved="no">
<source>Black</source>
<target state="translated">Preto</target>
</trans-unit>
<trans-unit id="Cannot forward message" xml:space="preserve" approved="no">
<source>Cannot forward message</source>
<target state="translated">Não é possível encaminhar mensagem</target>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve" approved="no">
<source>(new)</source>
<target state="translated">(novo)</target>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve" approved="no">
<source>(this device v%@)</source>
<target state="translated">este dispositivo</target>
</trans-unit>
<trans-unit id="**Add contact**: to create a new invitation link, or connect via a link you received." xml:space="preserve" approved="no">
<source>**Add contact**: to create a new invitation link, or connect via a link you received.</source>
<target state="translated">**Adicionar contato**: criar um novo link de convite ou conectar via um link que você recebeu.</target>
</trans-unit>
<trans-unit id="**Create group**: to create a new group." xml:space="preserve" approved="no">
<source>**Create group**: to create a new group.</source>
<target state="translated">**Criar grupo**: criar um novo grupo.</target>
</trans-unit>
<trans-unit id="**Warning**: the archive will be removed." xml:space="preserve" approved="no">
<source>**Warning**: the archive will be removed.</source>
<target state="translated">**Aviso**: o arquivo será removido.</target>
</trans-unit>
<trans-unit id="A few more things" xml:space="preserve" approved="no">
<source>A few more things</source>
<target state="translated">E mais algumas coisas</target>
</trans-unit>
<trans-unit id="Archived contacts" xml:space="preserve" approved="no">
<source>Archived contacts</source>
<target state="translated">Contatos arquivados</target>
</trans-unit>
</body>
</file>
<file original="en.lproj/SimpleX--iOS--InfoPlist.strings" source-language="en" target-language="pt-BR" datatype="plaintext">
@@ -1418,7 +1418,7 @@
</trans-unit>
<trans-unit id="Color chats with the new themes." xml:space="preserve">
<source>Color chats with the new themes.</source>
<target>Добавьте цвета к чатам в настройках тем.</target>
<target>Добавьте цвета к чатам в настройках.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Color mode" xml:space="preserve">
@@ -2176,7 +2176,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete up to 20 messages at once." xml:space="preserve">
<source>Delete up to 20 messages at once.</source>
<target>Удаляйте до 20 сообщений одновременно.</target>
<target>Удаляйте до 20 сообщений за раз.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete user profile?" xml:space="preserve">
@@ -4988,7 +4988,7 @@ Error: %@</source>
</trans-unit>
<trans-unit id="Private message routing 🚀" xml:space="preserve">
<source>Private message routing 🚀</source>
<target>Конфиденциальная доставка сообщений 🚀</target>
<target>Конфиденциальная доставка 🚀</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Private notes" xml:space="preserve">
File diff suppressed because it is too large Load Diff
@@ -314,7 +314,7 @@
</trans-unit>
<trans-unit id="About SimpleX Chat" xml:space="preserve" approved="no">
<source>About SimpleX Chat</source>
<target state="translated">關於 SimpleX 對話</target>
<target state="translated">關於 SimpleX Chat</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Accent color" xml:space="preserve" approved="no">
@@ -445,7 +445,7 @@
</trans-unit>
<trans-unit id="Allow your contacts to send disappearing messages." xml:space="preserve" approved="no">
<source>Allow your contacts to send disappearing messages.</source>
<target state="translated">允許的聯絡人傳送自動銷毀的訊息。</target>
<target state="translated">允許的聯絡人傳送限時訊息。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Allow your contacts to send voice messages." xml:space="preserve" approved="no">
@@ -5898,6 +5898,230 @@ It can happen because of some bug or when the connection is compromised.</source
<target state="translated">%@ 和 %@ 已連接</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">%@ 下載</target>
</trans-unit>
<trans-unit id="%@ uploaded" xml:space="preserve" approved="no">
<source>%@ uploaded</source>
<target state="translated">%@ 上傳</target>
</trans-unit>
<trans-unit id="Abort" xml:space="preserve" approved="no">
<source>Abort</source>
<target state="translated">中止</target>
</trans-unit>
<trans-unit id="**Create group**: to create a new group." xml:space="preserve" approved="no">
<source>**Create group**: to create a new group.</source>
<target state="translated">**創建群組**: 創建一個新的群組。</target>
</trans-unit>
<trans-unit id="Abort changing address" xml:space="preserve" approved="no">
<source>Abort changing address</source>
<target state="translated">中止更改地址</target>
</trans-unit>
<trans-unit id="Accept connection request?" xml:space="preserve" approved="no">
<source>Accept connection request?</source>
<target state="translated">接受連線請求?</target>
</trans-unit>
<trans-unit id="Camera not available" xml:space="preserve" approved="no">
<source>Camera not available</source>
<target state="translated">相機不可用</target>
</trans-unit>
<trans-unit id="All messages will be deleted - this cannot be undone!" xml:space="preserve" approved="no">
<source>All messages will be deleted - this cannot be undone!</source>
<target state="translated">所有訊息都將被刪除 - 這不能還原!</target>
</trans-unit>
<trans-unit id="Allow irreversible message deletion only if your contact allows it to you. (24 hours)" xml:space="preserve" approved="no">
<source>Allow irreversible message deletion only if your contact allows it to you. (24 hours)</source>
<target state="translated">只有你的聯絡人允許的情況下,才允許不可逆地將訊息刪除。(24小時)</target>
</trans-unit>
<trans-unit id="Allow to irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
<source>Allow to irreversibly delete sent messages. (24 hours)</source>
<target state="translated">允許將不可撤銷的訊息刪除。(24小時)</target>
</trans-unit>
<trans-unit id="Allow your contacts to irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
<source>Allow your contacts to irreversibly delete sent messages. (24 hours)</source>
<target state="translated">允許您的聯絡人不可復原地刪除已傳送的訊息。(24小時)</target>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve" approved="no">
<source>Bad desktop address</source>
<target state="translated">無效的桌面地址</target>
</trans-unit>
<trans-unit id="Error decrypting file" xml:space="preserve" approved="no">
<source>Error decrypting file</source>
<target state="translated">解密檔案時出錯</target>
</trans-unit>
<trans-unit id="Add contact" xml:space="preserve" approved="no">
<source>Add contact</source>
<target state="translated">新增聯絡人</target>
</trans-unit>
<trans-unit id="Advanced settings" xml:space="preserve" approved="no">
<source>Advanced settings</source>
<target state="translated">進階設定</target>
</trans-unit>
<trans-unit id="Allow calls?" xml:space="preserve" approved="no">
<source>Allow calls?</source>
<target state="translated">允許通話?</target>
</trans-unit>
<trans-unit id="Allow to send files and media." xml:space="preserve" approved="no">
<source>Allow to send files and media.</source>
<target state="translated">允許傳送檔案和媒體。</target>
</trans-unit>
<trans-unit id="Already joining the group!" xml:space="preserve" approved="no">
<source>Already joining the group!</source>
<target state="translated">已加入群組!</target>
</trans-unit>
<trans-unit id="App data migration" xml:space="preserve" approved="no">
<source>App data migration</source>
<target state="translated">應用資料轉移</target>
</trans-unit>
<trans-unit id="Apply" xml:space="preserve" approved="no">
<source>Apply</source>
<target state="translated">應用</target>
</trans-unit>
<trans-unit id="Apply to" xml:space="preserve" approved="no">
<source>Apply to</source>
<target state="translated">應用到</target>
</trans-unit>
<trans-unit id="Archive and upload" xml:space="preserve" approved="no">
<source>Archive and upload</source>
<target state="translated">儲存並上傳</target>
</trans-unit>
<trans-unit id="Block" xml:space="preserve" approved="no">
<source>Block</source>
<target state="translated">封鎖</target>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve" approved="no">
<source>Block group members</source>
<target state="translated">封鎖群組成員</target>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve" approved="no">
<source>Block member</source>
<target state="translated">封鎖成員</target>
</trans-unit>
<trans-unit id="Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!" xml:space="preserve" approved="no">
<source>Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!</source>
<target state="translated">保加利亞語、芬蘭語、泰語和烏克蘭語——感謝使用者們和[Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)</target>
</trans-unit>
<trans-unit id="Can't call member" xml:space="preserve" approved="no">
<source>Can't call member</source>
<target state="translated">無法與成員通話</target>
</trans-unit>
<trans-unit id="Can't message member" xml:space="preserve" approved="no">
<source>Can't message member</source>
<target state="translated">無法傳送訊息給成員</target>
</trans-unit>
<trans-unit id="Cancel migration" xml:space="preserve" approved="no">
<source>Cancel migration</source>
<target state="translated">取消遷移</target>
</trans-unit>
<trans-unit id="Chat database exported" xml:space="preserve" approved="no">
<source>Chat database exported</source>
<target state="translated">導出聊天數據庫</target>
</trans-unit>
<trans-unit id="0 sec" xml:space="preserve" approved="no">
<source>0 sec</source>
<target state="translated">0 秒</target>
</trans-unit>
<trans-unit id="All your contacts, conversations and files will be securely encrypted and uploaded in chunks to configured XFTP relays." xml:space="preserve" approved="no">
<source>All your contacts, conversations and files will be securely encrypted and uploaded in chunks to configured XFTP relays.</source>
<target state="translated">你的所有聯絡人、對話和文件將被安全加密並切塊上傳到設置的 XFTP 中繼。</target>
</trans-unit>
<trans-unit id="Address change will be aborted. Old receiving address will be used." xml:space="preserve" approved="no">
<source>Address change will be aborted. Old receiving address will be used.</source>
<target state="translated">將取消地址更改。將使用舊聯絡地址。</target>
</trans-unit>
<trans-unit id="Archiving database" xml:space="preserve" approved="no">
<source>Archiving database</source>
<target state="translated">正在儲存資料庫</target>
</trans-unit>
<trans-unit id="Cellular" xml:space="preserve" approved="no">
<source>Cellular</source>
<target state="translated">行動網路</target>
</trans-unit>
<trans-unit id="%@, %@ and %lld members" xml:space="preserve" approved="no">
<source>%@, %@ and %lld members</source>
<target state="translated">%@, %@ 和 %lld 成員</target>
</trans-unit>
<trans-unit id="%lld messages marked deleted" xml:space="preserve" approved="no">
<source>%lld messages marked deleted</source>
<target state="translated">%lld 條訊息已刪除</target>
</trans-unit>
<trans-unit id="Already connecting!" xml:space="preserve" approved="no">
<source>Already connecting!</source>
<target state="translated">已連接!</target>
</trans-unit>
<trans-unit id="Block member?" xml:space="preserve" approved="no">
<source>Block member?</source>
<target state="translated">封鎖成員?</target>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve" approved="no">
<source>(new)</source>
<target state="translated">(新)</target>
</trans-unit>
<trans-unit id="%@, %@ and %lld other members connected" xml:space="preserve" approved="no">
<source>%@, %@ and %lld other members connected</source>
<target state="translated">%@, %@ 和 %lld 個成員已連接</target>
</trans-unit>
<trans-unit id="A few more things" xml:space="preserve" approved="no">
<source>A few more things</source>
<target state="translated">其他</target>
</trans-unit>
<trans-unit id="Show last messages" xml:space="preserve" approved="no">
<source>Show last messages</source>
<target state="translated">顯示最新的訊息</target>
</trans-unit>
<trans-unit id="App encrypts new local files (except videos)." xml:space="preserve" approved="no">
<source>App encrypts new local files (except videos).</source>
<target state="translated">應用程式將為新的本機文件(影片除外)加密。</target>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve" approved="no">
<source>Better groups</source>
<target state="translated">更加的群組</target>
</trans-unit>
<trans-unit id="%lld new interface languages" xml:space="preserve" approved="no">
<source>%lld new interface languages</source>
<target state="translated">%lld 種新的介面語言</target>
</trans-unit>
<trans-unit id="Blocked by admin" xml:space="preserve" approved="no">
<source>Blocked by admin</source>
<target state="translated">由管理員封鎖</target>
</trans-unit>
<trans-unit id="Both you and your contact can irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
<source>Both you and your contact can irreversibly delete sent messages. (24 hours)</source>
<target state="translated">您與您的聯絡人都可以不可復原地删除已傳送的訊息。(24小時)</target>
</trans-unit>
<trans-unit id="Encrypt local files" xml:space="preserve" approved="no">
<source>Encrypt local files</source>
<target state="translated">加密本機檔案</target>
</trans-unit>
<trans-unit id="- more stable message delivery.&#10;- a bit better groups.&#10;- and more!" xml:space="preserve" approved="no">
<source>- more stable message delivery.
- a bit better groups.
- and more!</source>
<target state="translated">- 更穩定的傳送!
- 更好的社群!
- 以及更多!</target>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve" approved="no">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<target state="translated">- 可選擇通知已刪除的聯絡人
- 帶空格的共人資料名稱。
-以及更多!</target>
</trans-unit>
<trans-unit id="Abort changing address?" xml:space="preserve" approved="no">
<source>Abort changing address?</source>
<target state="translated">中止更改地址?</target>
</trans-unit>
<trans-unit id="Allow to send SimpleX links." xml:space="preserve" approved="no">
<source>Allow to send SimpleX links.</source>
<target state="translated">允許傳送 SimpleX 連結。</target>
</trans-unit>
<trans-unit id="Background" xml:space="preserve" approved="no">
<source>Background</source>
<target state="translated">後台</target>
</trans-unit>
</body>
</file>
<file original="en.lproj/SimpleX--iOS--InfoPlist.strings" source-language="en" target-language="zh-Hant" datatype="plaintext">
+15 -10
View File
@@ -571,17 +571,22 @@ func receivedMsgNtf(_ res: ChatResponse) async -> (String, NSENotification)? {
// TODO profile update
case let .receivedContactRequest(user, contactRequest):
return (UserContact(contactRequest: contactRequest).id, .nse(createContactRequestNtf(user, contactRequest)))
case let .newChatItem(user, aChatItem):
let cInfo = aChatItem.chatInfo
var cItem = aChatItem.chatItem
if !cInfo.ntfsEnabled {
ntfBadgeCountGroupDefault.set(max(0, ntfBadgeCountGroupDefault.get() - 1))
case let .newChatItems(user, chatItems):
// Received items are created one at a time
if let chatItem = chatItems.first {
let cInfo = chatItem.chatInfo
var cItem = chatItem.chatItem
if !cInfo.ntfsEnabled {
ntfBadgeCountGroupDefault.set(max(0, ntfBadgeCountGroupDefault.get() - 1))
}
if let file = cItem.autoReceiveFile() {
cItem = autoReceiveFile(file) ?? cItem
}
let ntf: NSENotification = cInfo.ntfsEnabled ? .nse(createMessageReceivedNtf(user, cInfo, cItem)) : .empty
return cItem.showNotification ? (chatItem.chatId, ntf) : nil
} else {
return nil
}
if let file = cItem.autoReceiveFile() {
cItem = autoReceiveFile(file) ?? cItem
}
let ntf: NSENotification = cInfo.ntfsEnabled ? .nse(createMessageReceivedNtf(user, cInfo, cItem)) : .empty
return cItem.showNotification ? (aChatItem.chatId, ntf) : nil
case let .rcvFileSndCancelled(_, aChatItem, _):
cleanupFile(aChatItem)
return nil
+13 -15
View File
@@ -54,32 +54,30 @@ func apiGetChats(userId: User.ID) throws -> Array<ChatData> {
throw r
}
func apiSendMessage(
func apiSendMessages(
chatInfo: ChatInfo,
cryptoFile: CryptoFile?,
msgContent: MsgContent
) throws -> AChatItem {
composedMessages: [ComposedMessage]
) throws -> [AChatItem] {
let r = sendSimpleXCmd(
chatInfo.chatType == .local
? .apiCreateChatItem(
? .apiCreateChatItems(
noteFolderId: chatInfo.apiId,
file: cryptoFile,
msg: msgContent
composedMessages: composedMessages
)
: .apiSendMessage(
: .apiSendMessages(
type: chatInfo.chatType,
id: chatInfo.apiId,
file: cryptoFile,
quotedItemId: nil,
msg: msgContent,
live: false,
ttl: nil
ttl: nil,
composedMessages: composedMessages
)
)
if case let .newChatItem(_, chatItem) = r {
return chatItem
if case let .newChatItems(_, chatItems) = r {
return chatItems
} else {
if let filePath = cryptoFile?.filePath { removeFile(filePath) }
for composedMessage in composedMessages {
if let filePath = composedMessage.fileSource?.filePath { removeFile(filePath) }
}
throw r
}
}
+14 -12
View File
@@ -141,23 +141,25 @@ class ShareModel: ObservableObject {
do {
SEChatState.shared.set(.sendingMessage)
await waitForOtherProcessesToSuspend()
let ci = try apiSendMessage(
let chatItems = try apiSendMessages(
chatInfo: selected.chatInfo,
cryptoFile: sharedContent.cryptoFile,
msgContent: sharedContent.msgContent(comment: self.comment)
composedMessages: [ComposedMessage(fileSource: sharedContent.cryptoFile, msgContent: sharedContent.msgContent(comment: self.comment))]
)
if selected.chatInfo.chatType == .local {
completion()
} else {
await MainActor.run { self.bottomBar = .loadingBar(progress: 0) }
if let e = await handleEvents(
isGroupChat: ci.chatInfo.chatType == .group,
isWithoutFile: sharedContent.cryptoFile == nil,
chatItemId: ci.chatItem.id
) {
await MainActor.run { errorAlert = e }
} else {
completion()
// TODO batch send: share multiple items
if let ci = chatItems.first {
await MainActor.run { self.bottomBar = .loadingBar(progress: 0) }
if let e = await handleEvents(
isGroupChat: ci.chatInfo.chatType == .group,
isWithoutFile: sharedContent.cryptoFile == nil,
chatItemId: ci.chatItem.id
) {
await MainActor.run { errorAlert = e }
} else {
completion()
}
}
}
} catch {
@@ -1,7 +1,9 @@
/*
InfoPlist.strings
SimpleX
/* Bundle display name */
"CFBundleDisplayName" = "SimpleX SE";
/* Bundle name */
"CFBundleName" = "SimpleX SE";
/* Copyright (human-readable) */
"NSHumanReadableCopyright" = "Copyright © 2024 SimpleX Chat. Wszelkie prawa zastrzeżone.";
Created by EP on 30/07/2024.
Copyright © 2024 SimpleX Chat. All rights reserved.
*/
@@ -1,7 +1,111 @@
/*
Localizable.strings
SimpleX
/* No comment provided by engineer. */
"%@" = "%@";
/* No comment provided by engineer. */
"App is locked!" = "Aplikacja zablokowana!";
/* No comment provided by engineer. */
"Cancel" = "Anuluj";
/* No comment provided by engineer. */
"Cannot access keychain to save database password" = "Nie można uzyskać dostępu do pęku kluczy aby zapisać hasło do bazy danych";
/* No comment provided by engineer. */
"Cannot forward message" = "Nie można przekazać wiadomości";
/* No comment provided by engineer. */
"Comment" = "Komentarz";
/* No comment provided by engineer. */
"Currently maximum supported file size is %@." = "Obecnie maksymalny obsługiwany rozmiar pliku to %@.";
/* No comment provided by engineer. */
"Database downgrade required" = "Wymagane obniżenie wersji bazy danych";
/* No comment provided by engineer. */
"Database encrypted!" = "Baza danych zaszyfrowana!";
/* No comment provided by engineer. */
"Database error" = "Błąd bazy danych";
/* No comment provided by engineer. */
"Database passphrase is different from saved in the keychain." = "Hasło bazy danych jest inne niż zapisane w pęku kluczy.";
/* No comment provided by engineer. */
"Database passphrase is required to open chat." = "Hasło do bazy danych jest wymagane do otwarcia czatu.";
/* No comment provided by engineer. */
"Database upgrade required" = "Wymagana aktualizacja bazy danych";
/* No comment provided by engineer. */
"Error preparing file" = "Błąd przygotowania pliku";
/* No comment provided by engineer. */
"Error preparing message" = "Błąd przygotowania wiadomości";
/* No comment provided by engineer. */
"Error: %@" = "Błąd: %@";
/* No comment provided by engineer. */
"File error" = "Błąd pliku";
/* No comment provided by engineer. */
"Incompatible database version" = "Niekompatybilna wersja bazy danych";
/* No comment provided by engineer. */
"Invalid migration confirmation" = "Nieprawidłowe potwierdzenie migracji";
/* No comment provided by engineer. */
"Keychain error" = "Błąd pęku kluczy";
/* No comment provided by engineer. */
"Large file!" = "Duży plik!";
/* No comment provided by engineer. */
"No active profile" = "Brak aktywnego profilu";
/* No comment provided by engineer. */
"Ok" = "Ok";
/* No comment provided by engineer. */
"Open the app to downgrade the database." = "Otwórz aplikację aby obniżyć wersję bazy danych.";
/* No comment provided by engineer. */
"Open the app to upgrade the database." = "Otwórz aplikację aby zaktualizować bazę danych.";
/* No comment provided by engineer. */
"Passphrase" = "Hasło";
/* No comment provided by engineer. */
"Please create a profile in the SimpleX app" = "Proszę utworzyć profil w aplikacji SimpleX";
/* No comment provided by engineer. */
"Selected chat preferences prohibit this message." = "Wybrane preferencje czatu zabraniają tej wiadomości.";
/* No comment provided by engineer. */
"Sending a message takes longer than expected." = "Wysłanie wiadomości trwa dłużej niż oczekiwano.";
/* No comment provided by engineer. */
"Sending message…" = "Wysyłanie wiadomości…";
/* No comment provided by engineer. */
"Share" = "Udostępnij";
/* No comment provided by engineer. */
"Slow network?" = "Wolna sieć?";
/* No comment provided by engineer. */
"Unknown database error: %@" = "Nieznany błąd bazy danych: %@";
/* No comment provided by engineer. */
"Unsupported format" = "Niewspierany format";
/* No comment provided by engineer. */
"Wait" = "Czekaj";
/* No comment provided by engineer. */
"Wrong database passphrase" = "Nieprawidłowe hasło bazy danych";
/* No comment provided by engineer. */
"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Możesz zezwolić na udostępnianie w ustawieniach Prywatność i bezpieczeństwo / Blokada SimpleX.";
Created by EP on 30/07/2024.
Copyright © 2024 SimpleX Chat. All rights reserved.
*/
@@ -1,7 +1,9 @@
/*
InfoPlist.strings
SimpleX
/* Bundle display name */
"CFBundleDisplayName" = "SimpleX SE";
/* Bundle name */
"CFBundleName" = "SimpleX SE";
/* Copyright (human-readable) */
"NSHumanReadableCopyright" = "Copyright © 2024 SimpleX Chat. Всі права захищені.";
Created by EP on 30/07/2024.
Copyright © 2024 SimpleX Chat. All rights reserved.
*/
@@ -1,7 +1,111 @@
/*
Localizable.strings
SimpleX
/* No comment provided by engineer. */
"%@" = "%@";
/* No comment provided by engineer. */
"App is locked!" = "Додаток заблоковано!";
/* No comment provided by engineer. */
"Cancel" = "Скасувати";
/* No comment provided by engineer. */
"Cannot access keychain to save database password" = "Не вдається отримати доступ до зв'язки ключів для збереження пароля до бази даних";
/* No comment provided by engineer. */
"Cannot forward message" = "Неможливо переслати повідомлення";
/* No comment provided by engineer. */
"Comment" = "Коментар";
/* No comment provided by engineer. */
"Currently maximum supported file size is %@." = "Наразі максимальний підтримуваний розмір файлу - %@.";
/* No comment provided by engineer. */
"Database downgrade required" = "Потрібне оновлення бази даних";
/* No comment provided by engineer. */
"Database encrypted!" = "База даних зашифрована!";
/* No comment provided by engineer. */
"Database error" = "Помилка в базі даних";
/* No comment provided by engineer. */
"Database passphrase is different from saved in the keychain." = "Парольна фраза бази даних відрізняється від збереженої у в’язці ключів.";
/* No comment provided by engineer. */
"Database passphrase is required to open chat." = "Для відкриття чату потрібно ввести пароль до бази даних.";
/* No comment provided by engineer. */
"Database upgrade required" = "Потрібне оновлення бази даних";
/* No comment provided by engineer. */
"Error preparing file" = "Помилка підготовки файлу";
/* No comment provided by engineer. */
"Error preparing message" = "Повідомлення про підготовку до помилки";
/* No comment provided by engineer. */
"Error: %@" = "Помилка: %@";
/* No comment provided by engineer. */
"File error" = "Помилка файлу";
/* No comment provided by engineer. */
"Incompatible database version" = "Несумісна версія бази даних";
/* No comment provided by engineer. */
"Invalid migration confirmation" = "Недійсне підтвердження міграції";
/* No comment provided by engineer. */
"Keychain error" = "Помилка зв'язки ключів";
/* No comment provided by engineer. */
"Large file!" = "Великий файл!";
/* No comment provided by engineer. */
"No active profile" = "Немає активного профілю";
/* No comment provided by engineer. */
"Ok" = "Гаразд";
/* No comment provided by engineer. */
"Open the app to downgrade the database." = "Відкрийте програму, щоб знизити версію бази даних.";
/* No comment provided by engineer. */
"Open the app to upgrade the database." = "Відкрийте програму, щоб оновити базу даних.";
/* No comment provided by engineer. */
"Passphrase" = "Парольна фраза";
/* No comment provided by engineer. */
"Please create a profile in the SimpleX app" = "Будь ласка, створіть профіль у додатку SimpleX";
/* No comment provided by engineer. */
"Selected chat preferences prohibit this message." = "Вибрані налаштування чату забороняють це повідомлення.";
/* No comment provided by engineer. */
"Sending a message takes longer than expected." = "Надсилання повідомлення займає більше часу, ніж очікувалося.";
/* No comment provided by engineer. */
"Sending message…" = "Надсилаю повідомлення…";
/* No comment provided by engineer. */
"Share" = "Поділіться";
/* No comment provided by engineer. */
"Slow network?" = "Повільна мережа?";
/* No comment provided by engineer. */
"Unknown database error: %@" = "Невідома помилка бази даних: %@";
/* No comment provided by engineer. */
"Unsupported format" = "Непідтримуваний формат";
/* No comment provided by engineer. */
"Wait" = "Зачекай";
/* No comment provided by engineer. */
"Wrong database passphrase" = "Неправильна ключова фраза до бази даних";
/* No comment provided by engineer. */
"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Ви можете дозволити спільний доступ у налаштуваннях Конфіденційність і безпека / SimpleX Lock.";
Created by EP on 30/07/2024.
Copyright © 2024 SimpleX Chat. All rights reserved.
*/
+40 -40
View File
@@ -214,11 +214,11 @@
D77B92DC2952372200A5A1CC /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = D77B92DB2952372200A5A1CC /* SwiftyGif */; };
D7F0E33929964E7E0068AF69 /* LZString in Frameworks */ = {isa = PBXBuildFile; productRef = D7F0E33829964E7E0068AF69 /* LZString */; };
E51CC1E62C62085600DB91FE /* OneHandUICard.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51CC1E52C62085600DB91FE /* OneHandUICard.swift */; };
E51ED5762C7691A2009F2C7C /* libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51ED5712C7691A2009F2C7C /* libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy.a */; };
E51ED5772C7691A2009F2C7C /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51ED5722C7691A2009F2C7C /* libgmp.a */; };
E51ED5782C7691A2009F2C7C /* libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51ED5732C7691A2009F2C7C /* libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy-ghc9.6.3.a */; };
E51ED5792C7691A2009F2C7C /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51ED5742C7691A2009F2C7C /* libgmpxx.a */; };
E51ED57A2C7691A2009F2C7C /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51ED5752C7691A2009F2C7C /* libffi.a */; };
E51ED5802C78BF95009F2C7C /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51ED57B2C78BF95009F2C7C /* libgmpxx.a */; };
E51ED5812C78BF95009F2C7C /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51ED57C2C78BF95009F2C7C /* libgmp.a */; };
E51ED5822C78BF95009F2C7C /* libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51ED57D2C78BF95009F2C7C /* libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA.a */; };
E51ED5832C78BF95009F2C7C /* libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51ED57E2C78BF95009F2C7C /* libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA-ghc9.6.3.a */; };
E51ED5842C78BF95009F2C7C /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51ED57F2C78BF95009F2C7C /* libffi.a */; };
E5DCF8DB2C56FAC1007928CC /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; };
E5DCF9712C590272007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF96F2C590272007928CC /* Localizable.strings */; };
E5DCF9842C5902CE007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9822C5902CE007928CC /* Localizable.strings */; };
@@ -550,11 +550,11 @@
D741547929AF90B00022400A /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/PushKit.framework; sourceTree = DEVELOPER_DIR; };
D7AA2C3429A936B400737B40 /* MediaEncryption.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; name = MediaEncryption.playground; path = Shared/MediaEncryption.playground; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
E51CC1E52C62085600DB91FE /* OneHandUICard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OneHandUICard.swift; sourceTree = "<group>"; };
E51ED5712C7691A2009F2C7C /* libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy.a"; sourceTree = "<group>"; };
E51ED5722C7691A2009F2C7C /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
E51ED5732C7691A2009F2C7C /* libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy-ghc9.6.3.a"; sourceTree = "<group>"; };
E51ED5742C7691A2009F2C7C /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
E51ED5752C7691A2009F2C7C /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
E51ED57B2C78BF95009F2C7C /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
E51ED57C2C78BF95009F2C7C /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
E51ED57D2C78BF95009F2C7C /* libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA.a"; sourceTree = "<group>"; };
E51ED57E2C78BF95009F2C7C /* libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA-ghc9.6.3.a"; sourceTree = "<group>"; };
E51ED57F2C78BF95009F2C7C /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
E5DCF9702C590272007928CC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
E5DCF9722C590274007928CC /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Localizable.strings; sourceTree = "<group>"; };
E5DCF9732C590275007928CC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
@@ -645,14 +645,14 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E51ED5802C78BF95009F2C7C /* libgmpxx.a in Frameworks */,
E51ED5812C78BF95009F2C7C /* libgmp.a in Frameworks */,
E51ED5822C78BF95009F2C7C /* libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA.a in Frameworks */,
E51ED5842C78BF95009F2C7C /* libffi.a in Frameworks */,
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
E51ED5772C7691A2009F2C7C /* libgmp.a in Frameworks */,
E51ED5762C7691A2009F2C7C /* libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy.a in Frameworks */,
E51ED57A2C7691A2009F2C7C /* libffi.a in Frameworks */,
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
E51ED5782C7691A2009F2C7C /* libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy-ghc9.6.3.a in Frameworks */,
E51ED5792C7691A2009F2C7C /* libgmpxx.a in Frameworks */,
E51ED5832C78BF95009F2C7C /* libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA-ghc9.6.3.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -729,11 +729,11 @@
5C764E5C279C70B7000C6508 /* Libraries */ = {
isa = PBXGroup;
children = (
E51ED5752C7691A2009F2C7C /* libffi.a */,
E51ED5722C7691A2009F2C7C /* libgmp.a */,
E51ED5742C7691A2009F2C7C /* libgmpxx.a */,
E51ED5732C7691A2009F2C7C /* libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy-ghc9.6.3.a */,
E51ED5712C7691A2009F2C7C /* libHSsimplex-chat-6.0.2.0-CUdJmkNQ3mRF4AChEwYJvy.a */,
E51ED57F2C78BF95009F2C7C /* libffi.a */,
E51ED57C2C78BF95009F2C7C /* libgmp.a */,
E51ED57B2C78BF95009F2C7C /* libgmpxx.a */,
E51ED57E2C78BF95009F2C7C /* libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA-ghc9.6.3.a */,
E51ED57D2C78BF95009F2C7C /* libHSsimplex-chat-6.1.0.0-29ba1DCA1ro2ZCUgGLJUlA.a */,
);
path = Libraries;
sourceTree = "<group>";
@@ -1879,7 +1879,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 233;
CURRENT_PROJECT_VERSION = 234;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
@@ -1904,7 +1904,7 @@
"@executable_path/Frameworks",
);
LLVM_LTO = YES_THIN;
MARKETING_VERSION = 6.0.1;
MARKETING_VERSION = 6.0.2;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos;
@@ -1928,7 +1928,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 233;
CURRENT_PROJECT_VERSION = 234;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
@@ -1953,7 +1953,7 @@
"@executable_path/Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.0.1;
MARKETING_VERSION = 6.0.2;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos;
@@ -1969,11 +1969,11 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 233;
CURRENT_PROJECT_VERSION = 234;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 6.0.1;
MARKETING_VERSION = 6.0.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -1989,11 +1989,11 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 233;
CURRENT_PROJECT_VERSION = 234;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 6.0.1;
MARKETING_VERSION = 6.0.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -2014,7 +2014,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 233;
CURRENT_PROJECT_VERSION = 234;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = s;
@@ -2029,7 +2029,7 @@
"@executable_path/../../Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.0.1;
MARKETING_VERSION = 6.0.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2051,7 +2051,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 233;
CURRENT_PROJECT_VERSION = 234;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_CODE_COVERAGE = NO;
@@ -2066,7 +2066,7 @@
"@executable_path/../../Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.0.1;
MARKETING_VERSION = 6.0.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2088,7 +2088,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 233;
CURRENT_PROJECT_VERSION = 234;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2114,7 +2114,7 @@
"$(PROJECT_DIR)/Libraries/sim",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.0.1;
MARKETING_VERSION = 6.0.2;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
@@ -2139,7 +2139,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 233;
CURRENT_PROJECT_VERSION = 234;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2165,7 +2165,7 @@
"$(PROJECT_DIR)/Libraries/sim",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.0.1;
MARKETING_VERSION = 6.0.2;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
@@ -2190,7 +2190,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 233;
CURRENT_PROJECT_VERSION = 234;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
@@ -2205,7 +2205,7 @@
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.0.1;
MARKETING_VERSION = 6.0.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -2224,7 +2224,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 233;
CURRENT_PROJECT_VERSION = 234;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
@@ -2239,7 +2239,7 @@
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.0.1;
MARKETING_VERSION = 6.0.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
+34 -20
View File
@@ -42,13 +42,13 @@ public enum ChatCommand {
case apiGetChats(userId: Int64)
case apiGetChat(type: ChatType, id: Int64, pagination: ChatPagination, search: String)
case apiGetChatItemInfo(type: ChatType, id: Int64, itemId: Int64)
case apiSendMessage(type: ChatType, id: Int64, file: CryptoFile?, quotedItemId: Int64?, msg: MsgContent, live: Bool, ttl: Int?)
case apiCreateChatItem(noteFolderId: Int64, file: CryptoFile?, msg: MsgContent)
case apiSendMessages(type: ChatType, id: Int64, live: Bool, ttl: Int?, composedMessages: [ComposedMessage])
case apiCreateChatItems(noteFolderId: Int64, composedMessages: [ComposedMessage])
case apiUpdateChatItem(type: ChatType, id: Int64, itemId: Int64, msg: MsgContent, live: Bool)
case apiDeleteChatItem(type: ChatType, id: Int64, itemIds: [Int64], mode: CIDeleteMode)
case apiDeleteMemberChatItem(groupId: Int64, itemIds: [Int64])
case apiChatItemReaction(type: ChatType, id: Int64, itemId: Int64, add: Bool, reaction: MsgReaction)
case apiForwardChatItem(toChatType: ChatType, toChatId: Int64, fromChatType: ChatType, fromChatId: Int64, itemId: Int64, ttl: Int?)
case apiForwardChatItems(toChatType: ChatType, toChatId: Int64, fromChatType: ChatType, fromChatId: Int64, itemIds: [Int64], ttl: Int?)
case apiGetNtfToken
case apiRegisterToken(token: DeviceToken, notificationMode: NotificationsMode)
case apiVerifyToken(token: DeviceToken, nonce: String, code: String)
@@ -97,6 +97,7 @@ public enum ChatCommand {
case apiVerifyGroupMember(groupId: Int64, groupMemberId: Int64, connectionCode: String?)
case apiAddContact(userId: Int64, incognito: Bool)
case apiSetConnectionIncognito(connId: Int64, incognito: Bool)
case apiChangeConnectionUser(connId: Int64, userId: Int64)
case apiConnectPlan(userId: Int64, connReq: String)
case apiConnect(userId: Int64, incognito: Bool, connReq: String)
case apiConnectContactViaAddress(userId: Int64, incognito: Bool, contactId: Int64)
@@ -190,20 +191,20 @@ public enum ChatCommand {
case let .apiGetChat(type, id, pagination, search): return "/_get chat \(ref(type, id)) \(pagination.cmdString)" +
(search == "" ? "" : " search=\(search)")
case let .apiGetChatItemInfo(type, id, itemId): return "/_get item info \(ref(type, id)) \(itemId)"
case let .apiSendMessage(type, id, file, quotedItemId, mc, live, ttl):
let msg = encodeJSON(ComposedMessage(fileSource: file, quotedItemId: quotedItemId, msgContent: mc))
case let .apiSendMessages(type, id, live, ttl, composedMessages):
let msgs = encodeJSON(composedMessages)
let ttlStr = ttl != nil ? "\(ttl!)" : "default"
return "/_send \(ref(type, id)) live=\(onOff(live)) ttl=\(ttlStr) json \(msg)"
case let .apiCreateChatItem(noteFolderId, file, mc):
let msg = encodeJSON(ComposedMessage(fileSource: file, msgContent: mc))
return "/_create *\(noteFolderId) json \(msg)"
return "/_send \(ref(type, id)) live=\(onOff(live)) ttl=\(ttlStr) json \(msgs)"
case let .apiCreateChatItems(noteFolderId, composedMessages):
let msgs = encodeJSON(composedMessages)
return "/_create *\(noteFolderId) json \(msgs)"
case let .apiUpdateChatItem(type, id, itemId, mc, live): return "/_update item \(ref(type, id)) \(itemId) live=\(onOff(live)) \(mc.cmdString)"
case let .apiDeleteChatItem(type, id, itemIds, mode): return "/_delete item \(ref(type, id)) \(itemIds.map({ "\($0)" }).joined(separator: ",")) \(mode.rawValue)"
case let .apiDeleteMemberChatItem(groupId, itemIds): return "/_delete member item #\(groupId) \(itemIds.map({ "\($0)" }).joined(separator: ","))"
case let .apiChatItemReaction(type, id, itemId, add, reaction): return "/_reaction \(ref(type, id)) \(itemId) \(onOff(add)) \(encodeJSON(reaction))"
case let .apiForwardChatItem(toChatType, toChatId, fromChatType, fromChatId, itemId, ttl):
case let .apiForwardChatItems(toChatType, toChatId, fromChatType, fromChatId, itemIds, ttl):
let ttlStr = ttl != nil ? "\(ttl!)" : "default"
return "/_forward \(ref(toChatType, toChatId)) \(ref(fromChatType, fromChatId)) \(itemId) ttl=\(ttlStr)"
return "/_forward \(ref(toChatType, toChatId)) \(ref(fromChatType, fromChatId)) \(itemIds.map({ "\($0)" }).joined(separator: ",")) ttl=\(ttlStr)"
case .apiGetNtfToken: return "/_ntf get "
case let .apiRegisterToken(token, notificationMode): return "/_ntf register \(token.cmdString) \(notificationMode.rawValue)"
case let .apiVerifyToken(token, nonce, code): return "/_ntf verify \(token.cmdString) \(nonce) \(code)"
@@ -262,6 +263,7 @@ public enum ChatCommand {
case let .apiVerifyGroupMember(groupId, groupMemberId, .none): return "/_verify code #\(groupId) \(groupMemberId)"
case let .apiAddContact(userId, incognito): return "/_connect \(userId) incognito=\(onOff(incognito))"
case let .apiSetConnectionIncognito(connId, incognito): return "/_set incognito :\(connId) \(onOff(incognito))"
case let .apiChangeConnectionUser(connId, userId): return "/_set conn user :\(connId) \(userId)"
case let .apiConnectPlan(userId, connReq): return "/_connect plan \(userId) \(connReq)"
case let .apiConnect(userId, incognito, connReq): return "/_connect \(userId) incognito=\(onOff(incognito)) \(connReq)"
case let .apiConnectContactViaAddress(userId, incognito, contactId): return "/_connect contact \(userId) incognito=\(onOff(incognito)) \(contactId)"
@@ -347,14 +349,14 @@ public enum ChatCommand {
case .apiGetChats: return "apiGetChats"
case .apiGetChat: return "apiGetChat"
case .apiGetChatItemInfo: return "apiGetChatItemInfo"
case .apiSendMessage: return "apiSendMessage"
case .apiCreateChatItem: return "apiCreateChatItem"
case .apiSendMessages: return "apiSendMessages"
case .apiCreateChatItems: return "apiCreateChatItems"
case .apiUpdateChatItem: return "apiUpdateChatItem"
case .apiDeleteChatItem: return "apiDeleteChatItem"
case .apiConnectContactViaAddress: return "apiConnectContactViaAddress"
case .apiDeleteMemberChatItem: return "apiDeleteMemberChatItem"
case .apiChatItemReaction: return "apiChatItemReaction"
case .apiForwardChatItem: return "apiForwardChatItem"
case .apiForwardChatItems: return "apiForwardChatItems"
case .apiGetNtfToken: return "apiGetNtfToken"
case .apiRegisterToken: return "apiRegisterToken"
case .apiVerifyToken: return "apiVerifyToken"
@@ -403,6 +405,7 @@ public enum ChatCommand {
case .apiVerifyGroupMember: return "apiVerifyGroupMember"
case .apiAddContact: return "apiAddContact"
case .apiSetConnectionIncognito: return "apiSetConnectionIncognito"
case .apiChangeConnectionUser: return "apiChangeConnectionUser"
case .apiConnectPlan: return "apiConnectPlan"
case .apiConnect: return "apiConnect"
case .apiDeleteChat: return "apiDeleteChat"
@@ -555,6 +558,7 @@ public enum ChatResponse: Decodable, Error {
case connectionVerified(user: UserRef, verified: Bool, expectedCode: String)
case invitation(user: UserRef, connReqInvitation: String, connection: PendingContactConnection)
case connectionIncognitoUpdated(user: UserRef, toConnection: PendingContactConnection)
case connectionUserChanged(user: UserRef, fromConnection: PendingContactConnection, toConnection: PendingContactConnection, newUser: UserRef)
case connectionPlan(user: UserRef, connectionPlan: ConnectionPlan)
case sentConfirmation(user: UserRef, connection: PendingContactConnection)
case sentInvitation(user: UserRef, connection: PendingContactConnection)
@@ -588,7 +592,7 @@ public enum ChatResponse: Decodable, Error {
case memberSubErrors(user: UserRef, memberSubErrors: [MemberSubError])
case groupEmpty(user: UserRef, groupInfo: GroupInfo)
case userContactLinkSubscribed
case newChatItem(user: UserRef, chatItem: AChatItem)
case newChatItems(user: UserRef, chatItems: [AChatItem])
case chatItemStatusUpdated(user: UserRef, chatItem: AChatItem)
case chatItemUpdated(user: UserRef, chatItem: AChatItem)
case chatItemNotChanged(user: UserRef, chatItem: AChatItem)
@@ -725,6 +729,7 @@ public enum ChatResponse: Decodable, Error {
case .connectionVerified: return "connectionVerified"
case .invitation: return "invitation"
case .connectionIncognitoUpdated: return "connectionIncognitoUpdated"
case .connectionUserChanged: return "connectionUserChanged"
case .connectionPlan: return "connectionPlan"
case .sentConfirmation: return "sentConfirmation"
case .sentInvitation: return "sentInvitation"
@@ -758,7 +763,7 @@ public enum ChatResponse: Decodable, Error {
case .memberSubErrors: return "memberSubErrors"
case .groupEmpty: return "groupEmpty"
case .userContactLinkSubscribed: return "userContactLinkSubscribed"
case .newChatItem: return "newChatItem"
case .newChatItems: return "newChatItems"
case .chatItemStatusUpdated: return "chatItemStatusUpdated"
case .chatItemUpdated: return "chatItemUpdated"
case .chatItemNotChanged: return "chatItemNotChanged"
@@ -893,6 +898,7 @@ public enum ChatResponse: Decodable, Error {
case let .connectionVerified(u, verified, expectedCode): return withUser(u, "verified: \(verified)\nconnectionCode: \(expectedCode)")
case let .invitation(u, connReqInvitation, connection): return withUser(u, "connReqInvitation: \(connReqInvitation)\nconnection: \(connection)")
case let .connectionIncognitoUpdated(u, toConnection): return withUser(u, String(describing: toConnection))
case let .connectionUserChanged(u, fromConnection, toConnection, newUser): return withUser(u, "fromConnection: \(String(describing: fromConnection))\ntoConnection: \(String(describing: toConnection))\newUserId: \(String(describing: newUser.userId))")
case let .connectionPlan(u, connectionPlan): return withUser(u, String(describing: connectionPlan))
case let .sentConfirmation(u, connection): return withUser(u, String(describing: connection))
case let .sentInvitation(u, connection): return withUser(u, String(describing: connection))
@@ -926,7 +932,9 @@ public enum ChatResponse: Decodable, Error {
case let .memberSubErrors(u, memberSubErrors): return withUser(u, String(describing: memberSubErrors))
case let .groupEmpty(u, groupInfo): return withUser(u, String(describing: groupInfo))
case .userContactLinkSubscribed: return noDetails
case let .newChatItem(u, chatItem): return withUser(u, String(describing: chatItem))
case let .newChatItems(u, chatItems):
let itemsString = chatItems.map { chatItem in String(describing: chatItem) }.joined(separator: "\n")
return withUser(u, itemsString)
case let .chatItemStatusUpdated(u, chatItem): return withUser(u, String(describing: chatItem))
case let .chatItemUpdated(u, chatItem): return withUser(u, String(describing: chatItem))
case let .chatItemNotChanged(u, chatItem): return withUser(u, String(describing: chatItem))
@@ -1113,10 +1121,16 @@ public enum ChatPagination: Hashable {
}
}
struct ComposedMessage: Encodable {
var fileSource: CryptoFile?
public struct ComposedMessage: Encodable {
public var fileSource: CryptoFile?
var quotedItemId: Int64?
var msgContent: MsgContent
public init(fileSource: CryptoFile? = nil, quotedItemId: Int64? = nil, msgContent: MsgContent) {
self.fileSource = fileSource
self.quotedItemId = quotedItemId
self.msgContent = msgContent
}
}
public struct ArchiveConfig: Encodable {
@@ -1842,7 +1856,6 @@ public enum ChatErrorType: Decodable, Hashable {
case inlineFileProhibited(fileId: Int64)
case invalidQuote
case invalidForward
case forwardNoFile
case invalidChatItemUpdate
case invalidChatItemDelete
case hasCurrentCall
@@ -1857,6 +1870,7 @@ public enum ChatErrorType: Decodable, Hashable {
case agentCommandError(message: String)
case invalidFileDescription(message: String)
case connectionIncognitoChangeProhibited
case connectionUserChangeProhibited
case peerChatVRangeIncompatible
case internalError(message: String)
case exception(message: String)
+5 -5
View File
@@ -506,7 +506,7 @@
"Allow to send files and media." = "Se permite enviar archivos y multimedia.";
/* No comment provided by engineer. */
"Allow to send SimpleX links." = "Permitir enviar enlaces SimpleX.";
"Allow to send SimpleX links." = "Se permite enviar enlaces SimpleX.";
/* No comment provided by engineer. */
"Allow to send voice messages." = "Permites enviar mensajes de voz.";
@@ -1606,7 +1606,7 @@
"Do it later" = "Hacer más tarde";
/* No comment provided by engineer. */
"Do not send history to new members." = "No enviar historial a miembros nuevos.";
"Do not send history to new members." = "No se envía el historial a los miembros nuevos.";
/* No comment provided by engineer. */
"Do NOT send messages directly, even if your or destination server does not support private routing." = "NO enviar mensajes directamente incluso si tu servidor o el de destino no soportan enrutamiento privado.";
@@ -3415,7 +3415,7 @@
"Prohibit sending files and media." = "No permitir el envío de archivos y multimedia.";
/* No comment provided by engineer. */
"Prohibit sending SimpleX links." = "No permitir el envío de enlaces SimpleX.";
"Prohibit sending SimpleX links." = "No se permite enviar enlaces SimpleX.";
/* No comment provided by engineer. */
"Prohibit sending voice messages." = "No se permiten mensajes de voz.";
@@ -3917,7 +3917,7 @@
"Send them from gallery or custom keyboards." = "Envíalos desde la galería o desde teclados personalizados.";
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "Enviar hasta 100 últimos mensajes a los miembros nuevos.";
"Send up to 100 last messages to new members." = "Se envían hasta 100 mensajes más recientes a los miembros nuevos.";
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "El remitente ha cancelado la transferencia de archivos.";
@@ -4979,7 +4979,7 @@
"You can accept calls from lock screen, without device and app authentication." = "Puede aceptar llamadas desde la pantalla de bloqueo, sin autenticación de dispositivos y aplicaciones.";
/* No comment provided by engineer. */
"You can change it in Appearance settings." = "Puede cambiarlo desde el menú Apariencia.";
"You can change it in Appearance settings." = "Puedes cambiar la posición de la barra desde el menú Apariencia.";
/* No comment provided by engineer. */
"You can create it later" = "Puedes crearla más tarde";
+10 -10
View File
@@ -659,10 +659,10 @@
"Bad desktop address" = "Hibás számítógép cím";
/* integrity error chat item */
"bad message hash" = "téves üzenet hash";
"bad message hash" = "hibás az üzenet ellenőrzőösszege";
/* No comment provided by engineer. */
"Bad message hash" = "Téves üzenet hash";
"Bad message hash" = "Hibás az üzenet ellenőrzőösszege";
/* integrity error chat item */
"bad message ID" = "téves üzenet ID";
@@ -1432,7 +1432,7 @@
"Delete link?" = "Hivatkozás törlése?";
/* No comment provided by engineer. */
"Delete member message?" = "Csoporttag üzenet törlése?";
"Delete member message?" = "Csoporttag üzenetének törlése?";
/* No comment provided by engineer. */
"Delete message?" = "Üzenet törlése?";
@@ -1495,7 +1495,7 @@
"Delivery receipts are disabled!" = "A kézbesítési jelentések ki vannak kapcsolva!";
/* No comment provided by engineer. */
"Delivery receipts!" = "Kézbesítési igazolások!";
"Delivery receipts!" = "Üzenet kézbesítési jelentések!";
/* No comment provided by engineer. */
"Description" = "Leírás";
@@ -1828,10 +1828,10 @@
"Enter this device name…" = "Eszköznév megadása…";
/* placeholder */
"Enter welcome message…" = "Üdvözlő üzenetet megadása…";
"Enter welcome message…" = "Üdvözlő üzenet megadása…";
/* placeholder */
"Enter welcome message… (optional)" = "Üdvözlő üzenetet megadása… (opcionális)";
"Enter welcome message… (optional)" = "Üdvözlő üzenet megadása… (opcionális)";
/* No comment provided by engineer. */
"Enter your name…" = "Adjon meg egy nevet…";
@@ -2783,7 +2783,7 @@
"Message delivery error" = "Üzenetkézbesítési hiba";
/* No comment provided by engineer. */
"Message delivery receipts!" = "Üzenetkézbesítési bizonylatok!";
"Message delivery receipts!" = "Üzenet kézbesítési jelentések!";
/* item status text */
"Message delivery warning" = "Üzenet kézbesítési figyelmeztetés";
@@ -2813,7 +2813,7 @@
"message received" = "üzenet érkezett";
/* No comment provided by engineer. */
"Message reception" = "Üzenetjelentés";
"Message reception" = "Üzenet kézbesítési jelentés";
/* No comment provided by engineer. */
"Message servers" = "Üzenetkiszolgálók";
@@ -3605,7 +3605,7 @@
"removed" = "eltávolítva";
/* rcv group event chat item */
"removed %@" = "%@ eltávolítva";
"removed %@" = "eltávolította őt: %@";
/* profile update event chat item */
"removed contact address" = "törölt kapcsolattartási cím";
@@ -4373,7 +4373,7 @@
"The encryption is working and the new encryption agreement is not required. It may result in connection errors!" = "A titkosítás működik, és új titkosítási egyezményre nincs szükség. Ez kapcsolati hibákat eredményezhet!";
/* No comment provided by engineer. */
"The hash of the previous message is different." = "Az előző üzenet hash-e más.";
"The hash of the previous message is different." = "Az előző üzenet ellenőrzőösszege különbözik.";
/* No comment provided by engineer. */
"The ID of the next message is incorrect (less or equal to the previous).\nIt can happen because of some bug or when the connection is compromised." = "A következő üzenet azonosítója hibás (kisebb vagy egyenlő az előzővel).\nEz valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.";
+1 -1
View File
@@ -1089,7 +1089,7 @@
"Connection" = "Connessione";
/* No comment provided by engineer. */
"Connection and servers status." = "Stato di connessione e server.";
"Connection and servers status." = "Stato della connessione e dei server.";
/* No comment provided by engineer. */
"Connection error" = "Errore di connessione";
+1 -1
View File
@@ -2630,7 +2630,7 @@
"Keep" = "Bewaar";
/* No comment provided by engineer. */
"Keep conversation" = "Blijf in gesprek";
"Keep conversation" = "Behoud het gesprek";
/* No comment provided by engineer. */
"Keep the app open to use it from desktop" = "Houd de app geopend om deze vanaf de desktop te gebruiken";
+234
View File
@@ -472,6 +472,9 @@
/* No comment provided by engineer. */
"Allow calls only if your contact allows them." = "Zezwalaj na połączenia tylko wtedy, gdy Twój kontakt na to pozwala.";
/* No comment provided by engineer. */
"Allow calls?" = "Zezwolić na połączenia?";
/* No comment provided by engineer. */
"Allow disappearing messages only if your contact allows it to you." = "Zezwól na znikające wiadomości tylko wtedy, gdy Twój kontakt Ci na to pozwoli.";
@@ -493,6 +496,9 @@
/* No comment provided by engineer. */
"Allow sending disappearing messages." = "Zezwól na wysyłanie znikających wiadomości.";
/* No comment provided by engineer. */
"Allow sharing" = "Zezwól na udostępnianie";
/* No comment provided by engineer. */
"Allow to irreversibly delete sent messages. (24 hours)" = "Zezwól na nieodwracalne usunięcie wysłanych wiadomości. (24 godziny)";
@@ -589,6 +595,12 @@
/* No comment provided by engineer. */
"Archive and upload" = "Archiwizuj i prześlij";
/* No comment provided by engineer. */
"Archive contacts to chat later." = "Archiwizuj kontakty aby porozmawiać później.";
/* No comment provided by engineer. */
"Archived contacts" = "Zarchiwizowane kontakty";
/* No comment provided by engineer. */
"Archiving database" = "Archiwizowanie bazy danych";
@@ -664,6 +676,9 @@
/* No comment provided by engineer. */
"Better messages" = "Lepsze wiadomości";
/* No comment provided by engineer. */
"Better networking" = "Lepsze sieciowanie";
/* No comment provided by engineer. */
"Black" = "Czarny";
@@ -697,6 +712,12 @@
/* No comment provided by engineer. */
"Blocked by admin" = "Zablokowany przez admina";
/* No comment provided by engineer. */
"Blur for better privacy." = "Rozmycie dla lepszej prywatności.";
/* No comment provided by engineer. */
"Blur media" = "Rozmycie mediów";
/* No comment provided by engineer. */
"bold" = "pogrubiona";
@@ -721,6 +742,9 @@
/* No comment provided by engineer. */
"By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)." = "Według profilu czatu (domyślnie) lub [według połączenia](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).";
/* No comment provided by engineer. */
"call" = "zadzwoń";
/* No comment provided by engineer. */
"Call already ended!" = "Połączenie już zakończone!";
@@ -736,15 +760,27 @@
/* No comment provided by engineer. */
"Calls" = "Połączenia";
/* No comment provided by engineer. */
"Calls prohibited!" = "Połączenia zakazane!";
/* No comment provided by engineer. */
"Camera not available" = "Kamera nie dostępna";
/* No comment provided by engineer. */
"Can't call contact" = "Nie można zadzwonić do kontaktu";
/* No comment provided by engineer. */
"Can't call member" = "Nie można zadzwonić do członka";
/* No comment provided by engineer. */
"Can't invite contact!" = "Nie można zaprosić kontaktu!";
/* No comment provided by engineer. */
"Can't invite contacts!" = "Nie można zaprosić kontaktów!";
/* No comment provided by engineer. */
"Can't message member" = "Nie można wysłać wiadomości do członka";
/* No comment provided by engineer. */
"Cancel" = "Anuluj";
@@ -830,6 +866,9 @@
/* No comment provided by engineer. */
"Chat database deleted" = "Baza danych czatu usunięta";
/* No comment provided by engineer. */
"Chat database exported" = "Wyeksportowano bazę danych czatu";
/* No comment provided by engineer. */
"Chat database imported" = "Zaimportowano bazę danych czatu";
@@ -842,6 +881,9 @@
/* No comment provided by engineer. */
"Chat is stopped. If you already used this database on another device, you should transfer it back before starting chat." = "Czat został zatrzymany. Jeśli korzystałeś już z tej bazy danych na innym urządzeniu, powinieneś przenieść ją z powrotem przed rozpoczęciem czatu.";
/* No comment provided by engineer. */
"Chat list" = "Lista czatów";
/* No comment provided by engineer. */
"Chat migrated!" = "Czat zmigrowany!";
@@ -893,6 +935,9 @@
/* No comment provided by engineer. */
"Clear verification" = "Wyczyść weryfikację";
/* No comment provided by engineer. */
"Color chats with the new themes." = "Koloruj czaty z nowymi motywami.";
/* No comment provided by engineer. */
"Color mode" = "Tryb koloru";
@@ -920,6 +965,9 @@
/* No comment provided by engineer. */
"Confirm" = "Potwierdź";
/* No comment provided by engineer. */
"Confirm contact deletion?" = "Potwierdzić usunięcie kontaktu?";
/* No comment provided by engineer. */
"Confirm database upgrades" = "Potwierdź aktualizacje bazy danych";
@@ -959,6 +1007,9 @@
/* No comment provided by engineer. */
"connect to SimpleX Chat developers." = "połącz się z deweloperami SimpleX Chat.";
/* No comment provided by engineer. */
"Connect to your friends faster." = "Szybciej łącz się ze znajomymi.";
/* No comment provided by engineer. */
"Connect to yourself?" = "Połączyć się ze sobą?";
@@ -1025,6 +1076,9 @@
/* No comment provided by engineer. */
"Connecting server… (error: %@)" = "Łączenie z serwerem... (błąd: %@)";
/* No comment provided by engineer. */
"Connecting to contact, please wait or check later!" = "Łączenie z kontaktem, poczekaj lub sprawdź później!";
/* No comment provided by engineer. */
"Connecting to desktop" = "Łączenie z komputerem";
@@ -1034,6 +1088,9 @@
/* No comment provided by engineer. */
"Connection" = "Połączenie";
/* No comment provided by engineer. */
"Connection and servers status." = "Stan połączenia i serwerów.";
/* No comment provided by engineer. */
"Connection error" = "Błąd połączenia";
@@ -1043,6 +1100,9 @@
/* chat list item title (it should not be shown */
"connection established" = "połączenie ustanowione";
/* No comment provided by engineer. */
"Connection notifications" = "Powiadomienia o połączeniu";
/* No comment provided by engineer. */
"Connection request sent!" = "Prośba o połączenie wysłana!";
@@ -1070,6 +1130,9 @@
/* No comment provided by engineer. */
"Contact already exists" = "Kontakt już istnieje";
/* No comment provided by engineer. */
"Contact deleted!" = "Kontakt usunięty!";
/* No comment provided by engineer. */
"contact has e2e encryption" = "kontakt posiada szyfrowanie e2e";
@@ -1082,12 +1145,18 @@
/* notification */
"Contact is connected" = "Kontakt jest połączony";
/* No comment provided by engineer. */
"Contact is deleted." = "Kontakt jest usunięty.";
/* No comment provided by engineer. */
"Contact name" = "Nazwa kontaktu";
/* No comment provided by engineer. */
"Contact preferences" = "Preferencje kontaktu";
/* No comment provided by engineer. */
"Contact will be deleted - this cannot be undone!" = "Kontakt zostanie usunięty nie można tego cofnąć!";
/* No comment provided by engineer. */
"Contacts" = "Kontakty";
@@ -1097,6 +1166,9 @@
/* No comment provided by engineer. */
"Continue" = "Kontynuuj";
/* No comment provided by engineer. */
"Conversation deleted!" = "Rozmowa usunięta!";
/* No comment provided by engineer. */
"Copy" = "Kopiuj";
@@ -1281,6 +1353,9 @@
swipe action */
"Delete" = "Usuń";
/* No comment provided by engineer. */
"Delete %lld messages of members?" = "Usunąć %lld wiadomości członków?";
/* No comment provided by engineer. */
"Delete %lld messages?" = "Usunąć %lld wiadomości?";
@@ -1317,6 +1392,9 @@
/* No comment provided by engineer. */
"Delete contact" = "Usuń kontakt";
/* No comment provided by engineer. */
"Delete contact?" = "Usunąć kontakt?";
/* No comment provided by engineer. */
"Delete database" = "Usuń bazę danych";
@@ -1380,9 +1458,15 @@
/* server test step */
"Delete queue" = "Usuń kolejkę";
/* No comment provided by engineer. */
"Delete up to 20 messages at once." = "Usuń do 20 wiadomości na raz.";
/* No comment provided by engineer. */
"Delete user profile?" = "Usunąć profil użytkownika?";
/* No comment provided by engineer. */
"Delete without notification" = "Usuń bez powiadomienia";
/* deleted chat item */
"deleted" = "usunięty";
@@ -1425,9 +1509,15 @@
/* No comment provided by engineer. */
"Desktop devices" = "Urządzenia komputerowe";
/* No comment provided by engineer. */
"Destination server address of %@ is incompatible with forwarding server %@ settings." = "Adres serwera docelowego %@ jest niekompatybilny z ustawieniami serwera przekazującego %@.";
/* snd error text */
"Destination server error: %@" = "Błąd docelowego serwera: %@";
/* No comment provided by engineer. */
"Destination server version of %@ is incompatible with forwarding server %@." = "Wersja serwera docelowego %@ jest niekompatybilna z serwerem przekierowującym %@.";
/* No comment provided by engineer. */
"Detailed statistics" = "Szczegółowe statystyki";
@@ -1437,6 +1527,9 @@
/* No comment provided by engineer. */
"Develop" = "Deweloperskie";
/* No comment provided by engineer. */
"Developer options" = "Opcje deweloperskie";
/* No comment provided by engineer. */
"Developer tools" = "Narzędzia deweloperskie";
@@ -1476,6 +1569,9 @@
/* No comment provided by engineer. */
"disabled" = "wyłączony";
/* No comment provided by engineer. */
"Disabled" = "Wyłączony";
/* No comment provided by engineer. */
"Disappearing message" = "Znikająca wiadomość";
@@ -1623,6 +1719,9 @@
/* enabled status */
"enabled" = "włączone";
/* No comment provided by engineer. */
"Enabled" = "Włączony";
/* No comment provided by engineer. */
"Enabled for" = "Włączony dla";
@@ -1764,6 +1863,9 @@
/* No comment provided by engineer. */
"Error changing setting" = "Błąd zmiany ustawienia";
/* No comment provided by engineer. */
"Error connecting to forwarding server %@. Please try later." = "Błąd połączenia z serwerem przekierowania %@. Spróbuj ponownie później.";
/* No comment provided by engineer. */
"Error creating address" = "Błąd tworzenia adresu";
@@ -2074,6 +2176,15 @@
/* No comment provided by engineer. */
"Forwarded from" = "Przekazane dalej od";
/* No comment provided by engineer. */
"Forwarding server %@ failed to connect to destination server %@. Please try later." = "Serwer przekazujący %@ nie mógł połączyć się z serwerem docelowym %@. Spróbuj ponownie później.";
/* No comment provided by engineer. */
"Forwarding server address is incompatible with network settings: %@." = "Adres serwera przekierowującego jest niekompatybilny z ustawieniami sieciowymi: %@.";
/* No comment provided by engineer. */
"Forwarding server version is incompatible with network settings: %@." = "Wersja serwera przekierowującego jest niekompatybilna z ustawieniami sieciowymi: %@.";
/* snd error text */
"Forwarding server: %@\nDestination server error: %@" = "Serwer przekazujący: %1$@\nBłąd serwera docelowego: %2$@";
@@ -2425,6 +2536,9 @@
/* group name */
"invitation to group %@" = "zaproszenie do grupy %@";
/* No comment provided by engineer. */
"invite" = "zaproś";
/* No comment provided by engineer. */
"Invite friends" = "Zaproś znajomych";
@@ -2470,6 +2584,9 @@
/* No comment provided by engineer. */
"It can happen when:\n1. The messages expired in the sending client after 2 days or on the server after 30 days.\n2. Message decryption failed, because you or your contact used old database backup.\n3. The connection was compromised." = "Może to nastąpić, gdy:\n1. Wiadomości wygasły w wysyłającym kliencie po 2 dniach lub na serwerze po 30 dniach.\n2. Odszyfrowanie wiadomości nie powiodło się, ponieważ Ty lub Twój kontakt użyliście starej kopii zapasowej bazy danych.\n3. Połączenie zostało skompromitowane.";
/* No comment provided by engineer. */
"It protects your IP address and connections." = "Chroni Twój adres IP i połączenia.";
/* No comment provided by engineer. */
"It seems like you are already connected via this link. If it is not the case, there was an error (%@)." = "Wygląda na to, że jesteś już połączony przez ten link. Jeśli tak nie jest, wystąpił błąd (%@).";
@@ -2512,6 +2629,9 @@
/* No comment provided by engineer. */
"Keep" = "Zachowaj";
/* No comment provided by engineer. */
"Keep conversation" = "Zachowaj rozmowę";
/* No comment provided by engineer. */
"Keep the app open to use it from desktop" = "Zostaw aplikację otwartą i używaj ją z komputera";
@@ -2623,6 +2743,12 @@
/* No comment provided by engineer. */
"Max 30 seconds, received instantly." = "Maksymalnie 30 sekund, odbierane natychmiast.";
/* No comment provided by engineer. */
"Media & file servers" = "Serwery mediów i plików";
/* blur media */
"Medium" = "Średni";
/* member role */
"member" = "członek";
@@ -2650,6 +2776,9 @@
/* No comment provided by engineer. */
"Menus" = "Menu";
/* No comment provided by engineer. */
"message" = "wiadomość";
/* item status text */
"Message delivery error" = "Błąd dostarczenia wiadomości";
@@ -2686,6 +2815,9 @@
/* No comment provided by engineer. */
"Message reception" = "Odebranie wiadomości";
/* No comment provided by engineer. */
"Message servers" = "Serwery wiadomości";
/* No comment provided by engineer. */
"Message source remains private." = "Źródło wiadomości pozostaje prywatne.";
@@ -2794,6 +2926,9 @@
/* No comment provided by engineer. */
"Multiple chat profiles" = "Wiele profili czatu";
/* No comment provided by engineer. */
"mute" = "wycisz";
/* swipe action */
"Mute" = "Wycisz";
@@ -2827,6 +2962,9 @@
/* No comment provided by engineer. */
"New chat" = "Nowy czat";
/* No comment provided by engineer. */
"New chat experience 🎉" = "Nowe możliwości czatu 🎉";
/* notification */
"New contact request" = "Nowa prośba o kontakt";
@@ -2845,6 +2983,9 @@
/* No comment provided by engineer. */
"New in %@" = "Nowość w %@";
/* No comment provided by engineer. */
"New media options" = "Nowe opcje mediów";
/* No comment provided by engineer. */
"New member role" = "Nowa rola członka";
@@ -2914,6 +3055,9 @@
/* No comment provided by engineer. */
"Not compatible!" = "Nie kompatybilny!";
/* No comment provided by engineer. */
"Nothing selected" = "Nic nie jest zaznaczone";
/* No comment provided by engineer. */
"Notifications" = "Powiadomienia";
@@ -2970,6 +3114,9 @@
/* No comment provided by engineer. */
"Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." = "Tylko urządzenia klienckie przechowują profile użytkowników, kontakty, grupy i wiadomości wysyłane za pomocą **2-warstwowego szyfrowania end-to-end**.";
/* No comment provided by engineer. */
"Only delete conversation" = "Usuń tylko rozmowę";
/* No comment provided by engineer. */
"Only group owners can change group preferences." = "Tylko właściciele grup mogą zmieniać preferencje grupy.";
@@ -3126,6 +3273,12 @@
/* No comment provided by engineer. */
"PING interval" = "Interwał PINGU";
/* No comment provided by engineer. */
"Play from the chat list." = "Odtwórz z listy czatów.";
/* No comment provided by engineer. */
"Please ask your contact to enable calls." = "Poproś kontakt o włącznie połączeń.";
/* No comment provided by engineer. */
"Please ask your contact to enable sending voice messages." = "Poproś Twój kontakt o włączenie wysyłania wiadomości głosowych.";
@@ -3306,6 +3459,9 @@
/* No comment provided by engineer. */
"Rate the app" = "Oceń aplikację";
/* No comment provided by engineer. */
"Reachable chat toolbar" = "Osiągalny pasek narzędzi czatu";
/* chat item menu */
"React…" = "Reaguj…";
@@ -3493,6 +3649,9 @@
/* No comment provided by engineer. */
"Reset" = "Resetuj";
/* No comment provided by engineer. */
"Reset all hints" = "Zresetuj wszystkie wskazówki";
/* No comment provided by engineer. */
"Reset all statistics" = "Resetuj wszystkie statystyki";
@@ -3568,6 +3727,9 @@
/* No comment provided by engineer. */
"Save and notify group members" = "Zapisz i powiadom członków grupy";
/* No comment provided by engineer. */
"Save and reconnect" = "Zapisz i połącz ponownie";
/* No comment provided by engineer. */
"Save and update group profile" = "Zapisz i zaktualizuj profil grupowy";
@@ -3643,6 +3805,9 @@
/* No comment provided by engineer. */
"Scan server QR code" = "Zeskanuj kod QR serwera";
/* No comment provided by engineer. */
"search" = "szukaj";
/* No comment provided by engineer. */
"Search" = "Szukaj";
@@ -3682,6 +3847,9 @@
/* chat item action */
"Select" = "Wybierz";
/* No comment provided by engineer. */
"Selected %lld" = "Zaznaczono %lld";
/* No comment provided by engineer. */
"Selected chat preferences prohibit this message." = "Wybrane preferencje czatu zabraniają tej wiadomości.";
@@ -3724,6 +3892,9 @@
/* No comment provided by engineer. */
"Send live message" = "Wyślij wiadomość na żywo";
/* No comment provided by engineer. */
"Send message to enable calls." = "Wyślij wiadomość aby włączyć połączenia.";
/* No comment provided by engineer. */
"Send messages directly when IP address is protected and your or destination server does not support private routing." = "Wysyłaj wiadomości bezpośrednio, gdy adres IP jest chroniony i Twój lub docelowy serwer nie obsługuje prywatnego trasowania.";
@@ -3904,12 +4075,18 @@
/* No comment provided by engineer. */
"Share address with contacts?" = "Udostępnić adres kontaktom?";
/* No comment provided by engineer. */
"Share from other apps." = "Udostępnij z innych aplikacji.";
/* No comment provided by engineer. */
"Share link" = "Udostępnij link";
/* No comment provided by engineer. */
"Share this 1-time invite link" = "Udostępnij ten jednorazowy link";
/* No comment provided by engineer. */
"Share to SimpleX" = "Udostępnij do SimpleX";
/* No comment provided by engineer. */
"Share with contacts" = "Udostępnij kontaktom";
@@ -4003,9 +4180,18 @@
/* No comment provided by engineer. */
"SMP server" = "Serwer SMP";
/* blur media */
"Soft" = "Łagodny";
/* No comment provided by engineer. */
"Some file(s) were not exported:" = "Niektóre plik(i) nie zostały wyeksportowane:";
/* No comment provided by engineer. */
"Some non-fatal errors occurred during import - you may see Chat console for more details." = "Podczas importu wystąpiły niekrytyczne błędy - więcej szczegółów można znaleźć w konsoli czatu.";
/* No comment provided by engineer. */
"Some non-fatal errors occurred during import:" = "Podczas importu wystąpiły niekrytyczne błędy:";
/* notification title */
"Somebody" = "Ktoś";
@@ -4072,6 +4258,9 @@
/* No comment provided by engineer. */
"strike" = "strajk";
/* blur media */
"Strong" = "Silne";
/* No comment provided by engineer. */
"Submit" = "Zatwierdź";
@@ -4117,6 +4306,9 @@
/* No comment provided by engineer. */
"Tap to scan" = "Dotknij, aby zeskanować";
/* No comment provided by engineer. */
"TCP connection" = "Połączenie TCP";
/* No comment provided by engineer. */
"TCP connection timeout" = "Limit czasu połączenia TCP";
@@ -4192,6 +4384,12 @@
/* No comment provided by engineer. */
"The message will be marked as moderated for all members." = "Wiadomość zostanie oznaczona jako moderowana dla wszystkich członków.";
/* No comment provided by engineer. */
"The messages will be deleted for all members." = "Wiadomości zostaną usunięte dla wszystkich członków.";
/* No comment provided by engineer. */
"The messages will be marked as moderated for all members." = "Wiadomości zostaną oznaczone jako moderowane dla wszystkich członków.";
/* No comment provided by engineer. */
"The next generation of private messaging" = "Następna generacja prywatnych wiadomości";
@@ -4303,9 +4501,15 @@
/* No comment provided by engineer. */
"To verify end-to-end encryption with your contact compare (or scan) the code on your devices." = "Aby zweryfikować szyfrowanie end-to-end z Twoim kontaktem porównaj (lub zeskanuj) kod na waszych urządzeniach.";
/* No comment provided by engineer. */
"Toggle chat list:" = "Przełącz listę czatów:";
/* No comment provided by engineer. */
"Toggle incognito when connecting." = "Przełącz incognito przy połączeniu.";
/* No comment provided by engineer. */
"Toolbar opacity" = "Nieprzezroczystość paska narzędzi";
/* No comment provided by engineer. */
"Total" = "Łącznie";
@@ -4408,6 +4612,9 @@
/* authentication reason */
"Unlock app" = "Odblokuj aplikację";
/* No comment provided by engineer. */
"unmute" = "wyłącz wyciszenie";
/* swipe action */
"Unmute" = "Wyłącz wyciszenie";
@@ -4429,6 +4636,9 @@
/* No comment provided by engineer. */
"Update network settings?" = "Zaktualizować ustawienia sieci?";
/* No comment provided by engineer. */
"Update settings?" = "Zaktualizować ustawienia?";
/* rcv group event chat item */
"updated group profile" = "zaktualizowano profil grupy";
@@ -4498,6 +4708,9 @@
/* No comment provided by engineer. */
"Use the app while in the call." = "Używaj aplikacji podczas połączenia.";
/* No comment provided by engineer. */
"Use the app with one hand." = "Korzystaj z aplikacji jedną ręką.";
/* No comment provided by engineer. */
"User profile" = "Profil użytkownika";
@@ -4552,6 +4765,9 @@
/* No comment provided by engineer. */
"Via secure quantum resistant protocol." = "Dzięki bezpiecznemu protokołowi odpornego kwantowo.";
/* No comment provided by engineer. */
"video" = "wideo";
/* No comment provided by engineer. */
"Video call" = "Połączenie wideo";
@@ -4762,6 +4978,9 @@
/* No comment provided by engineer. */
"You can accept calls from lock screen, without device and app authentication." = "Możesz przyjmować połączenia z ekranu blokady, bez uwierzytelniania urządzenia i aplikacji.";
/* No comment provided by engineer. */
"You can change it in Appearance settings." = "Możesz to zmienić w ustawieniach wyglądu.";
/* No comment provided by engineer. */
"You can create it later" = "Możesz go utworzyć później";
@@ -4783,6 +5002,9 @@
/* notification body */
"You can now chat with %@" = "Możesz teraz wysyłać wiadomości do %@";
/* No comment provided by engineer. */
"You can send messages to %@ from Archived contacts." = "Możesz wysyłać wiadomości do %@ ze zarchiwizowanych kontaktów.";
/* No comment provided by engineer. */
"You can set lock screen notification preview via settings." = "Podgląd powiadomień na ekranie blokady można ustawić w ustawieniach.";
@@ -4798,6 +5020,9 @@
/* No comment provided by engineer. */
"You can start chat via app Settings / Database or by restarting the app" = "Możesz rozpocząć czat poprzez Ustawienia aplikacji / Baza danych lub poprzez ponowne uruchomienie aplikacji";
/* No comment provided by engineer. */
"You can still view conversation with %@ in the list of chats." = "Nadal możesz przeglądać rozmowę z %@ na liście czatów.";
/* No comment provided by engineer. */
"You can turn on SimpleX Lock via Settings." = "Możesz włączyć blokadę SimpleX poprzez Ustawienia.";
@@ -4849,9 +5074,18 @@
/* snd group event chat item */
"you left" = "wyszedłeś";
/* No comment provided by engineer. */
"You may migrate the exported database." = "Możesz zmigrować wyeksportowaną bazy danych.";
/* No comment provided by engineer. */
"You may save the exported archive." = "Możesz zapisać wyeksportowane archiwum.";
/* No comment provided by engineer. */
"You must use the most recent version of your chat database on one device ONLY, otherwise you may stop receiving the messages from some contacts." = "Musisz używać najnowszej wersji bazy danych czatu TYLKO na jednym urządzeniu, w przeciwnym razie możesz przestać otrzymywać wiadomości od niektórych kontaktów.";
/* No comment provided by engineer. */
"You need to allow your contact to call to be able to call them." = "Aby móc dzwonić, musisz zezwolić kontaktowi na połączenia.";
/* No comment provided by engineer. */
"You need to allow your contact to send voice messages to be able to send them." = "Musisz zezwolić Twojemu kontaktowi na wysyłanie wiadomości głosowych, aby móc je wysyłać.";
File diff suppressed because it is too large Load Diff
@@ -846,15 +846,15 @@ object ChatController {
return null
}
suspend fun apiSendMessage(rh: Long?, type: ChatType, id: Long, file: CryptoFile? = null, quotedItemId: Long? = null, mc: MsgContent, live: Boolean = false, ttl: Int? = null): AChatItem? {
val cmd = CC.ApiSendMessage(type, id, file, quotedItemId, mc, live, ttl)
suspend fun apiSendMessages(rh: Long?, type: ChatType, id: Long, live: Boolean = false, ttl: Int? = null, composedMessages: List<ComposedMessage>): List<AChatItem>? {
val cmd = CC.ApiSendMessages(type, id, live, ttl, composedMessages)
return processSendMessageCmd(rh, cmd)
}
private suspend fun processSendMessageCmd(rh: Long?, cmd: CC): AChatItem? {
private suspend fun processSendMessageCmd(rh: Long?, cmd: CC): List<AChatItem>? {
val r = sendCmd(rh, cmd)
return when (r) {
is CR.NewChatItem -> r.chatItem
is CR.NewChatItems -> r.chatItems
else -> {
if (!(networkErrorAlert(r))) {
apiErrorAlert("processSendMessageCmd", generalGetString(MR.strings.error_sending_message), r)
@@ -863,13 +863,13 @@ object ChatController {
}
}
}
suspend fun apiCreateChatItem(rh: Long?, noteFolderId: Long, file: CryptoFile? = null, mc: MsgContent): AChatItem? {
val cmd = CC.ApiCreateChatItem(noteFolderId, file, mc)
suspend fun apiCreateChatItems(rh: Long?, noteFolderId: Long, composedMessages: List<ComposedMessage>): List<AChatItem>? {
val cmd = CC.ApiCreateChatItems(noteFolderId, composedMessages)
val r = sendCmd(rh, cmd)
return when (r) {
is CR.NewChatItem -> r.chatItem
is CR.NewChatItems -> r.chatItems
else -> {
apiErrorAlert("apiCreateChatItem", generalGetString(MR.strings.error_creating_message), r)
apiErrorAlert("apiCreateChatItems", generalGetString(MR.strings.error_creating_message), r)
null
}
}
@@ -885,9 +885,9 @@ object ChatController {
}
}
suspend fun apiForwardChatItem(rh: Long?, toChatType: ChatType, toChatId: Long, fromChatType: ChatType, fromChatId: Long, itemId: Long, ttl: Int?): ChatItem? {
val cmd = CC.ApiForwardChatItem(toChatType, toChatId, fromChatType, fromChatId, itemId, ttl)
return processSendMessageCmd(rh, cmd)?.chatItem
suspend fun apiForwardChatItems(rh: Long?, toChatType: ChatType, toChatId: Long, fromChatType: ChatType, fromChatId: Long, itemIds: List<Long>, ttl: Int?): List<ChatItem>? {
val cmd = CC.ApiForwardChatItems(toChatType, toChatId, fromChatType, fromChatId, itemIds, ttl)
return processSendMessageCmd(rh, cmd)?.map { it.chatItem }
}
@@ -2132,27 +2132,30 @@ object ChatController {
chatModel.networkStatuses[s.agentConnId] = s.networkStatus
}
}
is CR.NewChatItem -> withBGApi {
val cInfo = r.chatItem.chatInfo
val cItem = r.chatItem.chatItem
if (active(r.user)) {
withChats {
addChatItem(rhId, cInfo, cItem)
is CR.NewChatItems -> withBGApi {
r.chatItems.forEach { chatItem ->
val cInfo = chatItem.chatInfo
val cItem = chatItem.chatItem
if (active(r.user)) {
withChats {
addChatItem(rhId, cInfo, cItem)
}
} else if (cItem.isRcvNew && cInfo.ntfsEnabled) {
chatModel.increaseUnreadCounter(rhId, r.user)
}
} else if (cItem.isRcvNew && cInfo.ntfsEnabled) {
chatModel.increaseUnreadCounter(rhId, r.user)
}
val file = cItem.file
val mc = cItem.content.msgContent
if (file != null &&
val file = cItem.file
val mc = cItem.content.msgContent
if (file != null &&
appPrefs.privacyAcceptImages.get() &&
((mc is MsgContent.MCImage && file.fileSize <= MAX_IMAGE_SIZE_AUTO_RCV)
|| (mc is MsgContent.MCVideo && file.fileSize <= MAX_VIDEO_SIZE_AUTO_RCV)
|| (mc is MsgContent.MCVoice && file.fileSize <= MAX_VOICE_SIZE_AUTO_RCV && file.fileStatus !is CIFileStatus.RcvAccepted))) {
receiveFile(rhId, r.user, file.fileId, auto = true)
}
if (cItem.showNotification && (allowedToShowNotification() || chatModel.chatId.value != cInfo.id || chatModel.remoteHostId() != rhId)) {
ntfManager.notifyMessageReceived(r.user, cInfo, cItem)
|| (mc is MsgContent.MCVoice && file.fileSize <= MAX_VOICE_SIZE_AUTO_RCV && file.fileStatus !is CIFileStatus.RcvAccepted))
) {
receiveFile(rhId, r.user, file.fileId, auto = true)
}
if (cItem.showNotification && (allowedToShowNotification() || chatModel.chatId.value != cInfo.id || chatModel.remoteHostId() != rhId)) {
ntfManager.notifyMessageReceived(r.user, cInfo, cItem)
}
}
}
is CR.ChatItemStatusUpdated -> {
@@ -2863,13 +2866,13 @@ sealed class CC {
class ApiGetChats(val userId: Long): CC()
class ApiGetChat(val type: ChatType, val id: Long, val pagination: ChatPagination, val search: String = ""): CC()
class ApiGetChatItemInfo(val type: ChatType, val id: Long, val itemId: Long): CC()
class ApiSendMessage(val type: ChatType, val id: Long, val file: CryptoFile?, val quotedItemId: Long?, val mc: MsgContent, val live: Boolean, val ttl: Int?): CC()
class ApiCreateChatItem(val noteFolderId: Long, val file: CryptoFile?, val mc: MsgContent): CC()
class ApiSendMessages(val type: ChatType, val id: Long, val live: Boolean, val ttl: Int?, val composedMessages: List<ComposedMessage>): CC()
class ApiCreateChatItems(val noteFolderId: Long, val composedMessages: List<ComposedMessage>): CC()
class ApiUpdateChatItem(val type: ChatType, val id: Long, val itemId: Long, val mc: MsgContent, val live: Boolean): CC()
class ApiDeleteChatItem(val type: ChatType, val id: Long, val itemIds: List<Long>, val mode: CIDeleteMode): CC()
class ApiDeleteMemberChatItem(val groupId: Long, val itemIds: List<Long>): CC()
class ApiChatItemReaction(val type: ChatType, val id: Long, val itemId: Long, val add: Boolean, val reaction: MsgReaction): CC()
class ApiForwardChatItem(val toChatType: ChatType, val toChatId: Long, val fromChatType: ChatType, val fromChatId: Long, val itemId: Long, val ttl: Int?): CC()
class ApiForwardChatItems(val toChatType: ChatType, val toChatId: Long, val fromChatType: ChatType, val fromChatId: Long, val itemIds: List<Long>, val ttl: Int?): CC()
class ApiNewGroup(val userId: Long, val incognito: Boolean, val groupProfile: GroupProfile): CC()
class ApiAddMember(val groupId: Long, val contactId: Long, val memberRole: GroupMemberRole): CC()
class ApiJoinGroup(val groupId: Long): CC()
@@ -3008,20 +3011,22 @@ sealed class CC {
is ApiGetChats -> "/_get chats $userId pcc=on"
is ApiGetChat -> "/_get chat ${chatRef(type, id)} ${pagination.cmdString}" + (if (search == "") "" else " search=$search")
is ApiGetChatItemInfo -> "/_get item info ${chatRef(type, id)} $itemId"
is ApiSendMessage -> {
is ApiSendMessages -> {
val msgs = json.encodeToString(composedMessages)
val ttlStr = if (ttl != null) "$ttl" else "default"
"/_send ${chatRef(type, id)} live=${onOff(live)} ttl=${ttlStr} json ${json.encodeToString(ComposedMessage(file, quotedItemId, mc))}"
"/_send ${chatRef(type, id)} live=${onOff(live)} ttl=${ttlStr} json $msgs"
}
is ApiCreateChatItem -> {
"/_create *$noteFolderId json ${json.encodeToString(ComposedMessage(file, null, mc))}"
is ApiCreateChatItems -> {
val msgs = json.encodeToString(composedMessages)
"/_create *$noteFolderId json $msgs"
}
is ApiUpdateChatItem -> "/_update item ${chatRef(type, id)} $itemId live=${onOff(live)} ${mc.cmdString}"
is ApiDeleteChatItem -> "/_delete item ${chatRef(type, id)} ${itemIds.joinToString(",")} ${mode.deleteMode}"
is ApiDeleteMemberChatItem -> "/_delete member item #$groupId ${itemIds.joinToString(",")}"
is ApiChatItemReaction -> "/_reaction ${chatRef(type, id)} $itemId ${onOff(add)} ${json.encodeToString(reaction)}"
is ApiForwardChatItem -> {
is ApiForwardChatItems -> {
val ttlStr = if (ttl != null) "$ttl" else "default"
"/_forward ${chatRef(toChatType, toChatId)} ${chatRef(fromChatType, fromChatId)} $itemId ttl=${ttlStr}"
"/_forward ${chatRef(toChatType, toChatId)} ${chatRef(fromChatType, fromChatId)} ${itemIds.joinToString(",")} ttl=${ttlStr}"
}
is ApiNewGroup -> "/_group $userId incognito=${onOff(incognito)} ${json.encodeToString(groupProfile)}"
is ApiAddMember -> "/_add #$groupId $contactId ${memberRole.memberRole}"
@@ -3158,13 +3163,13 @@ sealed class CC {
is ApiGetChats -> "apiGetChats"
is ApiGetChat -> "apiGetChat"
is ApiGetChatItemInfo -> "apiGetChatItemInfo"
is ApiSendMessage -> "apiSendMessage"
is ApiCreateChatItem -> "apiCreateChatItem"
is ApiSendMessages -> "apiSendMessages"
is ApiCreateChatItems -> "apiCreateChatItems"
is ApiUpdateChatItem -> "apiUpdateChatItem"
is ApiDeleteChatItem -> "apiDeleteChatItem"
is ApiDeleteMemberChatItem -> "apiDeleteMemberChatItem"
is ApiChatItemReaction -> "apiChatItemReaction"
is ApiForwardChatItem -> "apiForwardChatItem"
is ApiForwardChatItems -> "apiForwardChatItems"
is ApiNewGroup -> "apiNewGroup"
is ApiAddMember -> "apiAddMember"
is ApiJoinGroup -> "apiJoinGroup"
@@ -4790,7 +4795,7 @@ sealed class CR {
@Serializable @SerialName("memberSubErrors") class MemberSubErrors(val user: UserRef, val memberSubErrors: List<MemberSubError>): CR()
@Serializable @SerialName("groupEmpty") class GroupEmpty(val user: UserRef, val group: GroupInfo): CR()
@Serializable @SerialName("userContactLinkSubscribed") class UserContactLinkSubscribed: CR()
@Serializable @SerialName("newChatItem") class NewChatItem(val user: UserRef, val chatItem: AChatItem): CR()
@Serializable @SerialName("newChatItems") class NewChatItems(val user: UserRef, val chatItems: List<AChatItem>): CR()
@Serializable @SerialName("chatItemStatusUpdated") class ChatItemStatusUpdated(val user: UserRef, val chatItem: AChatItem): CR()
@Serializable @SerialName("chatItemUpdated") class ChatItemUpdated(val user: UserRef, val chatItem: AChatItem): CR()
@Serializable @SerialName("chatItemNotChanged") class ChatItemNotChanged(val user: UserRef, val chatItem: AChatItem): CR()
@@ -4966,7 +4971,7 @@ sealed class CR {
is MemberSubErrors -> "memberSubErrors"
is GroupEmpty -> "groupEmpty"
is UserContactLinkSubscribed -> "userContactLinkSubscribed"
is NewChatItem -> "newChatItem"
is NewChatItems -> "newChatItems"
is ChatItemStatusUpdated -> "chatItemStatusUpdated"
is ChatItemUpdated -> "chatItemUpdated"
is ChatItemNotChanged -> "chatItemNotChanged"
@@ -5134,7 +5139,7 @@ sealed class CR {
is MemberSubErrors -> withUser(user, json.encodeToString(memberSubErrors))
is GroupEmpty -> withUser(user, json.encodeToString(group))
is UserContactLinkSubscribed -> noDetails()
is NewChatItem -> withUser(user, json.encodeToString(chatItem))
is NewChatItems -> withUser(user, chatItems.joinToString("\n") { json.encodeToString(it) })
is ChatItemStatusUpdated -> withUser(user, json.encodeToString(chatItem))
is ChatItemUpdated -> withUser(user, json.encodeToString(chatItem))
is ChatItemNotChanged -> withUser(user, json.encodeToString(chatItem))
@@ -380,24 +380,28 @@ fun ComposeView(
suspend fun send(chat: Chat, mc: MsgContent, quoted: Long?, file: CryptoFile? = null, live: Boolean = false, ttl: Int?): ChatItem? {
val cInfo = chat.chatInfo
val aChatItem = if (chat.chatInfo.chatType == ChatType.Local)
chatModel.controller.apiCreateChatItem(rh = chat.remoteHostId, noteFolderId = chat.chatInfo.apiId, file = file, mc = mc)
val chatItems = if (chat.chatInfo.chatType == ChatType.Local)
chatModel.controller.apiCreateChatItems(
rh = chat.remoteHostId,
noteFolderId = chat.chatInfo.apiId,
composedMessages = listOf(ComposedMessage(file, null, mc))
)
else
chatModel.controller.apiSendMessage(
rh = chat.remoteHostId,
type = cInfo.chatType,
id = cInfo.apiId,
file = file,
quotedItemId = quoted,
mc = mc,
live = live,
ttl = ttl
)
if (aChatItem != null) {
withChats {
addChatItem(chat.remoteHostId, cInfo, aChatItem.chatItem)
chatModel.controller.apiSendMessages(
rh = chat.remoteHostId,
type = cInfo.chatType,
id = cInfo.apiId,
live = live,
ttl = ttl,
composedMessages = listOf(ComposedMessage(file, quoted, mc))
)
if (!chatItems.isNullOrEmpty()) {
chatItems.forEach { aChatItem ->
withChats {
addChatItem(chat.remoteHostId, cInfo, aChatItem.chatItem)
}
}
return aChatItem.chatItem
return chatItems.first().chatItem
}
if (file != null) removeFile(file.filePath)
return null
@@ -414,21 +418,22 @@ fun ComposeView(
}
suspend fun forwardItem(rhId: Long?, forwardedItem: ChatItem, fromChatInfo: ChatInfo, ttl: Int?): ChatItem? {
val chatItem = controller.apiForwardChatItem(
val chatItems = controller.apiForwardChatItems(
rh = rhId,
toChatType = chat.chatInfo.chatType,
toChatId = chat.chatInfo.apiId,
fromChatType = fromChatInfo.chatType,
fromChatId = fromChatInfo.apiId,
itemId = forwardedItem.id,
itemIds = listOf(forwardedItem.id),
ttl = ttl
)
if (chatItem != null) {
chatItems?.forEach { chatItem ->
withChats {
addChatItem(rhId, chat.chatInfo, chatItem)
}
}
return chatItem
// TODO batch send: forward multiple messages
return chatItems?.firstOrNull()
}
fun checkLinkPreview(): MsgContent {
@@ -519,6 +524,7 @@ fun ComposeView(
ComposePreview.NoPreview -> msgs.add(MsgContent.MCText(msgText))
is ComposePreview.CLinkPreview -> msgs.add(checkLinkPreview())
is ComposePreview.MediaPreview -> {
// TODO batch send: batch media previews
preview.content.forEachIndexed { index, it ->
val file = when (it) {
is UploadContent.SimpleImage ->
@@ -1950,7 +1950,7 @@
<string name="servers_info_sessions_connected">متصل</string>
<string name="servers_info_connected_servers_section_header">الخوادم المتصلة</string>
<string name="servers_info_sessions_connecting">جارِ الاتصال</string>
<string name="servers_info_subscriptions_connections_subscribed">الاتصالات النسطة</string>
<string name="servers_info_subscriptions_connections_subscribed">الاتصالات النشطة</string>
<string name="current_user">ملف التعريف الحالي</string>
<string name="deletion_errors">أخطاء الحذف</string>
<string name="servers_info_detailed_statistics">إحصائيات مفصلة</string>
@@ -1526,9 +1526,9 @@
<string name="recent_history_is_not_sent_to_new_members">El historial no se envía a miembros nuevos.</string>
<string name="retry_verb">Reintentar</string>
<string name="camera_not_available">Cámara no disponible</string>
<string name="enable_sending_recent_history">Enviar hasta 100 últimos mensajes a los miembros nuevos.</string>
<string name="enable_sending_recent_history">Se envían hasta 100 mensajes más recientes a los miembros nuevos.</string>
<string name="add_contact_button_to_create_link_or_connect_via_link"><![CDATA[<b>Añadir contacto</b>: crea un enlace de invitación nuevo o usa un enlace recibido.]]></string>
<string name="disable_sending_recent_history">No enviar historial a miembros nuevos.</string>
<string name="disable_sending_recent_history">No se envía el historial a los miembros nuevos.</string>
<string name="or_show_this_qr_code">O muestra este código QR</string>
<string name="recent_history_is_sent_to_new_members">Hasta 100 últimos mensajes son enviados a los miembros nuevos.</string>
<string name="code_you_scanned_is_not_simplex_link_qr_code">El código QR escaneado no es un enlace SimpleX.</string>
@@ -1736,9 +1736,9 @@
<string name="network_type_ethernet">Ethernet por cable</string>
<string name="feature_roles_admins">administradores</string>
<string name="feature_enabled_for">Activado para</string>
<string name="prohibit_sending_simplex_links">No permitir el envío de enlaces SimpleX</string>
<string name="prohibit_sending_simplex_links">No se permite enviar enlaces SimpleX</string>
<string name="feature_roles_all_members">todos los miembros</string>
<string name="allow_to_send_simplex_links">Permitir enviar enlaces SimpleX.</string>
<string name="allow_to_send_simplex_links">Se permite enviar enlaces SimpleX.</string>
<string name="saved_description">guardado</string>
<string name="saved_from_description">guardado desde %s</string>
<string name="saved_chat_item_info_tab">Guardado</string>
@@ -2065,7 +2065,9 @@
<string name="invite_friends_short">Invitar</string>
<string name="v6_0_new_chat_experience">Nueva experiencia de chat 🎉</string>
<string name="v6_0_new_media_options">Nuevas opciones multimedia</string>
<string name="one_hand_ui_change_instruction">Puede cambiarlo desde el menú Apariencia.</string>
<string name="one_hand_ui_change_instruction">Puedes cambiar la posición de la barra desde el menú Apariencia.</string>
<string name="v6_0_upgrade_app_descr">Descarga nuevas versiones desde GitHub.</string>
<string name="new_message">Nuevo mensaje</string>
<string name="error_parsing_uri_title">Enlace no válido</string>
<string name="error_parsing_uri_desc">Por favor, comprueba que el enlace SimpleX es correcto.</string>
</resources>
@@ -44,7 +44,7 @@
<string name="network_session_mode_user_description"><![CDATA[Külön TCP kapcsolat (és SOCKS bejelentkezési adatok) lesz használva <b>az alkalmazásban minden csevegési profiljához </b>.]]></string>
<string name="both_you_and_your_contact_can_send_disappearing">Mindkét fél küldhet eltűnő üzeneteket.</string>
<string name="keychain_is_storing_securely">Az Android Keystore-t a jelmondat biztonságos tárolására használják - lehetővé teszi az értesítési szolgáltatás működését.</string>
<string name="alert_title_msg_bad_hash">Téves üzenet hash</string>
<string name="alert_title_msg_bad_hash">Hibás az üzenet ellenőrzőösszege</string>
<string name="color_background">Háttér</string>
<string name="socks_proxy_setting_limitations"><![CDATA[<b>Tudnivaló</b>: az üzenet- és fájl átjátszók SOCKS proxy által vannak kapcsolatban. A hívások és URL hivatkozás előnézetek közvetlen kapcsolatot használnak.]]></string>
<string name="full_backup">Alkalmazásadatok biztonsági mentése</string>
@@ -124,7 +124,7 @@
<string name="icon_descr_cancel_live_message">Élő csevegési üzenet visszavonása</string>
<string name="allow_irreversible_message_deletion_only_if">Az üzenetek végleges törlése kizárólag abban az esetben van engedélyezve, ha az ismerőse is engedélyezi. (24 óra)</string>
<string name="v4_6_audio_video_calls">Hang- és videóhívások</string>
<string name="integrity_msg_bad_hash">téves üzenet hash</string>
<string name="integrity_msg_bad_hash">hibás az üzenet ellenőrzőösszege</string>
<string name="notifications_mode_service">Mindig fut</string>
<string name="keychain_allows_to_receive_ntfs">Az Android Keystore biztonságosan fogja tárolni a jelmondatot az alkalmazás újraindítása, vagy a jelmondat megváltoztatás után - lehetővé téve az értesítések fogadását.</string>
<string name="all_app_data_will_be_cleared">Minden alkalmazásadat törölve.</string>
@@ -242,7 +242,7 @@
<string name="group_member_status_intro_invitation">kapcsolódás (bemutatkozó meghívó)</string>
<string name="create_simplex_address">SimpleX cím létrehozása</string>
<string name="rcv_direct_event_contact_deleted">törölt ismerős</string>
<string name="delete_member_message__question">Csoporttag üzenet törlése?</string>
<string name="delete_member_message__question">Csoporttag üzenetének törlése?</string>
<string name="chat_is_running">A csevegés fut</string>
<string name="share_one_time_link">Egyszer használatos meghívó hivatkozás létrehozása</string>
<string name="delete_link">Törlés</string>
@@ -487,7 +487,7 @@
\nCsatlakozzon hozzám SimpleX Chat-en keresztül: %s</string>
<string name="display_name_cannot_contain_whitespace">A megjelenített név nem tartalmazhat szóközöket.</string>
<string name="info_row_group">Csoport</string>
<string name="enter_welcome_message_optional">Üdvözlő üzenetet megadása… (opcionális)</string>
<string name="enter_welcome_message_optional">Üdvözlő üzenet megadása… (opcionális)</string>
<string name="error_exporting_chat_database">Hiba a csevegési adatbázis exportálásakor</string>
<string name="error_saving_file">Hiba a fájl mentésekor</string>
<string name="encrypt_local_files">Helyi fájlok titkosítása</string>
@@ -544,7 +544,7 @@
<string name="alert_text_encryption_renegotiation_failed">Sikertelen titkosítás-újraegyeztetés.</string>
<string name="error_deleting_user">Hiba a felhasználói profil törlésekor</string>
<string name="fix_connection_not_supported_by_group_member">Csoporttag általi javítás nem támogatott</string>
<string name="enter_welcome_message">Üdvözlő üzenetet megadása…</string>
<string name="enter_welcome_message">Üdvözlő üzenet megadása…</string>
<string name="encrypted_database">Titkosított adatbázis</string>
<string name="enter_password_to_show">Jelszó megadása a keresőben</string>
<string name="file_will_be_received_when_contact_completes_uploading">A fájl akkor érkezik meg, amikor a küldője befejezte annak feltöltését.</string>
@@ -1269,7 +1269,7 @@
<string name="chat_lock">SimpleX zár</string>
<string name="your_settings">Beállítások</string>
<string name="your_chat_database">Csevegési adatbázis</string>
<string name="rcv_group_event_member_deleted">%1$s eltávolítva</string>
<string name="rcv_group_event_member_deleted">eltávolította őt: %1$s</string>
<string name="smp_servers_test_failed">Sikertelen kiszolgáló teszt!</string>
<string name="verify_connection">Kapcsolat ellenőrzése</string>
<string name="whats_new_read_more">Tudjon meg többet</string>
@@ -1510,7 +1510,7 @@
<string name="read_more_in_user_guide_with_link"><![CDATA[További információ a <font color="#0088ff">Használati útmutatóban</font> olvasható.]]></string>
<string name="settings_is_storing_in_clear_text">A jelmondat a beállításokban egyszerű szövegként van tárolva.</string>
<string name="terminal_always_visible">Konzol megjelenítése új ablakban</string>
<string name="alert_text_msg_bad_hash">Az előző üzenet hash-e más.</string>
<string name="alert_text_msg_bad_hash">Az előző üzenet ellenőrzőösszege különbözik.</string>
<string name="receipts_section_description">Ezek a beállítások a jelenlegi profiljára vonatkoznak</string>
<string name="loading_remote_file_desc">Várjon, amíg a fájl betöltődik a csatolt mobilról</string>
<string name="read_more_in_github_with_link"><![CDATA[További információ a <font color="#0088ff">GitHub tárolónkban</font>.]]></string>
@@ -100,4 +100,16 @@
<string name="connected_mobile">Ponsel yang terhubung</string>
<string name="multicast_connect_automatically">Hubungkan secara otomatis</string>
<string name="callstate_connecting">menyambungkan…</string>
<string name="servers_info_sessions_connecting">Menghubungkan</string>
<string name="error_parsing_uri_title">Tautan tidak valid</string>
<string name="error_parsing_uri_desc">Periksa apakah tautan SimpleX sudah benar.</string>
<string name="connected_to_server_to_receive_messages_from_contact">Anda terhubung ke server yang digunakan untuk menerima pesan dari kontak ini.</string>
<string name="trying_to_connect_to_server_to_receive_messages_with_error">Mencoba menyambung ke server yang digunakan untuk menerima pesan dari kontak ini (error: %1$s).</string>
<string name="database_migration_in_progress">Migrasi basis data sedang berlangsung,
\nmemerlukan waktu beberapa menit.</string>
<string name="server_connecting">menghubungkan</string>
<string name="non_content_uri_alert_title">Lokasi file tidak valid</string>
<string name="app_was_crashed">Tampilan macet</string>
<string name="non_content_uri_alert_text">Anda membagikan lokasi file yang tidak valid. Laporkan masalah ini ke pengembang aplikasi.</string>
<string name="server_error">error</string>
</resources>
@@ -2051,7 +2051,7 @@
<string name="v6_0_reachable_chat_toolbar">Barra degli strumenti di chat accessibile</string>
<string name="v6_0_your_contacts_descr">Archivia contatti per chattare più tardi.</string>
<string name="v6_0_reachable_chat_toolbar_descr">Usa l\'app con una mano sola.</string>
<string name="v6_0_connection_servers_status_descr">Stato di connessione e server.</string>
<string name="v6_0_connection_servers_status_descr">Stato della connessione e dei server.</string>
<string name="v6_0_private_routing_descr">Protegge il tuo indirizzo IP e le connessioni.</string>
<string name="network_options_save_and_reconnect">Salva e riconnetti</string>
<string name="reset_all_hints">Ripristina tutti i suggerimenti</string>
@@ -2013,7 +2013,7 @@
<string name="info_view_connect_button">verbinden</string>
<string name="contact_deleted">Contact verwijderd!</string>
<string name="delete_contact_cannot_undo_warning">Het contact wordt verwijderd. Dit kan niet ongedaan worden gemaakt!</string>
<string name="keep_conversation">Blijf in gesprek</string>
<string name="keep_conversation">Behoud het gesprek</string>
<string name="info_view_message_button">bericht</string>
<string name="only_delete_conversation">Alleen conversatie verwijderen</string>
<string name="info_view_open_button">open</string>
@@ -2065,4 +2065,6 @@
<string name="v6_0_new_media_options">Nieuwe media-opties</string>
<string name="invite_friends_short">Uitnodigen</string>
<string name="new_message">Nieuw bericht</string>
<string name="error_parsing_uri_title">Ongeldige link</string>
<string name="error_parsing_uri_desc">Controleer of de SimpleX-link correct is.</string>
</resources>
@@ -181,7 +181,7 @@
<string name="you_are_observer">jesteś obserwatorem</string>
<string name="observer_cant_send_message_title">Nie możesz wysyłać wiadomości!</string>
<string name="icon_descr_server_status_connected">Połączony</string>
<string name="maximum_supported_file_size">Obecnie maksymalny obsługiwany rozmiar pliku to %1$s .</string>
<string name="maximum_supported_file_size">Obecnie maksymalny obsługiwany rozmiar pliku to %1$s.</string>
<string name="button_delete_contact">Usuń kontakt</string>
<string name="delete_contact_question">Usunąć kontakt\?</string>
<string name="icon_descr_server_status_disconnected">Rozłączony</string>
@@ -344,7 +344,7 @@
<string name="enter_one_ICE_server_per_line">Serwery ICE (po jednym na linię)</string>
<string name="network_disable_socks_info">Jeśli potwierdzisz, serwery wiadomości będą mogły zobaczyć Twój adres IP, a Twój dostawca - z jakimi serwerami się łączysz.</string>
<string name="network_and_servers">Sieć i serwery</string>
<string name="network_settings_title">Ustawienia sieci</string>
<string name="network_settings_title">Zaawansowane ustawienia</string>
<string name="network_use_onion_hosts_no">Nie</string>
<string name="network_use_onion_hosts_required_desc">Hosty onion będą wymagane do połączenia.
\nUwaga: nie będziesz mógł połączyć się z serwerami bez adresu .onion.</string>
@@ -408,11 +408,11 @@
<string name="decentralized">Zdecentralizowane</string>
<string name="callstate_ended">zakończona</string>
<string name="how_to_use_markdown">Jak korzystać z markdown</string>
<string name="immune_to_spam_and_abuse">Odporność na spam i nadużycia</string>
<string name="immune_to_spam_and_abuse">Odporność na spam</string>
<string name="italic_text">kursywa</string>
<string name="callstatus_missed">nieodebrane połączenie</string>
<string name="opensource_protocol_and_code_anybody_can_run_servers">Otwarto źródłowy protokół i kod - każdy może uruchomić serwery.</string>
<string name="people_can_connect_only_via_links_you_share">Ludzie mo się z Tobą połączyć tylko poprzez linki, które udostępniasz.</string>
<string name="opensource_protocol_and_code_anybody_can_run_servers">Każdy może hostować serwery.</string>
<string name="people_can_connect_only_via_links_you_share">Ty decydujesz, kto może się połączyć.</string>
<string name="privacy_redefined">Redefinicja prywatności</string>
<string name="callstate_received_answer">otrzymano odpowiedź…</string>
<string name="callstate_received_confirmation">otrzymano potwierdzenie…</string>
@@ -420,8 +420,9 @@
<string name="secret_text">sekret</string>
<string name="callstate_starting">uruchamianie…</string>
<string name="strikethrough_text">strajk</string>
<string name="first_platform_without_user_ids">Pierwsza platforma bez żadnych identyfikatorów użytkowników z założenia prywatna.</string>
<string name="next_generation_of_private_messaging">Następna generacja prywatnych wiadomości</string>
<string name="first_platform_without_user_ids">Brak identyfikatorów użytkownika.</string>
<string name="next_generation_of_private_messaging">Następna generacja
\nprywatnych wiadomości</string>
<string name="callstate_waiting_for_answer">oczekiwanie na odpowiedź…</string>
<string name="callstate_waiting_for_confirmation">oczekiwanie na potwierdzenie…</string>
<string name="you_can_use_markdown_to_format_messages__prompt">Możesz używać markdown do formatowania wiadomości:</string>
@@ -440,7 +441,7 @@
<string name="use_chat">Użyj czatu</string>
<string name="onboarding_notifications_mode_off">Gdy aplikacja jest uruchomiona</string>
<string name="you_control_servers_to_receive_your_contacts_to_send"><![CDATA[Kontrolujesz przez który serwer(y) <b>odbierać</b> wiadomości, Twoje kontakty - serwery, których używasz do wysyłania im wiadomości.]]></string>
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>Zużywa więcej baterii</b>! Usługa zawsze działa w tle - powiadomienia są wyświetlane, gdy tylko wiadomości są dostępne.]]></string>
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>Zużywa więcej baterii</b>! Aplikacja zawsze działa w tle - powiadomienia są wyświetlane natychmiastowo.]]></string>
<string name="incoming_audio_call">Przychodzące połączenie audio</string>
<string name="incoming_video_call">Przychodzące połączenie wideo</string>
<string name="paste_the_link_you_received">Wklej link, który otrzymałeś</string>
@@ -913,7 +914,7 @@
<string name="turning_off_service_and_periodic">Optymalizacja baterii jest aktywna, wyłącza usługi w tle i okresowe żądania nowych wiadomości. Możesz je ponownie włączyć za pośrednictwem ustawień.</string>
<string name="it_can_disabled_via_settings_notifications_still_shown"><![CDATA[<b>Można je wyłączyć poprzez ustawienia</b> - powiadomienia nadal będą pokazywane podczas działania aplikacji.]]></string>
<string name="onboarding_notifications_mode_off_desc"><![CDATA[<b>Najlepsze dla baterii</b>. Będziesz otrzymywać powiadomienia tylko wtedy, gdy aplikacja jest uruchomiona (NIE w tle).]]></string>
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>Dobry dla baterii</b>. Usługa w tle sprawdza wiadomości co 10 minut. Możesz przegapić połączenia lub pilne wiadomości.]]></string>
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>Dobry dla baterii</b>. Aplikacja sprawdza wiadomości co 10 minut. Możesz przegapić połączenia lub pilne wiadomości.]]></string>
<string name="both_you_and_your_contact_can_send_voice">Zarówno Ty, jak i Twój kontakt możecie wysyłać wiadomości głosowe.</string>
<string name="v4_5_transport_isolation_descr">Według profilu czatu (domyślnie) lub połączenia (BETA).</string>
<string name="alert_title_cant_invite_contacts">Nie można zaprosić kontaktów!</string>
@@ -1239,7 +1240,7 @@
\n- niestandardowy czas zniknięcia.
\n- historia edycji.</string>
<string name="item_info_no_text">brak tekstu</string>
<string name="non_fatal_errors_occured_during_import">Podczas importu wystąpiły niekrytyczne błędy - więcej szczegółów można znaleźć w konsoli czatu.</string>
<string name="non_fatal_errors_occured_during_import">Podczas importu wystąpiły niekrytyczne błędy:</string>
<string name="settings_restart_app">Restart</string>
<string name="settings_section_title_app">APLIKACJA</string>
<string name="shutdown_alert_desc">Powiadomienia przestaną działać do momentu ponownego uruchomienia aplikacji.</string>
@@ -1789,7 +1790,7 @@
<string name="settings_section_title_private_message_routing">TRASOWANIE PRYWATNYCH WIADOMOŚCI</string>
<string name="network_smp_proxy_fallback_prohibit_description">NIE wysyłaj wiadomości bezpośrednio, nawet jeśli serwer docelowy nie obsługuje prywatnego trasowania.</string>
<string name="private_routing_explanation">Aby chronić Twój adres IP, prywatne trasowanie używa Twoich serwerów SMP, aby dostarczyć wiadomości.</string>
<string name="network_smp_proxy_mode_unknown">Nieznane przekaźniki</string>
<string name="network_smp_proxy_mode_unknown">Nieznane serwery</string>
<string name="network_smp_proxy_mode_unknown_description">Używaj prywatnego trasowania z nieznanymi serwerami.</string>
<string name="update_network_smp_proxy_fallback_question">Rezerwowe trasowania wiadomości</string>
<string name="network_smp_proxy_mode_private_routing">Prywatne trasowanie</string>
@@ -1990,4 +1991,82 @@
<string name="send_errors">Wyślij błędy</string>
<string name="size">Rozmiar</string>
<string name="upload_errors">Błędy przesłania</string>
<string name="v6_0_increase_font_size">Zwiększ rozmiar czcionki.</string>
<string name="info_view_message_button">wiadomość</string>
<string name="compose_message_placeholder">Wiadomość</string>
<string name="info_view_open_button">otwórz</string>
<string name="info_view_search_button">szukaj</string>
<string name="selected_chat_items_selected_n">Zaznaczono %d</string>
<string name="info_view_video_button">wideo</string>
<string name="no_filtered_contacts">Brak filtrowanych kontaktów</string>
<string name="invite_friends_short">Zaproś</string>
<string name="v6_0_upgrade_app_descr">Pobieraj nowe wersje z GitHub.</string>
<string name="v6_0_new_media_options">Nowe opcje mediów</string>
<string name="contact_list_header_title">Twoje kontakty</string>
<string name="new_message">Nowa wiadomość</string>
<string name="v6_0_upgrade_app">Aktualizuj aplikację automatycznie</string>
<string name="v6_0_privacy_blur">Rozmycie dla lepszej prywatności.</string>
<string name="one_hand_ui_change_instruction">Możesz to zmienić w ustawieniach wyglądu.</string>
<string name="action_button_add_members">Zaproś</string>
<string name="cant_send_message_to_member_alert_title">Nie można wysłać wiadomości do członka grupy</string>
<string name="cant_call_member_send_message_alert_text">Wyślij wiadomość aby włączyć połączenia.</string>
<string name="v6_0_new_chat_experience">Nowe możliwości czatu 🎉</string>
<string name="v6_0_reachable_chat_toolbar_descr">Korzystaj z aplikacji jedną ręką.</string>
<string name="v6_0_chat_list_media">Odtwórz z listy czatów.</string>
<string name="deleted_chats">Zarchiwizowane kontakty</string>
<string name="info_view_call_button">zadzwoń</string>
<string name="info_view_connect_button">połącz</string>
<string name="v6_0_connection_servers_status_descr">Stan połączenia i serwerów.</string>
<string name="create_address_button">Utwórz</string>
<string name="error_parsing_uri_title">Nieprawidłowy link</string>
<string name="network_options_save_and_reconnect">Zapisz i połącz ponownie</string>
<string name="toolbar_settings">Ustawienia</string>
<string name="network_option_tcp_connection">Połączenie TCP</string>
<string name="selected_chat_items_nothing_selected">Nic nie jest zaznaczone</string>
<string name="error_parsing_uri_desc">Sprawdź czy link SimpleX jest poprawny.</string>
<string name="one_hand_ui_card_title">Przełącz listę czatów:</string>
<string name="v6_0_your_contacts_descr">Archiwizuj kontakty aby porozmawiać później.</string>
<string name="v6_0_private_routing_descr">Chroni Twój adres IP i połączenia.</string>
<string name="v6_0_reachable_chat_toolbar">Osiągalny pasek narzędzi czatu</string>
<string name="privacy_media_blur_radius_strong">Silne</string>
<string name="privacy_media_blur_radius">Rozmycie mediów</string>
<string name="privacy_media_blur_radius_medium">Średni</string>
<string name="privacy_media_blur_radius_off">Wyłącz</string>
<string name="privacy_media_blur_radius_soft">Łagodny</string>
<string name="keep_conversation">Zachowaj rozmowę</string>
<string name="only_delete_conversation">Usuń tylko rozmowę</string>
<string name="you_can_still_send_messages_to_contact">Możesz wysyłać wiadomości do %1$s ze zarchiwizowanych kontaktów.</string>
<string name="you_can_still_view_conversation_with_contact">Nadal możesz przeglądać rozmowę z %1$s na liście czatów.</string>
<string name="confirm_delete_contact_question">Potwierdzić usunięcie kontaktu?</string>
<string name="contact_deleted">Kontakt usunięty!</string>
<string name="delete_contact_cannot_undo_warning">Kontakt zostanie usunięty nie można tego cofnąć!</string>
<string name="conversation_deleted">Rozmowa usunięta!</string>
<string name="delete_without_notification">Usuń bez powiadomienia</string>
<string name="paste_link">Wklej link</string>
<string name="allow_calls_question">Zezwolić na połączenia?</string>
<string name="cant_call_contact_alert_title">Nie można zadzwonić do kontaktu</string>
<string name="cant_call_contact_connecting_wait_alert_text">Łączenie z kontaktem, poczekaj lub sprawdź później!</string>
<string name="cant_call_contact_deleted_alert_text">Kontakt jest usunięty.</string>
<string name="you_need_to_allow_calls">Aby móc dzwonić, musisz zezwolić kontaktowi na połączenia.</string>
<string name="calls_prohibited_alert_title">Połączenia zakazane!</string>
<string name="cant_call_member_alert_title">Nie można zadzwonić do członka grupy</string>
<string name="calls_prohibited_ask_to_enable_calls_alert_text">Poproś kontakt o włącznie połączeń.</string>
<string name="delete_members_messages__question">Usunąć %d wiadomości członków?</string>
<string name="delete_messages_mark_deleted_warning">Wiadomości zostaną oznaczone do usunięcia. Odbiorca(y) będą mogli ujawnić te wiadomości.</string>
<string name="select_verb">Zaznacz</string>
<string name="moderate_messages_will_be_deleted_warning">Wiadomości zostaną usunięte dla wszystkich członków.</string>
<string name="moderate_messages_will_be_marked_warning">Wiadomości zostaną oznaczone jako moderowane dla wszystkich członków.</string>
<string name="one_hand_ui">Osiągalny pasek narzędzi czatu</string>
<string name="chat_database_exported_title">Wyeksportowano bazę danych czatu</string>
<string name="chat_database_exported_continue">Kontynuuj</string>
<string name="media_and_file_servers">Serwery mediów i plików</string>
<string name="message_servers">Serwery wiadomości</string>
<string name="network_socks_proxy">Proxy SOCKS</string>
<string name="chat_database_exported_not_all_files">Niektóre plik(i) nie zostały wyeksportowane</string>
<string name="chat_database_exported_migrate">Możesz zmigrować wyeksportowaną bazy danych.</string>
<string name="chat_database_exported_save">Możesz zapisać wyeksportowane archiwum.</string>
<string name="reset_all_hints">Zresetuj wszystkie wskazówki</string>
<string name="v6_0_connect_faster_descr">Szybciej łącz się ze znajomymi.</string>
<string name="v6_0_connection_servers_status">Kontroluj swoją sieć</string>
<string name="v6_0_delete_many_messages_descr">Usuń do 20 wiadomości na raz.</string>
</resources>
@@ -636,4 +636,92 @@
<string name="enable_automatic_deletion_question">Cho phép xóa tin nhắn tự động?</string>
<string name="edit_verb">Chỉnh sửa</string>
<string name="icon_descr_email">Thư điện tử</string>
<string name="ci_status_other_error">Lỗi: %1$s</string>
<string name="error">Lỗi</string>
<string name="alert_text_encryption_renegotiation_failed">Tái đàm phán mã hóa thất bại.</string>
<string name="conn_event_ratchet_sync_ok">mã hóa ok</string>
<string name="snd_conn_event_ratchet_sync_allowed">cho phép tái đàm phán mã hóa với %s</string>
<string name="snd_conn_event_ratchet_sync_required">cần tái đàm phán mã hóa cho %s</string>
<string name="receipts_contacts_title_enable">Bật chỉ báo đã nhận?</string>
<string name="v5_3_encrypt_local_files">Mã hóa các tệp và phương tiện được lưu trữ</string>
<string name="error_alert_title">Lỗi</string>
<string name="call_service_notification_end_call">Kết thúc cuộc gọi</string>
<string name="v5_6_quantum_resistant_encryption_descr">Bật trong cuộc trò chuyện trực tiếp (BETA)!</string>
<string name="enabled_self_destruct_passcode">Bật mã truy cập tự hủy</string>
<string name="encrypt_database_question">Mã hóa cơ sở dữ liệu?</string>
<string name="encrypted_database">Cơ sở dữ liệu được mã hóa</string>
<string name="encryption_renegotiation_error">Lỗi tái đàm phán mã hóa</string>
<string name="migrate_to_device_enter_passphrase">Nhập mật khẩu</string>
<string name="receipts_contacts_enable_keep_overrides">Bật (giữ thông tin ghi đè)</string>
<string name="encrypt_database">Mã hóa</string>
<string name="conn_event_ratchet_sync_agreed">mã hóa đã đồng nhất</string>
<string name="conn_event_ratchet_sync_allowed">cho phép tái đàm phán mã hóa</string>
<string name="conn_event_ratchet_sync_required">cần tái đàm phán mã hóa</string>
<string name="network_option_enable_tcp_keep_alive">Bật TCP keep-alive</string>
<string name="enter_password_to_show">Nhập mật khẩu trong tìm kiếm</string>
<string name="enter_this_device_name">Nhập tên của thiết bị này…</string>
<string name="auth_enable_simplex_lock">Bật SimpleX Lock</string>
<string name="enter_welcome_message">Nhập lời chào…</string>
<string name="la_enter_app_passcode">Nhập mã truy cập</string>
<string name="icon_descr_server_status_error">Lỗi</string>
<string name="enter_welcome_message_optional">Nhập lời chào... (không bắt buộc)</string>
<string name="callstate_ended">đã kết thúc</string>
<string name="snd_conn_event_ratchet_sync_agreed">mã hóa đã đồng nhất cho %s</string>
<string name="snd_conn_event_ratchet_sync_ok">mã hóa ok cho %s</string>
<string name="server_error">lỗi</string>
<string name="smp_servers_enter_manually">Nhập máy chủ thủ công</string>
<string name="receipts_groups_enable_keep_overrides">Bật (giữ thông tin ghi đè nhóm)</string>
<string name="enter_correct_passphrase">Nhập đúng mật khẩu.</string>
<string name="enter_passphrase">Nhập mật khẩu…</string>
<string name="encrypt_local_files">Mã hóa các tệp cục bộ</string>
<string name="enable_self_destruct">Bật tự hủy</string>
<string name="receipts_groups_title_enable">Bật chỉ báo đã nhận cho các nhóm?</string>
<string name="group_display_name_field">Nhập tên nhóm:</string>
<string name="display_name">Nhập tên của bạn:</string>
<string name="enable_lock">Bật khóa</string>
<string name="servers_info_modal_error_title">Lỗi</string>
<string name="failed_to_create_user_title">Lỗi tạo hồ sơ!</string>
<string name="error_changing_message_deletion">Lỗi thay đổi cài đặt</string>
<string name="error_blocking_member_for_all">Lỗi chặn thành viên cho tất cả</string>
<string name="error_adding_members">Lỗi thêm thành viên</string>
<string name="error_creating_message">Lỗi tạo tin nhắn</string>
<string name="error_creating_address">Lỗi tạo địa chỉ</string>
<string name="error_accepting_contact_request">Lỗi chấp nhận yêu cầu liên hệ</string>
<string name="error_changing_address">Lỗi thay đổi địa chỉ</string>
<string name="error_deleting_database">Lỗi xóa cơ sở dữ liệu SimpleX Chat</string>
<string name="error_creating_member_contact">Lỗi tạo liên hệ thành viên</string>
<string name="error_aborting_address_change">Lỗi hủy bỏ thay đổi địa chỉ</string>
<string name="error_creating_link_for_group">Lỗi tạo liên kết nhóm</string>
<string name="error_changing_role">Lỗi thay đổi quyền hạn</string>
<string name="smp_proxy_error_connecting">Lỗi kết nối đến máy chủ chuyển tiếp %1$s. Vui lòng thử lại sau.</string>
<string name="error_deleting_contact">Lỗi xóa liên hệ</string>
<string name="error_deleting_group">Lỗi xóa nhóm</string>
<string name="error_deleting_link_for_group">Lỗi xóa liên kết nhóm</string>
<string name="error_deleting_contact_request">Lỗi xóa yêu cầu liên hệ</string>
<string name="migrate_from_device_error_deleting_database">Lỗi xóa cơ sở dữ liệu</string>
<string name="error_deleting_pending_contact_connection">Lỗi xóa kết nối liên hệ đang chờ xử lý</string>
<string name="migrate_from_device_error_exporting_archive">Lỗi xuất cơ sở dữ liệu SimpleX Chat</string>
<string name="error_encrypting_database">Lỗi mã hóa cơ sở dữ liệu</string>
<string name="error_enabling_delivery_receipts">Lỗi bật chỉ báo đã nhận!</string>
<string name="error_deleting_note_folder">Lỗi xóa ghi chú riêng tư</string>
<string name="error_deleting_user">Lỗi xóa hồ sơ người dùng</string>
<string name="error_importing_database">Lỗi nhập cơ sở dữ liệu SimpleX Chat</string>
<string name="error_exporting_chat_database">Lỗi xuất cơ sở dữ liệu SimpleX Chat</string>
<string name="migrate_to_device_error_downloading_archive">Lỗi tải xuống kho lưu trữ</string>
<string name="error_initializing_web_view">Lỗi khởi tạo WebView. Cập nhật hệ điều hành của bạn lên phiên bản mới. Vui lòng liên hệ với nhà phát triển.
\nLỗi: %s</string>
<string name="error_removing_member">Lỗi xóa thành viên</string>
<string name="error_with_info">Lỗi: %s</string>
<string name="unable_to_open_browser_title">Lỗi mở trình duyệt</string>
<string name="error_joining_group">Lỗi tham gia nhóm</string>
<string name="error_loading_details">Lỗi tải thông tin chi tiết</string>
<string name="error_receiving_file">Lỗi nhận tệp</string>
<string name="error_saving_group_profile">Lỗi lưu hồ sơ nhóm</string>
<string name="error_saving_file">Lỗi lưu tệp</string>
<string name="error_loading_smp_servers">Lỗi tải máy chủ SMP</string>
<string name="error_loading_xftp_servers">Lỗi tải máy chủ XFTP</string>
<string name="servers_info_reconnect_server_error">Lỗi kết nối lại máy chủ</string>
<string name="servers_info_reconnect_servers_error">Lỗi kết nối lại máy chủ</string>
<string name="servers_info_sessions_errors">Lỗi</string>
<string name="servers_info_reset_stats_alert_error_title">Lỗi khôi phục thống kê</string>
</resources>
@@ -19,10 +19,10 @@
<string name="accept">接受</string>
<string name="auth_unavailable">認證無效</string>
<string name="allow_verb">允許</string>
<string name="display_name__field">顯示名稱:</string>
<string name="display_name__field">個人資料名稱:</string>
<string name="full_name__field">全名:</string>
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>使用更多電量</b>通知服務長期在背景中運行 有效的訊息就會即時顯示在通知內。]]></string>
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>對電量友善</b>。通知服務於每十分鐘檢查一次訊息。你可能會錯過通話和迫切的訊息。]]></string>
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>使用更多電量</b>程式始終在背景中運行 通知會立即顯示。]]></string>
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>對電量友善</b>。程式每10分鐘檢查一次訊息。你可能會錯過電話或警急訊息。]]></string>
<string name="answer_call">回應通話請求</string>
<string name="clear_contacts_selection_button">清除</string>
<string name="allow_direct_messages">允許向群組內的成員傳送私訊。</string>
@@ -69,7 +69,7 @@
<string name="your_current_profile">你目前的個人檔案</string>
<string name="display_name_cannot_contain_whitespace">顯示的名稱中不能有空白。</string>
<string name="save_preferences_question">儲存設定?</string>
<string name="display_name">顯示名稱</string>
<string name="display_name">輸入你的名稱</string>
<string name="callstatus_error">通話出錯</string>
<string name="callstatus_calling">正在撥打…</string>
<string name="callstatus_in_progress">通話中</string>
@@ -130,7 +130,7 @@
<string name="create_secret_group_title">建立私密群組</string>
<string name="button_leave_group">退出群組</string>
<string name="group_member_status_connected">已連接</string>
<string name="group_display_name_field">群組顯示名稱:</string>
<string name="group_display_name_field">輸入群組名稱:</string>
<string name="group_full_name_field">群組全名:</string>
<string name="chat_preferences">對話設定</string>
<string name="chat_preferences_off">關閉</string>
@@ -153,7 +153,7 @@
<string name="group_preferences">群組設定</string>
<string name="contact_preferences">聯絡人設定</string>
<string name="share_image">分享媒體…</string>
<string name="both_you_and_your_contacts_can_delete">你和你的聯絡人都可以不可逆地刪除已傳送的訊息。</string>
<string name="both_you_and_your_contacts_can_delete">你和你的聯絡人都可以不可逆地刪除已傳送的訊息。</string>
<string name="server_connected">已連接</string>
<string name="simplex_link_mode_description">簡介</string>
<string name="simplex_link_mode_full">完整連結</string>
@@ -179,13 +179,13 @@
<string name="smp_servers_check_address">檢查輸入的伺服器地址,然後再試一次。</string>
<string name="chat_console">終端機對話</string>
<string name="star_on_github">於 Github 給個星星</string>
<string name="incognito_info_protects">匿名聊天模式會保護你的真實個人檔案名稱和頭像 — 當有新聯絡人的時候會自動建立一個隨機性的個人檔案</string>
<string name="incognito_info_protects">隱身模式透過為每個聯絡人使用新的隨機設定檔來保護您的隱私</string>
<string name="incognito_info_allows">這樣是允許每一個對話中擁有不同的顯示名稱,並且沒有任何的個人資料可用於分享或有機會外洩。</string>
<string name="allow_disappearing_messages_only_if">只有你的聯絡人允許的情況下,才允許自動銷毀訊息。</string>
<string name="allow_your_contacts_to_send_disappearing_messages">允許你的聯絡人傳送自動銷毀的訊息。</string>
<string name="allow_irreversible_message_deletion_only_if">只有你的聯絡人允許的情況下,才允許不可逆地將訊息刪除。</string>
<string name="allow_your_contacts_irreversibly_delete">允許你的聯絡人可以不可逆地刪除已發送的訊息。</string>
<string name="allow_to_delete_messages">允許不可撤銷的訊息刪除。</string>
<string name="allow_irreversible_message_deletion_only_if">只有你的聯絡人允許的情況下,才允許不可逆地將訊息刪除。(24小時)</string>
<string name="allow_your_contacts_irreversibly_delete">允許你的聯絡人不可逆地刪除已發送的訊息。(24小時)</string>
<string name="allow_to_delete_messages">允許不可逆地將已傳送的訊息刪除。(24小時)</string>
<string name="allow_to_send_voice">允許傳送語音訊息。</string>
<string name="delete_after">多久後刪除</string>
<string name="all_group_members_will_remain_connected">群組內所有成員會保持連接。</string>
@@ -231,9 +231,9 @@
<string name="v4_5_italian_interface_descr">感謝用戶 - 使用 Weblate 的翻譯貢獻!</string>
<string name="app_name">SimpleX</string>
<string name="thousand_abbreviation">k</string>
<string name="connect_via_contact_link">透過連結連接聯絡人?</string>
<string name="connect_via_invitation_link">透過邀請連結連接?</string>
<string name="connect_via_group_link">透過邀請連結連接群組?</string>
<string name="connect_via_contact_link">透過聯絡人地址連接</string>
<string name="connect_via_invitation_link">透過一次性連結連接?</string>
<string name="connect_via_group_link">加入群組?</string>
<string name="profile_will_be_sent_to_contact_sending_link">你的個人檔案將傳送給你接收此連結的聯絡人。</string>
<string name="you_will_join_group">你將加入此連結內的群組並且連接到此群組成為群組內的成員。</string>
<string name="connect_via_link_verb">連接</string>
@@ -509,7 +509,7 @@
<string name="callstate_ended">通話完結</string>
<string name="connect_button">連接</string>
<string name="network_and_servers">網路 &amp; 伺服器</string>
<string name="network_settings_title">網路設定</string>
<string name="network_settings_title">進階設定</string>
<string name="network_enable_socks">使用 SOCKS 代理伺服器</string>
<string name="save_and_notify_group_members">儲存並通知群組內的聯絡人</string>
<string name="exit_without_saving">退出並且不儲存記錄</string>
@@ -547,7 +547,8 @@
<string name="smp_servers_test_some_failed">有一些伺服器測試失敗:</string>
<string name="smp_servers_scan_qr">掃描伺服器的二維碼</string>
<string name="smp_servers_your_server">你的伺服器</string>
<string name="network_use_onion_hosts_required_desc">連接時需要使用 Onion 主機。</string>
<string name="network_use_onion_hosts_required_desc">連接時需要使用 Onion 主機。
\n請注意:如果沒有 .onion 地址,您將無法連接到伺服器。</string>
<string name="network_session_mode_user">對話檔案</string>
<string name="description_via_group_link">透過群組連結</string>
<string name="description_via_group_link_incognito">透過群組連結使用匿名聊天模式</string>
@@ -621,7 +622,7 @@
<string name="no_contacts_selected">沒有聯絡人可以選擇</string>
<string name="group_link">群組連結</string>
<string name="delete_link">刪除連結</string>
<string name="group_is_decentralized">群組是完全去中心化 - 只有群組內的成員能看到。</string>
<string name="group_is_decentralized">完全去中心化 - 只有成員能看到。</string>
<string name="prohibit_sending_disappearing">禁止傳送自動銷毀的訊息。</string>
<string name="ttl_hours">%d 個小時</string>
<string name="whats_new">更新內容</string>
@@ -643,7 +644,7 @@
<string name="save_group_profile">儲存群組檔案</string>
<string name="voice_prohibited_in_this_chat">語音訊息於這個聊天室是禁用的。</string>
<string name="v4_3_irreversible_message_deletion_desc">允許你的聯絡人可以完全刪除訊息。</string>
<string name="first_platform_without_user_ids">第一個沒有任何用戶識別符的通訊平台 – 以私隱為設計</string>
<string name="first_platform_without_user_ids">沒有用戶識別符</string>
<string name="next_generation_of_private_messaging">新一代的私密訊息平台</string>
<string name="decentralized">去中心化的</string>
<string name="people_can_connect_only_via_links_you_share">人們只能在你分享了連結後,才能和你連接。</string>
@@ -652,10 +653,10 @@
<string name="how_it_works">這是如何運作</string>
<string name="onboarding_notifications_mode_subtitle">你可以之後透過設定修改。</string>
<string name="make_private_connection">私下連接</string>
<string name="opensource_protocol_and_code_anybody_can_run_servers">開放源碼協議和程式碼 任何人可以運行伺服器。</string>
<string name="opensource_protocol_and_code_anybody_can_run_servers">任何人可以託管伺服器。</string>
<string name="ignore">無視</string>
<string name="incoming_audio_call">語音通話來電</string>
<string name="paste_the_link_you_received">貼上你收到的連結</string>
<string name="paste_the_link_you_received">貼上你收到的連結</string>
<string name="status_e2e_encrypted">端對端加密</string>
<string name="status_no_e2e_encryption">沒有端對端加密</string>
<string name="icon_descr_speaker_off">關閉喇叭</string>
@@ -757,7 +758,7 @@
<string name="message_deletion_prohibited">不可逆地刪除訊息於這個聊天室內是禁用的。</string>
<string name="only_you_can_send_voice">只有你可以傳送語音訊息。</string>
<string name="direct_messages_are_prohibited_in_chat">私訊群組內的成員於這個群組內是禁用的。</string>
<string name="group_members_can_delete">群組內的成員可以不可逆地刪除訊息。</string>
<string name="group_members_can_delete">群組內的成員可以不可逆地刪除訊息。24小時)</string>
<string name="v4_3_voice_messages">語音訊息</string>
<string name="v4_3_improved_server_configuration">改善伺服器配置</string>
<string name="v4_3_improved_privacy_and_security_desc">當你切換至最近應用程式版面時,無法預覽程式畫面。</string>
@@ -828,8 +829,8 @@
<string name="feature_enabled">已啟用</string>
<string name="feature_enabled_for_you">已為你啟用</string>
<string name="feature_enabled_for_contact">已為聯絡人啟用</string>
<string name="only_you_can_delete_messages">只有你能不可逆地刪除訊息(你的聯絡人可以將它標記為刪除)。</string>
<string name="only_your_contact_can_delete">只有你的聊絡人可以不可逆的刪除訊息(你可以將它標記為刪除)。</string>
<string name="only_you_can_delete_messages">只有你能不可逆地刪除訊息(你的聯絡人可以將它標記為刪除)。24小時)</string>
<string name="only_your_contact_can_delete">只有你的聊絡人可以不可逆的刪除訊息(你可以將它標記為刪除)。24小時)</string>
<string name="only_your_contact_can_send_voice">只有你的聯絡人可以傳送語音訊息。</string>
<string name="prohibit_direct_messages">禁止私訊群組內的成員。</string>
<string name="message_deletion_prohibited_in_chat">不可逆地刪除訊息於這個群組內是禁用的。</string>
@@ -899,7 +900,7 @@
<string name="icon_descr_expand_role">添加更多身份選項</string>
<string name="icon_descr_context">聯絡人頭像</string>
<string name="icon_descr_profile_image_placeholder">個人檔案頭像占位符</string>
<string name="immune_to_spam_and_abuse">不受垃圾郵件和濫用行為影響</string>
<string name="immune_to_spam_and_abuse">不受垃圾和騷擾訊息影響</string>
<string name="contact_wants_to_connect_via_call">%1$s 希望透過以下方式聯絡你</string>
<string name="icon_descr_video_on">開啟視訊</string>
<string name="icon_descr_flip_camera">翻轉相機</string>
@@ -908,7 +909,7 @@
<string name="your_calls">你的通話</string>
<string name="always_use_relay">經由分程傳遞連接</string>
<string name="call_on_lock_screen">在上鎖畫面顯示來電通知:</string>
<string name="integrity_msg_skipped">%1$d 你錯過了多個訊息</string>
<string name="integrity_msg_skipped">%1$d 條訊息已跳過</string>
<string name="integrity_msg_bad_hash">錯誤的訊息雜湊值</string>
<string name="alert_title_skipped_messages">你錯過了多個訊息</string>
<string name="settings_section_title_you"></string>
@@ -1103,7 +1104,7 @@
<string name="alert_text_decryption_error_n_messages_failed_to_decrypt">%1$d 訊息解密失敗。</string>
<string name="network_socks_toggle_use_socks_proxy">使用SOCKS 代理伺服器</string>
<string name="your_XFTP_servers">你的 XFTP 伺服器</string>
<string name="alert_text_decryption_error_too_many_skipped">%1$d 錯過了多個訊息</string>
<string name="alert_text_decryption_error_too_many_skipped">%1$d 條訊息已跳過</string>
<string name="v5_0_large_files_support">影片和檔案和最大上限為1gb</string>
<string name="gallery_video_button">影片</string>
<string name="submit_passcode">呈交</string>
@@ -1111,7 +1112,7 @@
<string name="learn_more">查看更多</string>
<string name="simplex_address">SimpleX 聯絡地址</string>
<string name="one_time_link_short">一次性連結</string>
<string name="theme_colors_section_title">主題顏色</string>
<string name="theme_colors_section_title">介面顏色</string>
<string name="create_simplex_address">建立 SimpleX 的聯絡地址</string>
<string name="profile_update_will_be_sent_to_contacts">更新了的個人檔案將傳送給你的聯絡人。</string>
<string name="share_address_with_contacts_question">與你的聯絡人分享聯絡地址?</string>
@@ -1140,7 +1141,7 @@
<string name="color_sent_message">已傳送訊息</string>
<string name="color_title">標題</string>
<string name="learn_more_about_address">關於 SimpleX 的聯絡地址</string>
<string name="color_primary_variant">外加的顏</string>
<string name="color_primary_variant">額外的強調</string>
<string name="color_secondary_variant">外加的輔助</string>
<string name="address_section_title">聯絡地址</string>
<string name="color_background">後台</string>
@@ -1241,4 +1242,563 @@
\n- 編輯紀錄。</string>
<string name="search_verb">搜尋</string>
<string name="la_mode_off">已關閉</string>
<string name="v5_8_safe_files_descr">確認來自未知伺服器的檔案。</string>
<string name="snd_error_quota">超出額度 - 收件人未收到先前傳送的訊息</string>
<string name="v5_6_app_data_migration">應用程式資料轉移</string>
<string name="migrate_to_device_apply_onion">應用</string>
<string name="migrate_from_device_confirm_you_remember_passphrase">請在轉移之前確認你還記得數據庫密碼</string>
<string name="blocked_by_admin_item_description">被管理員封鎖</string>
<string name="wallpaper_advanced_settings">進階設定</string>
<string name="v5_4_block_group_members">封鎖群組成員</string>
<string name="servers_info_subscriptions_connections_subscribed">活躍連接</string>
<string name="abort_switch_receiving_address_confirm">中止</string>
<string name="rcv_group_and_other_events">和其他 %d 事件</string>
<string name="block_member_question">封鎖成員?</string>
<string name="v5_3_new_interface_languages">6種全新的介面語言</string>
<string name="audio_device_bluetooth">藍芽</string>
<string name="moderated_items_description">%2$s 審核了 %1$d 條訊息</string>
<string name="blocked_item_description">已封鎖</string>
<string name="abort_switch_receiving_address_desc">將停止地址更改。將使用舊聯絡地址。</string>
<string name="app_check_for_updates_beta">測試</string>
<string name="app_check_for_updates">檢查更新</string>
<string name="permissions_camera_and_record_audio">相機和麥克風</string>
<string name="block_member_confirmation">封鎖</string>
<string name="theme_destination_app_theme">應用程式主題</string>
<string name="feature_roles_admins">管理員</string>
<string name="v6_0_privacy_blur">模糊以增強隱私</string>
<string name="feature_roles_all_members">所有成員</string>
<string name="v5_6_safer_groups_descr">管理員可以為所有人封鎖一名成員</string>
<string name="cannot_share_message_alert_title">無法傳送訊息</string>
<string name="block_for_all_question">為所有成員封鎖此成員?</string>
<string name="theme_black"></string>
<string name="abort_switch_receiving_address_question">中止更改地址?</string>
<string name="cant_send_message_to_member_alert_title">無法傳送訊息給群組成員</string>
<string name="chat_theme_apply_to_all_modes">所有顏色模式</string>
<string name="chat_theme_apply_to_mode">應用到</string>
<string name="la_app_passcode">應用程式密碼</string>
<string name="settings_section_title_app">應用程式</string>
<string name="settings_section_title_chat_colors">聊天顏色</string>
<string name="chat_is_stopped_you_should_transfer_database">聊天已停止。如果你已經在另一台設備使用過此資料庫,你應該在啟動聊天前將數據庫傳輸回來。</string>
<string name="in_developing_title">即將推出!</string>
<string name="app_check_for_updates_download_completed_title">軟體更新以下載</string>
<string name="v6_0_your_contacts_descr">儲存聯絡人以便稍後聊天</string>
<string name="permissions_camera">相機</string>
<string name="choose_file_title">選擇一個檔案</string>
<string name="migrate_from_device_archive_and_upload">存檔並上傳</string>
<string name="migrate_from_device_all_data_will_be_uploaded">你的所有聯絡人、對話和檔案將被安全加密並切塊上傳到你設定的 XFTP 中繼</string>
<string name="migrate_from_device_archiving_database">正在儲存資料庫</string>
<string name="migrate_from_device_cancel_migration">取消遷移</string>
<string name="snd_conn_event_ratchet_sync_started">與 %s 協調加密中…</string>
<string name="turn_off_battery_optimization_button">允許</string>
<string name="call_service_notification_audio_call">語音通話</string>
<string name="camera_not_available">相機不可用</string>
<string name="clear_note_folder_warning">所有訊息都將被刪除 - 這無法復原</string>
<string name="socks_proxy_setting_limitations"><![CDATA[<b>請注意</b>:訊息和檔案中繼通過 SOCKS 代理連接。通話和傳送連預覽使用直接連接。]]></string>
<string name="block_for_all">封鎖全部</string>
<string name="v5_4_better_groups">改進群組功能</string>
<string name="network_type_cellular">行動網路</string>
<string name="block_member_button">封鎖成員</string>
<string name="migrate_from_device_archive_will_be_deleted"><![CDATA[<b>警告</b>:此存檔將被刪除。]]></string>
<string name="clear_note_folder_question">清除私密筆記?</string>
<string name="add_contact_tab">添加聯絡人</string>
<string name="network_smp_proxy_mode_always">總是</string>
<string name="conn_event_ratchet_sync_started">協調加密中…</string>
<string name="allow_to_send_files">允許傳送檔案和媒體</string>
<string name="allow_to_send_simplex_links">允許傳送 SimpleX 連結</string>
<string name="v5_2_more_things">其他</string>
<string name="connect_plan_already_connecting">已連接!</string>
<string name="abort_switch_receiving_address">中止更改地址</string>
<string name="connect__a_new_random_profile_will_be_shared">將分享新的隨機個人檔案</string>
<string name="block_member_desc">所有來自 %s 的新訊息都將被隱藏!</string>
<string name="rcv_group_event_member_blocked">已封鎖 %s</string>
<string name="group_member_role_author">作者</string>
<string name="member_info_member_blocked">已封鎖</string>
<string name="member_blocked_by_admin">被管理員封鎖</string>
<string name="color_primary_variant2">額外的強調色2</string>
<string name="v5_3_new_interface_languages_descr">阿拉伯語、保加利亞語、芬蘭語、希伯來語、泰國語和烏克蘭語——感謝使用者們與Weblate</string>
<string name="connect_plan_already_joining_the_group">已加入群組!</string>
<string name="migrate_to_device_confirm_network_settings">確認網路設定</string>
<string name="attempts_label">嘗試</string>
<string name="acknowledged">已確認</string>
<string name="acknowledgement_errors">確認錯誤</string>
<string name="completed">完成</string>
<string name="chunks_deleted">區塊已刪除</string>
<string name="chunks_uploaded">區塊已上傳</string>
<string name="chunks_downloaded">區塊已下載</string>
<string name="add_contact_button_to_create_link_or_connect_via_link"><![CDATA[<b>添加聯絡人</b>: 來創建新的邀請連結,或通過你收到的連結進行連接。]]></string>
<string name="create_group_button_to_create_new_group"><![CDATA[<b>建立群組</b>: 建立新的群組。]]></string>
<string name="bad_desktop_address">錯誤的桌面地址</string>
<string name="migrate_to_device_chat_migrated">已轉移聊天</string>
<string name="migrate_from_device_choose_migrate_from_another_device"><![CDATA[在新的設備上選擇 <i>從另一部設備轉移</i> 並掃描QR code。]]></string>
<string name="migrate_from_device_using_on_two_device_breaks_encryption"><![CDATA[<b>請注意</b>: 作為安全保護措施,在兩部設備上使用同一數據庫會破壞解密來自你聯絡人的訊息。]]></string>
<string name="confirm_delete_contact_question">確定刪除聯絡人?</string>
<string name="app_check_for_updates_notice_title">檢查更新</string>
<string name="cant_call_contact_alert_title">無法與聯絡人通話</string>
<string name="calls_prohibited_alert_title">通話被禁止!</string>
<string name="cant_call_member_alert_title">無法與群組成員通話</string>
<string name="v5_3_encrypt_local_files_descr">應用程式將為新的本機檔案(影片除外)加密。</string>
<string name="migrate_from_device_check_connection_and_try_again">檢查你的網路連接並重試</string>
<string name="all_users">所有配置文件</string>
<string name="smp_servers_configured">已設定的 SMP 伺服器</string>
<string name="settings_section_title_chat_theme">聊天主題</string>
<string name="info_view_call_button">通話</string>
<string name="network_smp_proxy_fallback_allow_downgrade">允許降級</string>
<string name="network_smp_proxy_mode_always_description">始終使用私密路由。</string>
<string name="chat_database_exported_title">以導出聊天資料庫</string>
<string name="xftp_servers_configured">已設定的 XFTP 伺服器</string>
<string name="color_mode">色彩模式</string>
<string name="deleted_chats">已儲存的聯絡人</string>
<string name="privacy_media_blur_radius">模糊媒體</string>
<string name="allow_calls_question">允許通話?</string>
<string name="share_text_created_at">建立於:%s</string>
<string name="error_initializing_web_view">Webview 初始化失敗。更新你的系統到新版本。請聯繫開發者。
\n錯誤:%s</string>
<string name="rcv_direct_event_contact_deleted">已刪除聯絡人</string>
<string name="rcv_group_events_count">%d 個群事件</string>
<string name="message_too_large">訊息太大</string>
<string name="message_delivery_warning_title">訊息傳送警告</string>
<string name="ci_status_other_error">錯誤:%1$s</string>
<string name="developer_options_section">開發者選項</string>
<string name="snd_conn_event_ratchet_sync_required">與 %s 的加密需要重協商</string>
<string name="remote_host_error_inactive"><![CDATA[行動裝置 <b>%s</b> 不活躍]]></string>
<string name="favorite_chat">最喜歡</string>
<string name="v5_2_message_delivery_receipts">訊息成功送達!</string>
<string name="files_and_media">檔案和媒體</string>
<string name="remote_ctrl_was_disconnected_title">連線停止</string>
<string name="remote_host_error_bad_state"><![CDATA[與行動裝置 \u0020<b>%s</b>的連接不穩定]]></string>
<string name="receipts_section_contacts">聯絡人</string>
<string name="wallpaper_scale_fit">適合</string>
<string name="group_members_can_send_files">群組成員可以傳送檔案和媒體。</string>
<string name="linked_mobiles">連結行動裝置</string>
<string name="files_are_prohibited_in_group">此群組禁止檔案和媒體</string>
<string name="call_service_notification_end_call">結束通話</string>
<string name="delete_messages__question">刪除 %d 條訊息嗎?</string>
<string name="privacy_message_draft">訊息草稿</string>
<string name="conn_event_ratchet_sync_allowed">允許重新協商加密</string>
<string name="info_row_created_at">建立於</string>
<string name="error_blocking_member_for_all">為所有人封鎖時出錯</string>
<string name="desktop_app_version_is_incompatible">桌面應用版本 %s 與此應用不相容</string>
<string name="file_error_no_file">未找到檔案 - 檔案可能被刪除或被取消了</string>
<string name="file_error_relay">檔案伺服器錯誤:%1$s</string>
<string name="expand_verb">展開</string>
<string name="receipts_groups_enable_keep_overrides">啟用(保留組覆蓋)</string>
<string name="color_mode_light">淺色</string>
<string name="chat_theme_apply_to_light_mode">淺色模式</string>
<string name="group_members_can_send_simplex_links">群組成員可傳送 SimpleX 連結。</string>
<string name="color_mode_dark">深色</string>
<string name="servers_info_details">詳情</string>
<string name="servers_info_subscriptions_section_header">訊息接收</string>
<string name="error_parsing_uri_title">無效連結</string>
<string name="marked_deleted_items_description">%d 條訊息被標記為刪除</string>
<string name="blocked_items_description">%d 條訊息已攔截</string>
<string name="smp_proxy_error_broker_host">轉發伺服器地址不相容網路設定:%1$s。</string>
<string name="smp_proxy_error_broker_version">轉發伺服器地址不相容網路設定:%1$s。</string>
<string name="proxy_destination_error_broker_host">%1$s 的目標伺服器地址不相容轉送伺服器 %2$s 的設定</string>
<string name="proxy_destination_error_broker_version">%1$s 的目地伺服器版本不相容於轉送伺服器 %2$s.</string>
<string name="disable_notifications_button">關閉通知</string>
<string name="snd_error_expired">網路問題 - 多次嘗試傳送訊息後,訊息已過期。</string>
<string name="snd_error_proxy_relay">轉發伺服器:%1$s
\n目標伺服器錯誤:%2$s</string>
<string name="member_inactive_desc">如果成員變得活躍,可能會在之後傳送訊息。</string>
<string name="contact_deleted">刪除了聯絡人!</string>
<string name="delete_contact_cannot_undo_warning">聯絡人將被刪除 - 無法復原此操作</string>
<string name="network_smp_proxy_fallback_prohibit"></string>
<string name="app_check_for_updates_disabled">已停用</string>
<string name="app_check_for_updates_installed_successfully_title">安裝成功</string>
<string name="create_address_button">建立</string>
<string name="unable_to_open_browser_title">打開瀏覽器出錯</string>
<string name="receipts_contacts_enable_keep_overrides">啟用(保留覆蓋)</string>
<string name="receipts_groups_disable_keep_overrides">禁用(保留組覆蓋)</string>
<string name="receipts_groups_title_enable">為群組啟用回執?</string>
<string name="settings_section_title_network_connection">網路連接</string>
<string name="chat_database_exported_continue">繼續</string>
<string name="info_row_file_status">檔案狀態</string>
<string name="dark_mode_colors">深色模式顏色</string>
<string name="appearance_font_size">字體大小</string>
<string name="feature_enabled_for">啟用於</string>
<string name="v5_7_new_interface_languages">立陶宛語使用者介面</string>
<string name="v5_8_chat_themes">新的聊天主題</string>
<string name="v6_0_connection_servers_status_descr">連線和伺服器狀態</string>
<string name="v6_0_connection_servers_status">控制你的網路</string>
<string name="v6_0_upgrade_app_descr">從GitHub下載最新版本。</string>
<string name="enable_receipts_all">啟用</string>
<string name="v6_0_new_chat_experience">新的聊天體驗 🎉</string>
<string name="v6_0_new_media_options">新的媒體選項</string>
<string name="connected_mobile">以連接的行動裝置</string>
<string name="connected_desktop">連接桌面</string>
<string name="connected_to_desktop">連接到桌面</string>
<string name="desktop_connection_terminated">連線終止</string>
<string name="connect_to_desktop">連接到桌面</string>
<string name="migrate_from_device_error_uploading_archive">上傳存檔出錯</string>
<string name="migrate_to_device_file_delete_or_link_invalid">文件被刪除或鏈接無效</string>
<string name="migrate_to_device_import_failed">導入失敗</string>
<string name="audio_device_wired_headphones">頭戴式耳機</string>
<string name="audio_device_earpiece">耳機</string>
<string name="receipts_contacts_disable_for_all">對所有聯絡人關閉</string>
<string name="chat_theme_apply_to_dark_mode">深色模式</string>
<string name="error_enabling_delivery_receipts">啟用已讀回條時出錯!</string>
<string name="this_device_version"><![CDATA[<i>(此裝置 v%s)</i>]]></string>
<string name="desktop_incompatible_version">不相容的版本</string>
<string name="remote_ctrl_error_disconnected">PC版已斷線</string>
<string name="migrate_from_device_title">轉移裝置</string>
<string name="v5_7_call_sounds">通話鈴聲</string>
<string name="v5_7_forward">轉發並保存訊息</string>
<string name="v5_7_forward_descr">訊息來源保持私密</string>
<string name="no_connected_mobile">沒有已連接的行動裝置</string>
<string name="files_and_media_prohibited">禁止檔案和媒體!</string>
<string name="loading_remote_file_title">檔案載入中</string>
<string name="file_error">檔案錯誤</string>
<string name="update_network_smp_proxy_fallback_question">備用訊息路由</string>
<string name="network_smp_proxy_fallback_prohibit_description">如果你或你的目標伺服器不支持私密路由,將不直接傳送訊息。</string>
<string name="create_another_profile_button">建立個人資料</string>
<string name="migrate_from_another_device">從另一台裝置轉移</string>
<string name="profile_update_event_member_name_changed">成員姓名從 %1$s 改為了 %2$s</string>
<string name="conn_event_ratchet_sync_agreed">同意加密</string>
<string name="info_row_message_status">訊息狀態</string>
<string name="connect_via_member_address_alert_desc">連接請求將傳送給該組成員。</string>
<string name="v5_2_more_things_descr">- 更穩定的消息傳送。
\n- 更好的群組。
\n- 還有更多!</string>
<string name="v5_5_new_interface_languages">匈牙利語和土耳其語用戶界面</string>
<string name="migrate_from_device_migration_complete">轉移完成</string>
<string name="migrate_from_device_delete_database_from_device">從此裝置刪除數據庫</string>
<string name="delivery">傳送</string>
<string name="download_file">下載</string>
<string name="forward_chat_item">轉發</string>
<string name="forwarded_chat_item_info_tab">已轉發</string>
<string name="forwarded_from_chat_item_info_title">轉發自</string>
<string name="files_and_media_not_allowed">不允許檔案和媒體</string>
<string name="forward_message">轉發訊息…</string>
<string name="creating_link">建立連結中…</string>
<string name="keep_invitation_link">保留</string>
<string name="profile_update_event_contact_name_changed">聯絡人姓名從 %1$s 改為了 %2$s</string>
<string name="new_message">新訊息</string>
<string name="invite_friends_short">邀請</string>
<string name="receipts_contacts_disable_keep_overrides">停用(保留覆蓋)</string>
<string name="share_text_message_status">訊息狀態:%s</string>
<string name="message_queue_info">訊息隊列資訊</string>
<string name="servers_info_messages_received">收到的訊息</string>
<string name="encrypt_local_files">加密本機檔案</string>
<string name="settings_section_title_files">檔案</string>
<string name="receipts_groups_disable_for_all">對所有群組關閉</string>
<string name="wallpaper_scale_fill">填充</string>
<string name="v5_8_chat_themes_descr">讓你的聊天看上去不相同!</string>
<string name="v6_0_increase_font_size">增大字體大小。</string>
<string name="migrate_to_device_enter_passphrase">輸入密碼短語</string>
<string name="servers_info_messages_sent">傳送的訊息</string>
<string name="remote_ctrl_error_busy">PC版處理中</string>
<string name="connect_via_link_incognito">隱身模式連接</string>
<string name="conversation_deleted">已刪除對話!</string>
<string name="snd_error_relay">目標伺服器錯誤:%1$s</string>
<string name="loading_chats">聊天載入中…</string>
<string name="message_forwarded_title">已轉發的訊息</string>
<string name="blocked_by_admin_items_description">管理員封鎖了 %d 條訊息</string>
<string name="smp_proxy_error_connecting">連結轉發伺服器 %1$s 出錯。請稍候嘗試。</string>
<string name="migrate_from_device_error_deleting_database">刪除資料庫出錯</string>
<string name="snd_error_proxy">轉發伺服器:%1$s
\n錯誤:%2$s</string>
<string name="proxy_destination_error_failed_to_connect">轉發伺服器 %1$s 連結目標伺服器 %2$s 失敗。請稍後嘗試。</string>
<string name="migrate_to_device_importing_archive">導入存檔中</string>
<string name="v5_8_message_delivery">改進訊息傳送</string>
<string name="app_check_for_updates_button_install">安裝更新</string>
<string name="v6_0_private_routing_descr">它保護你的 IP 位址和連線。</string>
<string name="v5_5_join_group_conversation">加入群組對話</string>
<string name="remote_host_error_bad_version"><![CDATA[不支援行動裝置 <b>%s</b> 的版本。請檢察兩台裝置安裝的是否版本相同]]></string>
<string name="v5_7_network_descr">更可靠的網路連接</string>
<string name="v5_3_discover_join_groups">發現和加入群組</string>
<string name="devices">裝置</string>
<string name="new_mobile_device">新行動裝置</string>
<string name="migrate_from_device_error_saving_settings">保存設定出錯</string>
<string name="migrate_from_device_exported_file_doesnt_exist">導出的檔案不存在</string>
<string name="migrate_from_device_error_exporting_archive">導出資料庫時出錯</string>
<string name="migrate_from_device_confirm_upload">確認上傳</string>
<string name="migrate_from_device_creating_archive_link">正在建立存檔連結</string>
<string name="conn_event_ratchet_sync_ok">加密OK</string>
<string name="unblock_member_desc">將顯示來自 %s 的訊息!</string>
<string name="delivery_receipts_title">送達回執!</string>
<string name="forwarded_description">已轉發</string>
<string name="e2ee_info_no_pq"><![CDATA[訊息、檔案和通話均受到<b>端對端加密</b>的保護,並具有完全的前向加密、不可否認性和入侵恢復。]]></string>
<string name="encryption_renegotiation_error">加密協商錯誤</string>
<string name="e2ee_info_pq"><![CDATA[訊息、檔案和通話受到完全前向加密、不可否認性和入侵恢復的<b>抗量子端對端加密</b>保護。]]></string>
<string name="alert_text_encryption_renegotiation_failed">加密重協商失敗</string>
<string name="database_encryption_will_be_updated_in_settings">將更新資料庫密碼並儲存在設定中。</string>
<string name="v5_4_incognito_groups_descr">使用隨機身分建立群組</string>
<string name="v5_4_better_groups_descr">加入速度更快、訊息更可靠。</string>
<string name="v5_4_incognito_groups">匿名群組</string>
<string name="link_a_mobile">連接行動裝置</string>
<string name="in_reply_to">回復</string>
<string name="connect_with_contact_name_question">和 %1$s 連接?</string>
<string name="v5_3_new_desktop_app_descr">在桌面應用裡建立新的帳號。💻</string>
<string name="enter_this_device_name">輸入此裝置名稱…</string>
<string name="connected_to_mobile">已連結到行動裝置</string>
<string name="multicast_discoverable_via_local_network">可通過局域網發現</string>
<string name="new_desktop"><![CDATA[<i>(新)</i>]]></string>
<string name="agent_critical_error_title">嚴重錯誤</string>
<string name="agent_internal_error_title">內部錯誤</string>
<string name="migrate_from_device_error_verifying_passphrase">驗證密碼短語出錯:</string>
<string name="failed_to_create_user_invalid_title">顯示名稱無效!</string>
<string name="non_content_uri_alert_title">無效的檔案路徑</string>
<string name="v5_2_favourites_filter_descr">過濾未讀和收藏的聊天記錄。</string>
<string name="disconnect_remote_host">斷開連結</string>
<string name="disconnect_desktop_question">斷開桌面連結?</string>
<string name="error_aborting_address_change">中止地址更改時出錯</string>
<string name="error_showing_desktop_notification">顯示通知出錯,請聯繫開發者。</string>
<string name="delete_and_notify_contact">刪除並通知聯絡人</string>
<string name="update_network_smp_proxy_mode_question">訊息路由模式</string>
<string name="network_smp_proxy_mode_never_description">不使用私密路由。</string>
<string name="permissions_grant">要進行通話請授予一項或多項權限</string>
<string name="permissions_find_in_settings_and_grant">在 Android 系統設定中找到此權限並手動授予權限。</string>
<string name="permissions_grant_in_settings">在系統設定中授予</string>
<string name="error_sending_message_contact_invitation">傳送邀請出錯</string>
<string name="error_creating_member_contact">建立聯絡人時出錯</string>
<string name="v5_2_disappear_one_message">移除一條訊息</string>
<string name="v5_2_fix_encryption">保持連接</string>
<string name="v5_3_discover_join_groups_descr">- 連接到目錄服務(BETA)!
\n- 發送回執(最多20名成員)。
\n- 更快,更穩定。</string>
<string name="v5_4_link_mobile_desktop">連接行動端和桌面端應用程式! 🔗</string>
<string name="v5_5_message_delivery">改進訊息傳送</string>
<string name="delivery_receipts_are_disabled">已關閉送達回執!</string>
<string name="remote_host_was_disconnected_toast"><![CDATA[行動裝置 <b>%s</b> 斷開連接]]></string>
<string name="remote_host_error_missing"><![CDATA[行動裝置 <b>%s</b> 未找到]]></string>
<string name="migrate_to_device_downloading_archive">存檔下載中</string>
<string name="migrate_to_device_migrating">轉移中</string>
<string name="migrate_to_device_download_failed">下載失敗</string>
<string name="receipts_groups_enable_for_all">為所有組啟用</string>
<string name="conn_event_ratchet_sync_required">需要重協商加密</string>
<string name="send_receipts_disabled">關閉</string>
<string name="fix_connection">修復連結</string>
<string name="fix_connection_not_supported_by_contact">修復聯絡人不支援的問題</string>
<string name="fix_connection_confirm">修復</string>
<string name="fix_connection_question">修復連結?</string>
<string name="database_migration_in_progress">正在進行資料庫轉移。
\n可能需要幾分鐘時間。</string>
<string name="error_creating_message">建立訊息出錯</string>
<string name="error_deleting_note_folder">刪除私密筆記錯誤</string>
<string name="enable_camera_access">啟用相機訪問</string>
<string name="new_chat">新聊天</string>
<string name="receipts_contacts_enable_for_all">為所有人啟用</string>
<string name="error_synchronizing_connection">同步連接時出錯</string>
<string name="error_showing_content">顯示內容出錯</string>
<string name="error_showing_message">顯示訊息出錯</string>
<string name="error_alert_title">錯誤</string>
<string name="system_restricted_background_in_call_title">無後台通話</string>
<string name="create_chat_profile">建立聊天資料</string>
<string name="snd_conn_event_ratchet_sync_agreed">已同意 %s 的加密</string>
<string name="snd_conn_event_ratchet_sync_allowed">允許重新協商與 %s 的加密</string>
<string name="snd_conn_event_ratchet_sync_ok">與 %s 的加密OK</string>
<string name="desktop_devices">桌面設備</string>
<string name="linked_desktop_options">連接桌面選項</string>
<string name="linked_desktops">連接桌面</string>
<string name="rcv_group_event_member_created_contact">直接連線中</string>
<string name="action_button_add_members">邀請</string>
<string name="create_group_button">建立群組</string>
<string name="fix_connection_not_supported_by_group_member">修復群組成員不支援的問題</string>
<string name="v6_0_connect_faster_descr">更快地連接到你的好友</string>
<string name="v6_0_delete_many_messages_descr">最多同時刪除20條訊息</string>
<string name="remote_ctrl_error_inactive">PC版非活躍</string>
<string name="servers_info_connected_servers_section_header">已連接的伺服器</string>
<string name="servers_info_detailed_statistics">詳細統計數據</string>
<string name="member_info_member_disabled">已停用</string>
<string name="member_info_member_inactive">不活躍</string>
<string name="connect_via_member_address_alert_title">直接連接?</string>
<string name="wallpaper_preview_hello_alice">午安!</string>
<string name="wallpaper_preview_hello_bob">早安!</string>
<string name="disable_sending_recent_history">不向新成員傳送歷史訊息</string>
<string name="recent_history_is_not_sent_to_new_members">未發送歷史訊息給新成員。</string>
<string name="v5_6_quantum_resistant_encryption_descr">在私聊中開啟(測試版)!</string>
<string name="v5_6_app_data_migration_descr">透過QR code轉移到另一部裝置。</string>
<string name="dont_enable_receipts">不啟用</string>
<string name="error">錯誤</string>
<string name="remote_host_was_disconnected_title">連線停止</string>
<string name="remote_host_disconnected_from"><![CDATA[和移動裝置<b>%s</b>的連結斷開,原因是:%s]]></string>
<string name="remote_ctrl_disconnected_with_reason">斷線原因:%s</string>
<string name="disconnect_remote_hosts">斷開行動裝置連接</string>
<string name="desktop_address">桌面地址</string>
<string name="discover_on_network">通過局域網發現</string>
<string name="remote_host_error_busy"><![CDATA[行動裝置 <b>%s</b> 處理中]]></string>
<string name="remote_host_error_disconnected"><![CDATA[行動裝置 <b>%s</b> 斷開連接]]></string>
<string name="migrate_to_device_downloading_details">下載連結詳情中</string>
<string name="connect_plan_group_already_exists">群組已存在!</string>
<string name="servers_info_modal_error_title">錯誤</string>
<string name="servers_info_downloaded">已下載</string>
<string name="servers_info_reset_stats_alert_error_title">重製統計數據出錯</string>
<string name="expired_label">已過期</string>
<string name="connections">連接數</string>
<string name="created">已建立</string>
<string name="deletion_errors">刪除錯誤</string>
<string name="decryption_errors">解密出錯</string>
<string name="deleted">已刪除</string>
<string name="downloaded_files">已下載的檔案</string>
<string name="download_errors">下載出錯</string>
<string name="possible_slow_function_desc">功能執行所花費的時間過長:%1$d 秒:%2$s</string>
<string name="invalid_name">無效名稱</string>
<string name="correct_name_to">正確名字為 %s?</string>
<string name="copy_error">複製錯誤</string>
<string name="connecting_to_desktop">正在連接到桌面</string>
<string name="found_desktop">找到桌面</string>
<string name="multicast_connect_automatically">自動連接</string>
<string name="remote_ctrl_error_bad_state">與PC版的連接不穩定</string>
<string name="desktop_device">桌面</string>
<string name="remote_ctrl_error_bad_version">已安裝的PC版本不支援。請確認兩台裝置所安裝的版本相同</string>
<string name="remote_ctrl_error_bad_invitation">PC版邀請碼錯誤</string>
<string name="connect_plan_connect_via_link">通過連結連接?</string>
<string name="connect_plan_join_your_group">加入你的群組嗎?</string>
<string name="migrate_to_device_title">轉移到此處</string>
<string name="invalid_file_link">無效連結</string>
<string name="migrate_to_device_finalize_migration">在另一部設備上完成轉移</string>
<string name="migrate_to_device_error_downloading_archive">下載存檔錯誤</string>
<string name="migrate_from_device_to_another_device">轉移到另一部裝置</string>
<string name="migrate_from_device_chat_should_be_stopped">必須停止聊天才能繼續。</string>
<string name="keep_conversation">保留對話</string>
<string name="delete_without_notification">不通知刪除</string>
<string name="invalid_qr_code">無效的QR code</string>
<string name="keep_unused_invitation_question">保留未使用的邀請嗎?</string>
<string name="receipts_contacts_title_disable">停用回執?</string>
<string name="receipts_contacts_title_enable">啟用回執?</string>
<string name="cant_call_contact_connecting_wait_alert_text">正在連接聯絡人,請等待或稍後檢查!</string>
<string name="cant_call_contact_deleted_alert_text">聯絡人被刪除了。</string>
<string name="info_row_debug_delivery">傳送調試</string>
<string name="v5_3_encrypt_local_files">為儲存的檔案和媒體加密</string>
<string name="connect_plan_connect_to_yourself">連接到你自己?</string>
<string name="migrate_from_device_finalize_migration">完成轉移</string>
<string name="current_user">目前配置文件</string>
<string name="servers_info_files_tab">檔案</string>
<string name="servers_info_reconnect_server_error">重連伺服器出錯</string>
<string name="servers_info_reconnect_servers_error">重連伺服器出錯</string>
<string name="duplicates_label">重複</string>
<string name="share_text_file_status">檔案狀態:%s</string>
<string name="permissions_required">授予權限</string>
<string name="permissions_record_audio">麥克風</string>
<string name="database_will_be_encrypted_and_passphrase_stored_in_settings">資料庫將被加密,密碼將儲存在設定中</string>
<string name="delete_members_messages__question">刪除成員的 %d 條訊息嗎?</string>
<string name="member_inactive_title">成員非活躍</string>
<string name="compose_message_placeholder">輸入訊息</string>
<string name="delete_messages_mark_deleted_warning">訊息將被標記為刪除。收信人可以揭示這些訊息。</string>
<string name="info_view_connect_button">連接</string>
<string name="info_view_message_button">訊息</string>
<string name="app_check_for_updates_notice_disable">停用</string>
<string name="app_check_for_updates_download_started">下載更新中,請不要關閉應用</string>
<string name="app_check_for_updates_button_download">下載 %s%s</string>
<string name="network_smp_proxy_mode_never">從不</string>
<string name="privacy_media_blur_radius_medium">中等</string>
<string name="media_and_file_servers">媒體和檔案伺服器</string>
<string name="message_servers">訊息伺服器</string>
<string name="v5_2_disappear_one_message_descr">即使在對話中禁用。</string>
<string name="v5_2_favourites_filter">更快的發起聊天</string>
<string name="v5_2_fix_encryption_descr">修復還原備份後的加密問題</string>
<string name="v5_7_network">網路管理</string>
<string name="v5_3_new_desktop_app">新的桌面應用!</string>
<string name="servers_info_sessions_connected">已連接</string>
<string name="servers_info_sessions_connecting">連接中</string>
<string name="servers_info_sessions_errors">錯誤</string>
<string name="receipts_groups_title_disable">為群組停用回執?</string>
<string name="past_member_vName">過往的成員 %1$s</string>
<string name="v5_8_private_routing">私密訊息路由 🚀</string>
<string name="paste_archive_link">貼上存檔連結</string>
<string name="open_on_mobile_and_scan_qr_code"><![CDATA[在行動應用中打開<i>從桌面使用</i>並掃描QR code。]]></string>
<string name="no_info_on_delivery">無傳送資訊</string>
<string name="or_show_this_qr_code">或者顯示此碼</string>
<string name="servers_info_subscriptions_connections_pending">待連接</string>
<string name="error_parsing_uri_desc">請檢查 Simple X 鏈接是否正確。</string>
<string name="note_folder_local_display_name">私密筆記</string>
<string name="please_try_later">請稍後再試。</string>
<string name="no_filtered_contacts">沒有過濾的聯絡人</string>
<string name="app_check_for_updates_button_open">打開檔案位置</string>
<string name="rcv_group_event_open_chat">打開</string>
<string name="v5_5_private_notes">私密筆記</string>
<string name="v5_8_persian_ui">波斯語用戶界面</string>
<string name="v6_0_chat_list_media">從聊天列表播放。</string>
<string name="migrate_from_device_database_init">正在準備上傳</string>
<string name="feature_roles_owners">擁有者</string>
<string name="not_compatible">不相容!</string>
<string name="agent_critical_error_desc">請將它報告給開發者:
\n%s
\n
\n建議重啟應用。</string>
<string name="loading_remote_file_desc">從已連接行動裝置加載檔案時請稍候片刻</string>
<string name="or_scan_qr_code">或者掃描QR code</string>
<string name="prohibit_sending_simplex_links">禁止傳送 SimpleX 連結</string>
<string name="no_selected_chat">沒有選擇聊天</string>
<string name="permissions_open_settings">打開設定</string>
<string name="settings_section_title_user_theme">這人資料主題</string>
<string name="settings_section_title_profile_images">個人資料圖片</string>
<string name="only_one_device_can_work_at_the_same_time">同一時刻只有一台裝置可工作</string>
<string name="protect_ip_address">保護 IP 地址</string>
<string name="network_type_other">其他</string>
<string name="network_type_no_network_connection">無網路連接</string>
<string name="no_history">無歷史記錄</string>
<string name="no_filtered_chats">無過濾聊天</string>
<string name="agent_internal_error_desc">請將它報告給開發者:
\n%s</string>
<string name="turn_off_system_restriction_button">打開應用程式設定</string>
<string name="auth_open_migration_to_another_device">開啟轉移畫面</string>
<string name="shutdown_alert_desc">通知將停止,直到您重啟應用程式</string>
<string name="prohibit_sending_files">禁止傳送檔案和媒體。</string>
<string name="connect_plan_open_group">打開群組</string>
<string name="only_owners_can_enable_files_and_media">只有群組所有者才能啟用檔案和媒體。</string>
<string name="paste_the_link_you_received_to_connect_with_your_contact">貼上你收到的連結以與你的聯絡人聯絡…</string>
<string name="servers_info_previously_connected_servers_section_header">先前連接的伺服器</string>
<string name="other_label">其他</string>
<string name="message_queue_info_none"></string>
<string name="v5_4_more_things_descr">- 可選擇通知已刪除的聯絡人。
\n- 帶空格的個人資料名稱。
\n- 以及更多!</string>
<string name="v5_5_simpler_connect_ui">貼上連結以連接!</string>
<string name="paste_desktop_address">貼上桌面地址</string>
<string name="migrate_to_device_confirm_network_settings_footer">請確認此裝置的網路設定是否正確。</string>
<string name="other_errors">其他錯誤</string>
<string name="remote_ctrl_connection_stopped_desc">請檢查行動裝置和桌面設備連接到的是同一個本地網絡,且桌面防火牆允許連接。
\n請和開發者分享任何其他問題。</string>
<string name="open_port_in_firewall_title">在防火牆中打開端口</string>
<string name="or_paste_archive_link">或貼上存檔連結</string>
<string name="migrate_to_device_database_init">正在準備下載</string>
<string name="only_delete_conversation">只刪除對話</string>
<string name="paste_link">貼上連結</string>
<string name="smp_servers_other">其他 SMP 伺服器</string>
<string name="xftp_servers_other">其他 XFTP 伺服器</string>
<string name="calls_prohibited_ask_to_enable_calls_alert_text">請讓你的聯絡人啟用通話。</string>
<string name="v5_6_picture_in_picture_calls">畫中畫通話</string>
<string name="migrate_from_device_or_share_this_file_link">或安全分享此文件連結</string>
<string name="servers_info_missing">無資訊,試試重新加載</string>
<string name="open_server_settings_button">打開伺服器設定</string>
<string name="private_routing_error">私密路由出錯</string>
<string name="message_forwarded_desc">尚無直接連接,訊息由管理員轉發。</string>
<string name="selected_chat_items_nothing_selected">什麼也沒選中</string>
<string name="info_view_open_button">打開</string>
<string name="network_smp_proxy_mode_private_routing">私密路由</string>
<string name="open_database_folder">打開資料庫文件夾</string>
<string name="settings_section_title_private_message_routing">私密訊息路由</string>
<string name="app_check_for_updates_installed_successfully_desc">請重啟應用程式。</string>
<string name="privacy_media_blur_radius_off">關閉</string>
<string name="v5_6_quantum_resistant_encryption">抗量子加密</string>
<string name="profile_update_event_removed_address">刪除了聯繫地址</string>
<string name="servers_info_reconnect_server_title">重連伺服器?</string>
<string name="servers_info_detailed_statistics_received_messages_header">接收到的訊息</string>
<string name="servers_info_detailed_statistics_receive_errors">接收錯誤</string>
<string name="servers_info_reconnect_servers_message">重新連接所有已連接的伺服器來強制傳送訊息。這會使用額外流量。</string>
<string name="servers_info_reconnect_server_message">重連伺服器強制傳送訊息。這會使用額外流量。</string>
<string name="network_option_rcv_concurrency">並行接收</string>
<string name="recipients_can_not_see_who_message_from">收件人看不到這條訊息來自誰。</string>
<string name="profile_update_event_removed_picture">刪除了資料圖片</string>
<string name="one_hand_ui">可使用的聊天工具箱</string>
<string name="v6_0_reachable_chat_toolbar">可存取的聊天工具欄</string>
<string name="v5_5_join_group_conversation_descr">最近歷史和改進的目錄機器人。</string>
<string name="network_option_protocol_timeout_per_kb">每 KB 協議超時</string>
<string name="v5_8_private_routing_descr">保護您的真實 IP 地址。不讓你聯絡人選擇的訊息中繼看到它。
\n在*網絡&amp;伺服器*設定中開啓。</string>
<string name="you_can_change_it_later">隨機密碼以明文形式儲存在設定中。
\n您可以稍後更改。</string>
<string name="send_receipts_disabled_alert_title">傳送回條已禁用</string>
<string name="servers_info_proxied_servers_section_header">代理伺服器</string>
<string name="servers_info_reconnect_servers_title">重連伺服器?</string>
<string name="conn_event_enabled_pq">抗量子端到端加密</string>
<string name="color_received_quote">收到的回覆</string>
<string name="servers_info_reconnect_all_servers_button">重連所有伺服器</string>
<string name="reconnect">重連</string>
<string name="proxied">代理</string>
<string name="random_port">隨機</string>
<string name="refresh_qr_code">更新</string>
<string name="servers_info_detailed_statistics_received_total">接收總計</string>
<string name="app_check_for_updates_button_remind_later">稍後提醒</string>
</resources>
+4 -4
View File
@@ -26,11 +26,11 @@ android.enableJetifier=true
kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.jvm.target=11
android.version_name=6.0.1
android.version_code=232
android.version_name=6.0.2
android.version_code=234
desktop.version_name=6.0.1
desktop.version_code=62
desktop.version_name=6.0.2
desktop.version_code=63
kotlin.version=1.9.23
gradle.plugin.version=8.2.0
+1 -1
View File
@@ -46,7 +46,7 @@ mySquaringBot _user cc = do
CRContactConnected _ contact _ -> do
contactConnected contact
sendMessage cc contact welcomeMessage
CRNewChatItem _ (AChatItem _ SMDRcv (DirectChat contact) ChatItem {content = mc@CIRcvMsgContent {}}) -> do
CRNewChatItems {chatItems = (AChatItem _ SMDRcv (DirectChat contact) ChatItem {content = mc@CIRcvMsgContent {}}) : _} -> do
let msg = T.unpack $ ciContentToText mc
number_ = readMaybe msg :: Maybe Integer
sendMessage cc contact $ case number_ of
@@ -40,7 +40,7 @@ broadcastBot BroadcastBotOpts {publishers, welcomeMessage, prohibitedMessage} _u
CRContactConnected _ ct _ -> do
contactConnected ct
sendMessage cc ct welcomeMessage
CRNewChatItem _ (AChatItem _ SMDRcv (DirectChat ct) ci@ChatItem {content = CIRcvMsgContent mc})
CRNewChatItems {chatItems = (AChatItem _ SMDRcv (DirectChat ct) ci@ChatItem {content = CIRcvMsgContent mc}) : _}
| publisher `elem` publishers ->
if allowContent mc
then do
@@ -73,7 +73,7 @@ crDirectoryEvent = \case
CRGroupDeleted {groupInfo} -> Just $ DEGroupDeleted groupInfo
CRChatItemUpdated {chatItem = AChatItem _ SMDRcv (DirectChat ct) _} -> Just $ DEItemEditIgnored ct
CRChatItemsDeleted {chatItemDeletions = ((ChatItemDeletion (AChatItem _ SMDRcv (DirectChat ct) _) _) : _), byUser = False} -> Just $ DEItemDeleteIgnored ct
CRNewChatItem {chatItem = AChatItem _ SMDRcv (DirectChat ct) ci@ChatItem {content = CIRcvMsgContent mc, meta = CIMeta {itemLive}}} ->
CRNewChatItems {chatItems = (AChatItem _ SMDRcv (DirectChat ct) ci@ChatItem {content = CIRcvMsgContent mc, meta = CIMeta {itemLive}}) : _} ->
Just $ case (mc, itemLive) of
(MCText t, Nothing) -> DEContactCommand ct ciId $ fromRight err $ A.parseOnly (directoryCmdP <* A.endOfInput) $ T.dropWhileEnd isSpace t
_ -> DEUnsupportedMessage ct ciId
+1 -1
View File
@@ -1,5 +1,5 @@
name: simplex-chat
version: 6.0.2.0
version: 6.1.0.0
#synopsis:
#description:
homepage: https://github.com/simplex-chat/simplex-chat#readme
+1 -1
View File
@@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack
name: simplex-chat
version: 6.0.2.0
version: 6.1.0.0
category: Web, System, Services, Cryptography
homepage: https://github.com/simplex-chat/simplex-chat#readme
author: simplex.chat
+470 -282
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -11,6 +11,7 @@ import Control.Concurrent.Async
import Control.Concurrent.STM
import Control.Monad
import qualified Data.ByteString.Char8 as B
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.Text as T
import Simplex.Chat.Controller
import Simplex.Chat.Core
@@ -31,7 +32,7 @@ chatBotRepl welcome answer _user cc = do
CRContactConnected _ contact _ -> do
contactConnected contact
void $ sendMessage cc contact welcome
CRNewChatItem _ (AChatItem _ SMDRcv (DirectChat contact) ChatItem {content = mc@CIRcvMsgContent {}}) -> do
CRNewChatItems {chatItems = (AChatItem _ SMDRcv (DirectChat contact) ChatItem {content = mc@CIRcvMsgContent {}}) : _} -> do
let msg = T.unpack $ ciContentToText mc
void $ sendMessage cc contact =<< answer contact msg
_ -> pure ()
@@ -68,8 +69,8 @@ sendComposedMessage cc = sendComposedMessage' cc . contactId'
sendComposedMessage' :: ChatController -> ContactId -> Maybe ChatItemId -> MsgContent -> IO ()
sendComposedMessage' cc ctId quotedItemId msgContent = do
let cm = ComposedMessage {fileSource = Nothing, quotedItemId, msgContent}
sendChatCmd cc (APISendMessage (ChatRef CTDirect ctId) False Nothing cm) >>= \case
CRNewChatItem {} -> printLog cc CLLInfo $ "sent message to contact ID " <> show ctId
sendChatCmd cc (APISendMessages (ChatRef CTDirect ctId) False Nothing (cm :| [])) >>= \case
CRNewChatItems {} -> printLog cc CLLInfo $ "sent message to contact ID " <> show ctId
r -> putStrLn $ "unexpected send message response: " <> show r
deleteMessage :: ChatController -> Contact -> ChatItemId -> IO ()
+4 -5
View File
@@ -292,13 +292,13 @@ data ChatCommand
| APIGetChat ChatRef ChatPagination (Maybe String)
| APIGetChatItems ChatPagination (Maybe String)
| APIGetChatItemInfo ChatRef ChatItemId
| APISendMessage {chatRef :: ChatRef, liveMessage :: Bool, ttl :: Maybe Int, composedMessage :: ComposedMessage}
| APICreateChatItem {noteFolderId :: NoteFolderId, composedMessage :: ComposedMessage}
| APISendMessages {chatRef :: ChatRef, liveMessage :: Bool, ttl :: Maybe Int, composedMessages :: NonEmpty ComposedMessage}
| APICreateChatItems {noteFolderId :: NoteFolderId, composedMessages :: NonEmpty ComposedMessage}
| APIUpdateChatItem {chatRef :: ChatRef, chatItemId :: ChatItemId, liveMessage :: Bool, msgContent :: MsgContent}
| APIDeleteChatItem ChatRef (NonEmpty ChatItemId) CIDeleteMode
| APIDeleteMemberChatItem GroupId (NonEmpty ChatItemId)
| APIChatItemReaction {chatRef :: ChatRef, chatItemId :: ChatItemId, add :: Bool, reaction :: MsgReaction}
| APIForwardChatItem {toChatRef :: ChatRef, fromChatRef :: ChatRef, chatItemId :: ChatItemId, ttl :: Maybe Int}
| APIForwardChatItems {toChatRef :: ChatRef, fromChatRef :: ChatRef, chatItemIds :: NonEmpty ChatItemId, ttl :: Maybe Int}
| APIUserRead UserId
| UserRead
| APIChatRead ChatRef (Maybe (ChatItemId, ChatItemId))
@@ -597,7 +597,7 @@ data ChatResponse
| CRContactCode {user :: User, contact :: Contact, connectionCode :: Text}
| CRGroupMemberCode {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionCode :: Text}
| CRConnectionVerified {user :: User, verified :: Bool, expectedCode :: Text}
| CRNewChatItem {user :: User, chatItem :: AChatItem}
| CRNewChatItems {user :: User, chatItems :: [AChatItem]}
| CRChatItemStatusUpdated {user :: User, chatItem :: AChatItem}
| CRChatItemUpdated {user :: User, chatItem :: AChatItem}
| CRChatItemNotChanged {user :: User, chatItem :: AChatItem}
@@ -1178,7 +1178,6 @@ data ChatErrorType
| CEInlineFileProhibited {fileId :: FileTransferId}
| CEInvalidQuote
| CEInvalidForward
| CEForwardNoFile
| CEInvalidChatItemUpdate
| CEInvalidChatItemDelete
| CEHasCurrentCall
+6 -4
View File
@@ -17,16 +17,18 @@ import Simplex.Chat.Messages
data MsgBatch = MsgBatch ByteString [SndMessage]
-- | Batches [SndMessage] into batches of ByteStrings in form of JSON arrays.
-- | Batches SndMessages in [Either ChatError SndMessage] into batches of ByteStrings in form of JSON arrays.
-- Preserves original errors in the list.
-- Does not check if the resulting batch is a valid JSON.
-- If a single element is passed, it is returned as is (a JSON string).
-- If an element exceeds maxLen, it is returned as ChatError.
batchMessages :: Int -> [SndMessage] -> [Either ChatError MsgBatch]
batchMessages :: Int -> [Either ChatError SndMessage] -> [Either ChatError MsgBatch]
batchMessages maxLen = addBatch . foldr addToBatch ([], [], 0, 0)
where
msgBatch batch = Right (MsgBatch (encodeMessages batch) batch)
addToBatch :: SndMessage -> ([Either ChatError MsgBatch], [SndMessage], Int, Int) -> ([Either ChatError MsgBatch], [SndMessage], Int, Int)
addToBatch msg@SndMessage {msgBody} acc@(batches, batch, len, n)
addToBatch :: Either ChatError SndMessage -> ([Either ChatError MsgBatch], [SndMessage], Int, Int) -> ([Either ChatError MsgBatch], [SndMessage], Int, Int)
addToBatch (Left err) acc = (Left err : addBatch acc, [], 0, 0) -- step over original error
addToBatch (Right msg@SndMessage {msgBody}) acc@(batches, batch, len, n)
| batchLen <= maxLen = (batches, msg : batch, len', n + 1)
| msgLen <= maxLen = (addBatch acc, [msg], msgLen, 1)
| otherwise = (errLarge msg : addBatch acc, [], 0, 0)
+2 -2
View File
@@ -72,11 +72,11 @@ import UnliftIO.Directory (copyFile, createDirectoryIfMissing, doesDirectoryExis
-- when acting as host
minRemoteCtrlVersion :: AppVersion
minRemoteCtrlVersion = AppVersion [6, 0, 0, 4]
minRemoteCtrlVersion = AppVersion [6, 1, 0, 0]
-- when acting as controller
minRemoteHostVersion :: AppVersion
minRemoteHostVersion = AppVersion [6, 0, 0, 4]
minRemoteHostVersion = AppVersion [6, 1, 0, 0]
currentAppVersion :: AppVersion
currentAppVersion = AppVersion SC.version
+5 -5
View File
@@ -966,20 +966,20 @@ lookupFileTransferRedirectMeta db User {userId} fileId = do
redirects <- DB.query db "SELECT file_id FROM files WHERE user_id = ? AND redirect_file_id = ?" (userId, fileId)
rights <$> mapM (runExceptT . getFileTransferMeta_ db userId . fromOnly) redirects
createLocalFile :: ToField (CIFileStatus d) => CIFileStatus d -> DB.Connection -> User -> NoteFolder -> ChatItemId -> UTCTime -> CryptoFile -> Integer -> Integer -> IO Int64
createLocalFile fileStatus db User {userId} NoteFolder {noteFolderId} chatItemId itemTs CryptoFile {filePath, cryptoArgs} fileSize fileChunkSize = do
createLocalFile :: ToField (CIFileStatus d) => CIFileStatus d -> DB.Connection -> User -> NoteFolder -> UTCTime -> CryptoFile -> Integer -> Integer -> IO Int64
createLocalFile fileStatus db User {userId} NoteFolder {noteFolderId} itemTs CryptoFile {filePath, cryptoArgs} fileSize fileChunkSize = do
DB.execute
db
[sql|
INSERT INTO files
( user_id, note_folder_id, chat_item_id,
( user_id, note_folder_id,
file_name, file_path, file_size,
file_crypto_key, file_crypto_nonce,
chunk_size, file_inline, ci_file_status, protocol, created_at, updated_at
)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)
|]
( (userId, noteFolderId, chatItemId)
( (userId, noteFolderId)
:. (takeFileName filePath, filePath, fileSize)
:. maybe (Nothing, Nothing) (\(CFArgs key nonce) -> (Just key, Just nonce)) cryptoArgs
:. (fileChunkSize, Nothing :: Maybe InlineFileMode, fileStatus, FPLocal, itemTs, itemTs)
+2 -2
View File
@@ -69,7 +69,7 @@ runInputLoop ct@ChatTerminal {termState, liveMessageState} cc = forever $ do
Nothing -> setActive ct ""
Just rhId -> updateRemoteUser ct u rhId
CRChatItems u chatName_ _ -> whenCurrUser cc u $ mapM_ (setActive ct . chatActiveTo) chatName_
CRNewChatItem u (AChatItem _ SMDSnd cInfo _) -> whenCurrUser cc u $ setActiveChat ct cInfo
CRNewChatItems u ((AChatItem _ SMDSnd cInfo _) : _) -> whenCurrUser cc u $ setActiveChat ct cInfo
CRChatItemUpdated u (AChatItem _ SMDSnd cInfo _) -> whenCurrUser cc u $ setActiveChat ct cInfo
CRChatItemsDeleted u ((ChatItemDeletion (AChatItem _ _ cInfo _) _) : _) _ _ -> whenCurrUser cc u $ setActiveChat ct cInfo
CRContactDeleted u c -> whenCurrUser cc u $ unsetActiveContact ct c
@@ -93,7 +93,7 @@ runInputLoop ct@ChatTerminal {termState, liveMessageState} cc = forever $ do
Right SendMessageBroadcast {} -> True
_ -> False
startLiveMessage :: Either a ChatCommand -> ChatResponse -> IO ()
startLiveMessage (Right (SendLiveMessage chatName msg)) (CRNewChatItem _ (AChatItem cType SMDSnd _ ChatItem {meta = CIMeta {itemId}})) = do
startLiveMessage (Right (SendLiveMessage chatName msg)) (CRNewChatItems {chatItems = [AChatItem cType SMDSnd _ ChatItem {meta = CIMeta {itemId}}]}) = do
whenM (isNothing <$> readTVarIO liveMessageState) $ do
let s = T.unpack msg
int = case cType of SCTGroup -> 5000000; _ -> 3000000 :: Int
+1 -1
View File
@@ -44,7 +44,7 @@ simplexChatCLI' cfg opts@ChatOpts {chatCmd, chatCmdLog, chatCmdDelay, chatServer
when (chatCmdLog /= CCLNone) . void . forkIO . forever $ do
(_, _, r') <- atomically . readTBQueue $ outputQ cc
case r' of
CRNewChatItem {} -> printResponse r'
CRNewChatItems {} -> printResponse r'
_ -> when (chatCmdLog == CCLAll) $ printResponse r'
sendChatCmdStr cc chatCmd >>= printResponse
threadDelay $ chatCmdDelay * 1000000
+3 -2
View File
@@ -147,7 +147,7 @@ runTerminalOutput ct cc@ChatController {outputQ, showLiveItems, logFilePath} Cha
forever $ do
(_, outputRH, r) <- atomically $ readTBQueue outputQ
case r of
CRNewChatItem u ci -> when markRead $ markChatItemRead u ci
CRNewChatItems u (ci : _) -> when markRead $ markChatItemRead u ci -- At the moment of writing received items are created one at a time
CRChatItemUpdated u ci -> when markRead $ markChatItemRead u ci
CRRemoteHostConnected {remoteHost = RemoteHostInfo {remoteHostId}} -> getRemoteUser remoteHostId
CRRemoteHostStopped {remoteHostId_} -> mapM_ removeRemoteUser remoteHostId_
@@ -175,7 +175,8 @@ runTerminalOutput ct cc@ChatController {outputQ, showLiveItems, logFilePath} Cha
responseNotification :: ChatTerminal -> ChatController -> ChatResponse -> IO ()
responseNotification t@ChatTerminal {sendNotification} cc = \case
CRNewChatItem u (AChatItem _ SMDRcv cInfo ci@ChatItem {chatDir, content = CIRcvMsgContent mc, formattedText}) ->
-- At the moment of writing received items are created one at a time
CRNewChatItems u ((AChatItem _ SMDRcv cInfo ci@ChatItem {chatDir, content = CIRcvMsgContent mc, formattedText}) : _) ->
when (chatDirNtf u cInfo chatDir $ isMention ci) $ do
whenCurrUser cc u $ setActiveChat t cInfo
case (cInfo, chatDir) of
+4 -2
View File
@@ -120,7 +120,10 @@ responseToView hu@(currentRH, user_) ChatConfig {logLevel, showReactions, showRe
CRConnectionVerified u verified code -> ttyUser u [plain $ if verified then "connection verified" else "connection not verified, current code is " <> code]
CRContactCode u ct code -> ttyUser u $ viewContactCode ct code testView
CRGroupMemberCode u g m code -> ttyUser u $ viewGroupMemberCode g m code testView
CRNewChatItem u (AChatItem _ _ chat item) -> ttyUser u $ unmuted u chat item $ viewChatItem chat item False ts tz <> viewItemReactions item
CRNewChatItems u chatItems ->
concatMap
(\(AChatItem _ _ chat item) -> ttyUser u $ unmuted u chat item $ viewChatItem chat item False ts tz <> viewItemReactions item)
chatItems
CRChatItems u _ chatItems -> ttyUser u $ concatMap (\(AChatItem _ _ chat item) -> viewChatItem chat item True ts tz <> viewItemReactions item) chatItems
CRChatItemInfo u ci ciInfo -> ttyUser u $ viewChatItemInfo ci ciInfo tz
CRChatItemId u itemId -> ttyUser u [plain $ maybe "no item" show itemId]
@@ -2025,7 +2028,6 @@ viewChatError isCmd logLevel testView = \case
CEInlineFileProhibited _ -> ["A small file sent without acceptance - you can enable receiving such files with -f option."]
CEInvalidQuote -> ["cannot reply to this message"]
CEInvalidForward -> ["cannot forward this message"]
CEForwardNoFile -> ["cannot forward this message, file not found"]
CEInvalidChatItemUpdate -> ["cannot update this item"]
CEInvalidChatItemDelete -> ["cannot delete this item"]
CEHasCurrentCall -> ["call already in progress"]
+15 -2
View File
@@ -52,6 +52,7 @@ chatDirectTests = do
it "repeat AUTH errors disable contact" testRepeatAuthErrorsDisableContact
it "should send multiline message" testMultilineMessage
it "send large message" testLargeMessage
it "send multiple messages api" testSendMulti
describe "duplicate contacts" $ do
it "duplicate contacts are separate (contacts don't merge)" testDuplicateContactsSeparate
it "new contact is separate with multiple duplicate contacts (contacts don't merge)" testDuplicateContactsMultipleSeparate
@@ -839,6 +840,18 @@ testLargeMessage =
bob <## "contact alice changed to alice2"
bob <## "use @alice2 <message> to send messages"
testSendMulti :: HasCallStack => FilePath -> IO ()
testSendMulti =
testChat2 aliceProfile bobProfile $
\alice bob -> do
connectUsers alice bob
alice ##> "/_send @2 json [{\"msgContent\": {\"type\": \"text\", \"text\": \"test 1\"}}, {\"msgContent\": {\"type\": \"text\", \"text\": \"test 2\"}}]"
alice <# "@bob test 1"
alice <# "@bob test 2"
bob <# "alice> test 1"
bob <# "alice> test 2"
testGetSetSMPServers :: HasCallStack => FilePath -> IO ()
testGetSetSMPServers =
testChat2 aliceProfile bobProfile $
@@ -2162,7 +2175,7 @@ testSetChatItemTTL =
-- chat item with file
alice #$> ("/_files_folder ./tests/tmp/app_files", id, "ok")
copyFile "./tests/fixtures/test.jpg" "./tests/tmp/app_files/test.jpg"
alice ##> "/_send @2 json {\"filePath\": \"test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}"
alice ##> "/_send @2 json [{\"filePath\": \"test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}]"
alice <# "/f @bob test.jpg"
alice <## "use /fc 1 to cancel sending"
bob <# "alice> sends file test.jpg (136.5 KiB / 139737 bytes)"
@@ -2410,7 +2423,7 @@ setupDesynchronizedRatchet tmp alice = do
(bob </)
bob ##> "/tail @alice 1"
bob <# "alice> decryption error, possibly due to the device change (header, 3 messages)"
bob ##> "@alice 1"
bob `send` "@alice 1"
bob <## "error: command is prohibited, sendMessagesB: send prohibited"
(alice </)
where
+12 -12
View File
@@ -64,7 +64,7 @@ runTestMessageWithFile :: HasCallStack => FilePath -> IO ()
runTestMessageWithFile = testChat2 aliceProfile bobProfile $ \alice bob -> withXFTPServer $ do
connectUsers alice bob
alice ##> "/_send @2 json {\"filePath\": \"./tests/fixtures/test.jpg\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi, sending a file\"}}"
alice ##> "/_send @2 json [{\"filePath\": \"./tests/fixtures/test.jpg\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi, sending a file\"}}]"
alice <# "@bob hi, sending a file"
alice <# "/f @bob ./tests/fixtures/test.jpg"
alice <## "use /fc 1 to cancel sending"
@@ -91,7 +91,7 @@ testSendImage =
testChat2 aliceProfile bobProfile $
\alice bob -> withXFTPServer $ do
connectUsers alice bob
alice ##> "/_send @2 json {\"filePath\": \"./tests/fixtures/test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}"
alice ##> "/_send @2 json [{\"filePath\": \"./tests/fixtures/test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}]"
alice <# "/f @bob ./tests/fixtures/test.jpg"
alice <## "use /fc 1 to cancel sending"
bob <# "alice> sends file test.jpg (136.5 KiB / 139737 bytes)"
@@ -122,7 +122,7 @@ testSenderMarkItemDeleted =
testChat2 aliceProfile bobProfile $
\alice bob -> withXFTPServer $ do
connectUsers alice bob
alice ##> "/_send @2 json {\"filePath\": \"./tests/fixtures/test_1MB.pdf\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi, sending a file\"}}"
alice ##> "/_send @2 json [{\"filePath\": \"./tests/fixtures/test_1MB.pdf\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi, sending a file\"}}]"
alice <# "@bob hi, sending a file"
alice <# "/f @bob ./tests/fixtures/test_1MB.pdf"
alice <## "use /fc 1 to cancel sending"
@@ -147,7 +147,7 @@ testFilesFoldersSendImage =
connectUsers alice bob
alice #$> ("/_files_folder ./tests/fixtures", id, "ok")
bob #$> ("/_files_folder ./tests/tmp/app_files", id, "ok")
alice ##> "/_send @2 json {\"filePath\": \"test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}"
alice ##> "/_send @2 json [{\"filePath\": \"test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}]"
alice <# "/f @bob test.jpg"
alice <## "use /fc 1 to cancel sending"
bob <# "alice> sends file test.jpg (136.5 KiB / 139737 bytes)"
@@ -180,7 +180,7 @@ testFilesFoldersImageSndDelete =
alice #$> ("/_files_folder ./tests/tmp/alice_app_files", id, "ok")
copyFile "./tests/fixtures/test_1MB.pdf" "./tests/tmp/alice_app_files/test_1MB.pdf"
bob #$> ("/_files_folder ./tests/tmp/bob_app_files", id, "ok")
alice ##> "/_send @2 json {\"filePath\": \"test_1MB.pdf\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}"
alice ##> "/_send @2 json [{\"filePath\": \"test_1MB.pdf\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}]"
alice <# "/f @bob test_1MB.pdf"
alice <## "use /fc 1 to cancel sending"
bob <# "alice> sends file test_1MB.pdf (1017.7 KiB / 1042157 bytes)"
@@ -212,7 +212,7 @@ testFilesFoldersImageRcvDelete =
connectUsers alice bob
alice #$> ("/_files_folder ./tests/fixtures", id, "ok")
bob #$> ("/_files_folder ./tests/tmp/app_files", id, "ok")
alice ##> "/_send @2 json {\"filePath\": \"test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}"
alice ##> "/_send @2 json [{\"filePath\": \"test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}]"
alice <# "/f @bob test.jpg"
alice <## "use /fc 1 to cancel sending"
bob <# "alice> sends file test.jpg (136.5 KiB / 139737 bytes)"
@@ -239,7 +239,7 @@ testSendImageWithTextAndQuote =
connectUsers alice bob
bob #> "@alice hi alice"
alice <# "bob> hi alice"
alice ##> ("/_send @2 json {\"filePath\": \"./tests/fixtures/test.jpg\", \"quotedItemId\": " <> itemId 1 <> ", \"msgContent\": {\"text\":\"hey bob\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}")
alice ##> ("/_send @2 json [{\"filePath\": \"./tests/fixtures/test.jpg\", \"quotedItemId\": " <> itemId 1 <> ", \"msgContent\": {\"text\":\"hey bob\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}]")
alice <# "@bob > hi alice"
alice <## " hey bob"
alice <# "/f @bob ./tests/fixtures/test.jpg"
@@ -265,7 +265,7 @@ testSendImageWithTextAndQuote =
bob @@@ [("@alice", "hey bob")]
-- quoting (file + text) with file uses quoted text
bob ##> ("/_send @2 json {\"filePath\": \"./tests/fixtures/test.pdf\", \"quotedItemId\": " <> itemId 2 <> ", \"msgContent\": {\"text\":\"\",\"type\":\"file\"}}")
bob ##> ("/_send @2 json [{\"filePath\": \"./tests/fixtures/test.pdf\", \"quotedItemId\": " <> itemId 2 <> ", \"msgContent\": {\"text\":\"\",\"type\":\"file\"}}]")
bob <# "@alice > hey bob"
bob <## " test.pdf"
bob <# "/f @alice ./tests/fixtures/test.pdf"
@@ -287,7 +287,7 @@ testSendImageWithTextAndQuote =
B.readFile "./tests/tmp/test.pdf" `shouldReturn` txtSrc
-- quoting (file without text) with file uses file name
alice ##> ("/_send @2 json {\"filePath\": \"./tests/fixtures/test.jpg\", \"quotedItemId\": " <> itemId 3 <> ", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}")
alice ##> ("/_send @2 json [{\"filePath\": \"./tests/fixtures/test.jpg\", \"quotedItemId\": " <> itemId 3 <> ", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}]")
alice <# "@bob > test.pdf"
alice <## " test.jpg"
alice <# "/f @bob ./tests/fixtures/test.jpg"
@@ -313,7 +313,7 @@ testGroupSendImage =
\alice bob cath -> withXFTPServer $ do
createGroup3 "team" alice bob cath
threadDelay 1000000
alice ##> "/_send #1 json {\"filePath\": \"./tests/fixtures/test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}"
alice ##> "/_send #1 json [{\"filePath\": \"./tests/fixtures/test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}]"
alice <# "/f #team ./tests/fixtures/test.jpg"
alice <## "use /fc 1 to cancel sending"
concurrentlyN_
@@ -361,7 +361,7 @@ testGroupSendImageWithTextAndQuote =
(cath <# "#team bob> hi team")
threadDelay 1000000
msgItemId <- lastItemId alice
alice ##> ("/_send #1 json {\"filePath\": \"./tests/fixtures/test.jpg\", \"quotedItemId\": " <> msgItemId <> ", \"msgContent\": {\"text\":\"hey bob\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}")
alice ##> ("/_send #1 json [{\"filePath\": \"./tests/fixtures/test.jpg\", \"quotedItemId\": " <> msgItemId <> ", \"msgContent\": {\"text\":\"hey bob\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}]")
alice <# "#team > bob hi team"
alice <## " hey bob"
alice <# "/f #team ./tests/fixtures/test.jpg"
@@ -460,7 +460,7 @@ testXFTPFileTransferEncrypted =
let fileJSON = LB.unpack $ J.encode $ CryptoFile srcPath $ Just cfArgs
withXFTPServer $ do
connectUsers alice bob
alice ##> ("/_send @2 json {\"msgContent\":{\"type\":\"file\", \"text\":\"\"}, \"fileSource\": " <> fileJSON <> "}")
alice ##> ("/_send @2 json [{\"msgContent\":{\"type\":\"file\", \"text\":\"\"}, \"fileSource\": " <> fileJSON <> "}]")
alice <# "/f @bob ./tests/tmp/alice/test.pdf"
alice <## "use /fc 1 to cancel sending"
bob <# "alice> sends file test.pdf (266.0 KiB / 272376 bytes)"
+34 -4
View File
@@ -33,6 +33,8 @@ chatForwardTests = do
it "with relative paths: from contact to contact" testForwardFileContactToContact
it "with relative paths: from group to notes" testForwardFileGroupToNotes
it "with relative paths: from notes to group" testForwardFileNotesToGroup
describe "multi forward api" $ do
it "from contact to contact" testForwardContactToContactMulti
testForwardContactToContact :: HasCallStack => FilePath -> IO ()
testForwardContactToContact =
@@ -384,7 +386,7 @@ testForwardFileNoFilesFolder =
connectUsers bob cath
-- send original file
alice ##> "/_send @2 json {\"filePath\": \"./tests/fixtures/test.pdf\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi\"}}"
alice ##> "/_send @2 json [{\"filePath\": \"./tests/fixtures/test.pdf\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi\"}}]"
alice <# "@bob hi"
alice <# "/f @bob ./tests/fixtures/test.pdf"
alice <## "use /fc 1 to cancel sending"
@@ -441,7 +443,7 @@ testForwardFileContactToContact =
connectUsers bob cath
-- send original file
alice ##> "/_send @2 json {\"filePath\": \"test.pdf\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi\"}}"
alice ##> "/_send @2 json [{\"filePath\": \"test.pdf\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi\"}}]"
alice <# "@bob hi"
alice <# "/f @bob test.pdf"
alice <## "use /fc 1 to cancel sending"
@@ -506,7 +508,7 @@ testForwardFileGroupToNotes =
createCCNoteFolder cath
-- send original file
alice ##> "/_send #1 json {\"filePath\": \"test.pdf\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi\"}}"
alice ##> "/_send #1 json [{\"filePath\": \"test.pdf\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi\"}}]"
alice <# "#team hi"
alice <# "/f #team test.pdf"
alice <## "use /fc 1 to cancel sending"
@@ -555,7 +557,7 @@ testForwardFileNotesToGroup =
createGroup2 "team" alice cath
-- create original file
alice ##> "/_create *1 json {\"filePath\": \"test.pdf\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi\"}}"
alice ##> "/_create *1 json [{\"filePath\": \"test.pdf\", \"msgContent\": {\"type\": \"text\", \"text\": \"hi\"}}]"
alice <# "* hi"
alice <# "* file 1 (test.pdf)"
@@ -590,3 +592,31 @@ testForwardFileNotesToGroup =
alice <## "notes: all messages are removed"
fwdFileExists <- doesFileExist "./tests/tmp/alice_files/test_1.pdf"
fwdFileExists `shouldBe` True
testForwardContactToContactMulti :: HasCallStack => FilePath -> IO ()
testForwardContactToContactMulti =
testChat3 aliceProfile bobProfile cathProfile $
\alice bob cath -> do
connectUsers alice bob
connectUsers alice cath
connectUsers bob cath
alice #> "@bob hi"
bob <# "alice> hi"
msgId1 <- lastItemId alice
threadDelay 1000000
bob #> "@alice hey"
alice <# "bob> hey"
msgId2 <- lastItemId alice
alice ##> ("/_forward @3 @2 " <> msgId1 <> "," <> msgId2)
alice <# "@cath <- you @bob"
alice <## " hi"
alice <# "@cath <- @bob"
alice <## " hey"
cath <# "alice> -> forwarded"
cath <## " hi"
cath <# "alice> -> forwarded"
cath <## " hey"
+20 -6
View File
@@ -64,6 +64,7 @@ chatGroupTests = do
it "moderate message of another group member (full delete)" testGroupModerateFullDelete
it "moderate message that arrives after the event of moderation" testGroupDelayedModeration
it "moderate message that arrives after the event of moderation (full delete)" testGroupDelayedModerationFullDelete
it "send multiple messages api" testSendMulti
describe "async group connections" $ do
xit "create and join group when clients go offline" testGroupAsync
describe "group links" $ do
@@ -1818,6 +1819,18 @@ testGroupDelayedModerationFullDelete tmp = do
where
cfg = testCfgCreateGroupDirect
testSendMulti :: HasCallStack => FilePath -> IO ()
testSendMulti =
testChat2 aliceProfile bobProfile $
\alice bob -> do
createGroup2 "team" alice bob
alice ##> "/_send #1 json [{\"msgContent\": {\"type\": \"text\", \"text\": \"test 1\"}}, {\"msgContent\": {\"type\": \"text\", \"text\": \"test 2\"}}]"
alice <# "#team test 1"
alice <# "#team test 2"
bob <# "#team alice> test 1"
bob <# "#team alice> test 2"
testGroupAsync :: HasCallStack => FilePath -> IO ()
testGroupAsync tmp = do
withNewTestChat tmp "alice" aliceProfile $ \alice -> do
@@ -3468,7 +3481,8 @@ testGroupSyncRatchet tmp =
bob <## "1 contacts connected (use /cs for the list)"
bob <## "#team: connected to server(s)"
bob `send` "#team 1"
bob <## "error: command is prohibited, sendMessagesB: send prohibited" -- silence?
-- "send prohibited" error is not printed in group as SndMessage is created,
-- but it should be displayed in per member snd statuses
bob <# "#team 1"
(alice </)
-- synchronize bob and alice
@@ -4908,7 +4922,7 @@ testGroupHistoryLargeFile =
createGroup2 "team" alice bob
bob ##> "/_send #1 json {\"filePath\": \"./tests/tmp/testfile\", \"msgContent\": {\"text\":\"hello\",\"type\":\"file\"}}"
bob ##> "/_send #1 json [{\"filePath\": \"./tests/tmp/testfile\", \"msgContent\": {\"text\":\"hello\",\"type\":\"file\"}}]"
bob <# "#team hello"
bob <# "/f #team ./tests/tmp/testfile"
bob <## "use /fc 1 to cancel sending"
@@ -4969,7 +4983,7 @@ testGroupHistoryMultipleFiles =
threadDelay 1000000
bob ##> "/_send #1 json {\"filePath\": \"./tests/tmp/testfile_bob\", \"msgContent\": {\"text\":\"hi alice\",\"type\":\"file\"}}"
bob ##> "/_send #1 json [{\"filePath\": \"./tests/tmp/testfile_bob\", \"msgContent\": {\"text\":\"hi alice\",\"type\":\"file\"}}]"
bob <# "#team hi alice"
bob <# "/f #team ./tests/tmp/testfile_bob"
bob <## "use /fc 1 to cancel sending"
@@ -4981,7 +4995,7 @@ testGroupHistoryMultipleFiles =
threadDelay 1000000
alice ##> "/_send #1 json {\"filePath\": \"./tests/tmp/testfile_alice\", \"msgContent\": {\"text\":\"hey bob\",\"type\":\"file\"}}"
alice ##> "/_send #1 json [{\"filePath\": \"./tests/tmp/testfile_alice\", \"msgContent\": {\"text\":\"hey bob\",\"type\":\"file\"}}]"
alice <# "#team hey bob"
alice <# "/f #team ./tests/tmp/testfile_alice"
alice <## "use /fc 2 to cancel sending"
@@ -5047,7 +5061,7 @@ testGroupHistoryFileCancel =
createGroup2 "team" alice bob
bob ##> "/_send #1 json {\"filePath\": \"./tests/tmp/testfile_bob\", \"msgContent\": {\"text\":\"hi alice\",\"type\":\"file\"}}"
bob ##> "/_send #1 json [{\"filePath\": \"./tests/tmp/testfile_bob\", \"msgContent\": {\"text\":\"hi alice\",\"type\":\"file\"}}]"
bob <# "#team hi alice"
bob <# "/f #team ./tests/tmp/testfile_bob"
bob <## "use /fc 1 to cancel sending"
@@ -5063,7 +5077,7 @@ testGroupHistoryFileCancel =
threadDelay 1000000
alice ##> "/_send #1 json {\"filePath\": \"./tests/tmp/testfile_alice\", \"msgContent\": {\"text\":\"hey bob\",\"type\":\"file\"}}"
alice ##> "/_send #1 json [{\"filePath\": \"./tests/tmp/testfile_alice\", \"msgContent\": {\"text\":\"hey bob\",\"type\":\"file\"}}]"
alice <# "#team hey bob"
alice <# "/f #team ./tests/tmp/testfile_alice"
alice <## "use /fc 2 to cancel sending"
+13 -4
View File
@@ -17,6 +17,7 @@ chatLocalChatsTests :: SpecWith FilePath
chatLocalChatsTests = do
describe "note folders" $ do
it "create folders, add notes, read, search" testNotes
it "create multiple messages api" testCreateMulti
it "switch users" testUserNotes
it "preview pagination for notes" testPreviewsPagination
it "chat pagination" testChatPagination
@@ -52,6 +53,14 @@ testNotes tmp = withNewTestChat tmp "alice" aliceProfile $ \alice -> do
alice ##> "/tail *"
alice <# "* Greetings."
testCreateMulti :: FilePath -> IO ()
testCreateMulti tmp = withNewTestChat tmp "alice" aliceProfile $ \alice -> do
createCCNoteFolder alice
alice ##> "/_create *1 json [{\"msgContent\": {\"type\": \"text\", \"text\": \"test 1\"}}, {\"msgContent\": {\"type\": \"text\", \"text\": \"test 2\"}}]"
alice <# "* test 1"
alice <# "* test 2"
testUserNotes :: FilePath -> IO ()
testUserNotes tmp = withNewTestChat tmp "alice" aliceProfile $ \alice -> do
createCCNoteFolder alice
@@ -120,7 +129,7 @@ testFiles tmp = withNewTestChat tmp "alice" aliceProfile $ \alice -> do
let source = "./tests/fixtures/test.jpg"
let stored = files </> "test.jpg"
copyFile source stored
alice ##> "/_create *1 json {\"filePath\": \"test.jpg\", \"msgContent\": {\"text\":\"hi myself\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}"
alice ##> "/_create *1 json [{\"filePath\": \"test.jpg\", \"msgContent\": {\"text\":\"hi myself\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}]"
alice <# "* hi myself"
alice <# "* file 1 (test.jpg)"
@@ -141,7 +150,7 @@ testFiles tmp = withNewTestChat tmp "alice" aliceProfile $ \alice -> do
-- one more file
let stored2 = files </> "another_test.jpg"
copyFile source stored2
alice ##> "/_create *1 json {\"filePath\": \"another_test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}"
alice ##> "/_create *1 json [{\"filePath\": \"another_test.jpg\", \"msgContent\": {\"text\":\"\",\"type\":\"image\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\"}}]"
alice <# "* file 2 (another_test.jpg)"
alice ##> "/_delete item *1 2 internal"
@@ -173,8 +182,8 @@ testOtherFiles =
bob ##> "/fr 1"
bob
<### [ "saving file 1 from alice to test.jpg",
"started receiving file 1 (test.jpg) from alice"
]
"started receiving file 1 (test.jpg) from alice"
]
bob <## "completed receiving file 1 (test.jpg) from alice"
bob /* "test"
+2 -2
View File
@@ -1721,7 +1721,7 @@ testSetContactPrefs = testChat2 aliceProfile bobProfile $
let startFeatures = [(0, e2eeInfoPQStr), (0, "Disappearing messages: allowed"), (0, "Full deletion: off"), (0, "Message reactions: enabled"), (0, "Voice messages: off"), (0, "Audio/video calls: enabled")]
alice #$> ("/_get chat @2 count=100", chat, startFeatures)
bob #$> ("/_get chat @2 count=100", chat, startFeatures)
let sendVoice = "/_send @2 json {\"filePath\": \"test.txt\", \"msgContent\": {\"type\": \"voice\", \"text\": \"\", \"duration\": 10}}"
let sendVoice = "/_send @2 json [{\"filePath\": \"test.txt\", \"msgContent\": {\"type\": \"voice\", \"text\": \"\", \"duration\": 10}}]"
voiceNotAllowed = "bad chat command: feature not allowed Voice messages"
alice ##> sendVoice
alice <## voiceNotAllowed
@@ -2227,7 +2227,7 @@ testGroupPrefsSimplexLinksForRole = testChat3 aliceProfile bobProfile cathProfil
inv <- getInvitation bob
bob ##> ("#team \"" <> inv <> "\\ntest\"")
bob <## "bad chat command: feature not allowed SimpleX links"
bob ##> ("/_send #1 json {\"msgContent\": {\"type\": \"text\", \"text\": \"" <> inv <> "\\ntest\"}}")
bob ##> ("/_send #1 json [{\"msgContent\": {\"type\": \"text\", \"text\": \"" <> inv <> "\\ntest\"}}]")
bob <## "bad chat command: feature not allowed SimpleX links"
(alice </)
(cath </)
+1 -1
View File
@@ -112,7 +112,7 @@ runBatcherTest maxLen msgs expectedErrors expectedBatches =
runBatcherTest' :: Int -> [SndMessage] -> [ChatError] -> [ByteString] -> IO ()
runBatcherTest' maxLen msgs expectedErrors expectedBatches = do
let (errors, batches) = partitionEithers $ batchMessages maxLen msgs
let (errors, batches) = partitionEithers $ batchMessages maxLen (map Right msgs)
batchedStrs = map (\(MsgBatch batchBody _) -> batchBody) batches
testErrors errors `shouldBe` testErrors expectedErrors
batchedStrs `shouldBe` expectedBatches
+2 -2
View File
@@ -238,7 +238,7 @@ remoteStoreFileTest =
desktop ##> "/get remote file 1 {\"userId\": 1, \"fileId\": 1, \"sent\": true, \"fileSource\": {\"filePath\": \"test_1.pdf\"}}"
hostError desktop "SEFileNotFound"
-- send file not encrypted locally on mobile host
desktop ##> "/_send @2 json {\"filePath\": \"test_1.pdf\", \"msgContent\": {\"type\": \"file\", \"text\": \"sending a file\"}}"
desktop ##> "/_send @2 json [{\"filePath\": \"test_1.pdf\", \"msgContent\": {\"type\": \"file\", \"text\": \"sending a file\"}}]"
desktop <# "@bob sending a file"
desktop <# "/f @bob test_1.pdf"
desktop <## "use /fc 1 to cancel sending"
@@ -268,7 +268,7 @@ remoteStoreFileTest =
B.readFile (desktopHostStore </> "test_1.pdf") `shouldReturn` src
-- send file encrypted locally on mobile host
desktop ##> ("/_send @2 json {\"fileSource\": {\"filePath\":\"test_2.pdf\", \"cryptoArgs\": " <> LB.unpack (J.encode cfArgs) <> "}, \"msgContent\": {\"type\": \"file\", \"text\": \"\"}}")
desktop ##> ("/_send @2 json [{\"fileSource\": {\"filePath\":\"test_2.pdf\", \"cryptoArgs\": " <> LB.unpack (J.encode cfArgs) <> "}, \"msgContent\": {\"type\": \"file\", \"text\": \"\"}}]")
desktop <# "/f @bob test_2.pdf"
desktop <## "use /fc 2 to cancel sending"
bob <# "alice> sends file test_2.pdf (266.0 KiB / 272376 bytes)"