Compare commits

..

2 Commits

Author SHA1 Message Date
Levitating Pineapple 469ff6b754 Merge master 2024-09-19 11:18:50 +03:00
Levitating Pineapple 17f99edb6f ios: add on on-device translation sheet to chat 2024-09-19 11:04:46 +03:00
143 changed files with 2428 additions and 7126 deletions
+3 -3
View File
@@ -1111,8 +1111,8 @@ func receiveFiles(user: any UserLike, fileIds: [Int64], userApprovedRelays: Bool
showAlert(
title: NSLocalizedString("Unknown servers!", comment: "alert title"),
message: (
String.localizedStringWithFormat(NSLocalizedString("Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.", comment: "alert message"), srvs) +
(otherErrsStr != "" ? "\n\n" + String.localizedStringWithFormat(NSLocalizedString("Other file errors:\n%@", comment: "alert message"), otherErrsStr) : "")
NSLocalizedString("Without Tor or VPN, your IP address will be visible to these XFTP relays: \(srvs).", comment: "alert message") +
(otherErrsStr != "" ? "\n\n" + NSLocalizedString("Other file errors:\n\(otherErrsStr)", comment: "alert message") : "")
),
buttonTitle: NSLocalizedString("Download", comment: "alert button"),
buttonAction: {
@@ -1156,7 +1156,7 @@ func receiveFiles(user: any UserLike, fileIds: [Int64], userApprovedRelays: Bool
await MainActor.run {
showAlert(
NSLocalizedString("Error receiving file", comment: "alert title"),
message: String.localizedStringWithFormat(NSLocalizedString("File errors:\n%@", comment: "alert message"), otherErrsStr)
message: NSLocalizedString("File errors:\n\(otherErrsStr)", comment: "alert message")
)
}
}
+1 -1
View File
@@ -197,7 +197,7 @@ class ThemeManager {
var themeIds = currentThemeIdsDefault.get()
themeIds[nonSystemThemeName] = prevValue.themeId
currentThemeIdsDefault.set(themeIds)
applyTheme(currentThemeDefault.get())
applyTheme(nonSystemThemeName)
}
static func copyFromSameThemeOverrides(_ type: WallpaperType?, _ lowerLevelOverride: ThemeModeOverride?, _ pref: Binding<ThemeModeOverride>) -> Bool {
@@ -75,14 +75,9 @@ enum MetaColorMode {
}
}
func statusSpacer(_ sent: Bool) -> Text {
var statusSpacer: Text {
switch self {
case .normal, .transparent:
Text(
sent
? Image("checkmark.wide")
: Image(systemName: "circlebadge.fill")
).foregroundColor(.clear)
case .normal, .transparent: Text(Image(systemName: "circlebadge.fill")).foregroundColor(.clear)
case .invertedMaterial: Text(" ").kerning(13)
}
}
@@ -135,10 +130,10 @@ func ciMetaText(
colorMode.resolve(statusColor)
}
r = r + colored(Text(image), metaColor)
space = Text(" ")
} else if !meta.disappearing {
r = r + colorMode.statusSpacer(meta.itemStatus.sent)
space = colorMode.statusSpacer + Text(" ")
}
space = Text(" ")
}
if let enc = encrypted {
appendSpace()
@@ -19,6 +19,7 @@ struct ChatItemForwardingView: View {
@Binding var composeState: ComposeState
@State private var searchText: String = ""
@FocusState private var searchFocused
@State private var alert: SomeAlert?
private let chatsToForwardTo = filterChatsToForwardTo(chats: ChatModel.shared.chats)
@@ -45,6 +46,8 @@ struct ChatItemForwardingView: View {
VStack(alignment: .leading) {
if !chatsToForwardTo.isEmpty {
List {
searchFieldView(text: $searchText, focussed: $searchFocused, theme.colors.onBackground, theme.colors.secondary)
.padding(.leading, 2)
let s = searchText.trimmingCharacters(in: .whitespaces).localizedLowercase
let chats = s == "" ? chatsToForwardTo : chatsToForwardTo.filter { foundChat($0, s) }
ForEach(chats) { chat in
@@ -52,7 +55,6 @@ struct ChatItemForwardingView: View {
.disabled(chatModel.deletedChats.contains(chat.chatInfo.id))
}
}
.searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
.modifier(ThemedBackground(grouped: true))
} else {
ZStack {
+18 -5
View File
@@ -622,11 +622,7 @@ struct ChatView: View {
Text(String.localizedStringWithFormat(
NSLocalizedString("%@, %@", comment: "format for date separator in chat"),
date.formatted(.dateTime.weekday(.abbreviated)),
date.formatted(
Calendar.current.isDate(date, equalTo: .now, toGranularity: .year)
? .dateTime.day().month(.abbreviated)
: .dateTime.day().month(.abbreviated).year()
)
date.formatted(.dateTime.day().month(.abbreviated))
))
.font(.callout)
.fontWeight(.medium)
@@ -895,6 +891,7 @@ struct ChatView: View {
@State private var showDeleteMessages = false
@State private var showChatItemInfoSheet: Bool = false
@State private var chatItemInfo: ChatItemInfo?
@State private var showTranslationSheet: Bool = false
@State private var msgWidth: CGFloat = 0
@Binding var selectedChatItems: Set<Int64>?
@@ -1212,6 +1209,11 @@ struct ChatView: View {
}) {
ChatItemInfoView(ci: ci, chatItemInfo: $chatItemInfo)
}
.sheet(isPresented: $showTranslationSheet) {
if #available(iOS 18.0, *) {
TranslateView(source: ci.text).presentationDetents([.medium, .large])
}
}
}
private func showMemberImage(_ member: GroupMember, _ prevItem: ChatItem?) -> Bool {
@@ -1268,6 +1270,9 @@ struct ChatView: View {
shareButton(ci)
copyButton(ci)
}
if #available(iOS 18.0, *) {
if !ci.text.isEmpty { translateButton(ci) }
}
if let fileSource = fileSource, fileExists {
if case .image = ci.content.msgContent, let image = getLoadedImage(ci.file) {
if image.imageData != nil {
@@ -1452,6 +1457,14 @@ struct ChatView: View {
}
}
private func translateButton(_ ci: ChatItem) -> Button<some View> {
Button {
showTranslationSheet = true
} label: {
Label("Translate", systemImage: "globe")
}
}
func saveButton(image: UIImage) -> Button<some View> {
Button {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
@@ -105,10 +105,8 @@ struct AddGroupMembersViewCommon: View {
.padding(.leading, 2)
let s = searchText.trimmingCharacters(in: .whitespaces).localizedLowercase
let members = s == "" ? membersToAdd : membersToAdd.filter { $0.chatViewName.localizedLowercase.contains(s) }
ForEach(members + [dummyContact]) { contact in
if contact.contactId != dummyContact.contactId {
contactCheckView(contact)
}
ForEach(members) { contact in
contactCheckView(contact)
}
}
}
@@ -132,14 +130,6 @@ struct AddGroupMembersViewCommon: View {
.modifier(ThemedBackground(grouped: true))
}
// Resolves keyboard losing focus bug in iOS16 and iOS17,
// when there are no items inside `ForEach(memebers)` loop
private let dummyContact: Contact = {
var dummy = Contact.sampleData
dummy.contactId = -1
return dummy
}()
private func inviteMembersButton() -> some View {
Button {
inviteMembers()
@@ -0,0 +1,73 @@
//
// TranslateView.swift
// SimpleX
//
// Created by user on 19/09/2024.
// Copyright © 2024 SimpleX Chat. All rights reserved.
//
import SwiftUI
import Translation
@available(iOS 18.0, *)
struct TranslateView: View {
let source: String
@State private var supprtedLanguages = [Locale.Language]()
@State private var target: String?
@State private var configuration = TranslationSession.Configuration()
var body: some View {
NavigationStack {
List {
Section {
languagePicker("From", selection: $configuration.source)
Text(source).foregroundStyle(.secondary).lineLimit(1)
}
Section {
languagePicker("To ", selection: $configuration.target)
if let target {
Text(target)
} else {
ProgressView()
}
} footer: {
Text("\(Image(systemName: "info.circle")) Uses on device translation")
}
}
.navigationTitle("Translate")
}
.task { supprtedLanguages = await LanguageAvailability().supportedLanguages }
.translationTask(configuration) { session in
do {
target = nil
let response = try await session.translate(source)
await MainActor.run {
configuration.source = response.sourceLanguage
configuration.target = response.targetLanguage
target = response.targetText
}
} catch {
print(error)
}
}
}
@ViewBuilder
private func languagePicker(_ label: String, selection: Binding<Locale.Language?>) -> some View {
Picker(label, selection: selection) {
Text("Detect language").tag(Optional<Locale.Language>.none)
ForEach(supprtedLanguages, id: \.self) { language in
Text(title(for: language)).tag(language)
}
}
}
private func title(for language: Locale.Language) -> String {
if let code = language.languageCode,
let string = Locale.current.localizedString(forLanguageCode: code.identifier) {
string
} else {
language.minimalIdentifier
}
}
}
@@ -35,16 +35,11 @@ struct ChatPreviewView: View {
}
.padding(.leading, 4)
let chatTs = if let cItem {
cItem.meta.itemTs
} else {
chat.chatInfo.chatTs
}
VStack(spacing: 0) {
HStack(alignment: .top) {
chatPreviewTitle()
Spacer()
(formatTimestampText(chatTs))
(cItem?.timestampText ?? formatTimestampText(chat.chatInfo.chatTs))
.font(.subheadline)
.frame(minWidth: 60, alignment: .trailing)
.foregroundColor(theme.colors.secondary)
+135 -92
View File
@@ -14,20 +14,11 @@ struct UserPicker: View {
@Environment(\.colorScheme) private var colorScheme: ColorScheme
@Environment(\.dismiss) private var dismiss: DismissAction
@Binding var activeSheet: UserPickerSheet?
@State private var currentUser: Int64?
@State private var switchingProfile = false
@State private var frameWidth: CGFloat = 0
// Inset grouped list dimensions
private let imageSize: CGFloat = 44
private let rowPadding: CGFloat = 16
private let sectionSpacing: CGFloat = 35
private var sectionHorizontalPadding: CGFloat { frameWidth > 375 ? 20 : 16 }
private let sectionShape = RoundedRectangle(cornerRadius: 10, style: .continuous)
var body: some View {
if #available(iOS 16.0, *) {
let v = viewBody.presentationDetents([.height(400)])
let v = viewBody.presentationDetents([.height(420)])
if #available(iOS 16.4, *) {
v.scrollBounceBehavior(.basedOnSize)
} else {
@@ -37,80 +28,88 @@ struct UserPicker: View {
viewBody
}
}
@ViewBuilder
private var viewBody: some View {
let otherUsers: [UserInfo] = m.users
.filter { u in !u.user.hidden && u.user.userId != m.currentUser?.userId }
.sorted(using: KeyPathComparator<UserInfo>(\.user.activeOrder, order: .reverse))
let sectionWidth = max(frameWidth - sectionHorizontalPadding * 2, 0)
let currentUserWidth = max(frameWidth - sectionHorizontalPadding - rowPadding * 2 - 14 - imageSize, 0)
VStack(spacing: 0) {
if let user = m.currentUser {
StickyScrollView {
HStack(spacing: rowPadding) {
HStack {
ProfileImage(imageStr: user.image, size: imageSize, color: Color(uiColor: .tertiarySystemGroupedBackground))
.padding(.trailing, 6)
profileName(user).lineLimit(1)
}
.padding(rowPadding)
.frame(width: otherUsers.isEmpty ? sectionWidth : currentUserWidth, alignment: .leading)
.background(Color(.secondarySystemGroupedBackground))
.clipShape(sectionShape)
.onTapGesture { activeSheet = .currentProfile }
ForEach(otherUsers) { u in
userView(u, size: imageSize)
.frame(maxWidth: sectionWidth * 0.618)
.fixedSize()
}
}
.padding(.horizontal, sectionHorizontalPadding)
}
.frame(height: 2 * rowPadding + imageSize)
.padding(.top, sectionSpacing)
.overlay(DetermineWidth())
.onPreferenceChange(DetermineWidth.Key.self) { frameWidth = $0 }
}
List {
Section {
openSheetOnTap("qrcode", title: m.userAddress == nil ? "Create SimpleX address" : "Your SimpleX address", sheet: .address)
openSheetOnTap("switch.2", title: "Chat preferences", sheet: .chatPreferences)
openSheetOnTap("person.crop.rectangle.stack", title: "Your chat profiles", sheet: .chatProfiles)
openSheetOnTap("desktopcomputer", title: "Use from desktop", sheet: .useFromDesktop)
ZStack(alignment: .trailing) {
openSheetOnTap("gearshape", title: "Settings", sheet: .settings)
Image(systemName: colorScheme == .light ? "sun.max" : "moon.fill")
.resizable()
.symbolRenderingMode(.monochrome)
.foregroundColor(theme.colors.secondary)
.frame(maxWidth: 20, maxHeight: 20)
.onTapGesture {
if (colorScheme == .light) {
ThemeManager.applyTheme(systemDarkThemeDefault.get())
let otherUsers = m.users.filter { u in !u.user.hidden && u.user.userId != m.currentUser?.userId }
return List {
Section(header: Text("You").foregroundColor(theme.colors.secondary)) {
if let user = m.currentUser {
openSheetOnTap(label: {
ZStack {
let v = ProfilePreview(profileOf: user)
.foregroundColor(.primary)
.padding(.leading, -8)
if #available(iOS 16.0, *) {
v
} else {
ThemeManager.applyTheme(DefaultTheme.LIGHT.themeName)
v.padding(.vertical, 4)
}
}
.onLongPressGesture {
ThemeManager.applyTheme(DefaultTheme.SYSTEM_THEME_NAME)
}) {
activeSheet = .currentProfile
}
openSheetOnTap(title: m.userAddress == nil ? "Create SimpleX address" : "Your SimpleX address", icon: "qrcode") {
activeSheet = .address
}
openSheetOnTap(title: "Chat preferences", icon: "switch.2") {
activeSheet = .chatPreferences
}
}
}
Section {
if otherUsers.isEmpty {
openSheetOnTap(title: "Your chat profiles", icon: "person.crop.rectangle.stack") {
activeSheet = .chatProfiles
}
} else {
let v = userPickerRow(otherUsers, size: 44)
.padding(.leading, -11)
if #available(iOS 16.0, *) {
v
} else {
v.padding(.vertical, 4)
}
}
openSheetOnTap(title: "Use from desktop", icon: "desktopcomputer") {
activeSheet = .useFromDesktop
}
ZStack(alignment: .trailing) {
openSheetOnTap(title: "Settings", icon: "gearshape") {
activeSheet = .settings
}
Label {} icon: {
Image(systemName: colorScheme == .light ? "sun.max" : "moon.fill")
.resizable()
.symbolRenderingMode(.monochrome)
.foregroundColor(theme.colors.secondary)
.frame(maxWidth: 20, maxHeight: 20)
}
.onTapGesture {
if (colorScheme == .light) {
ThemeManager.applyTheme(systemDarkThemeDefault.get())
} else {
ThemeManager.applyTheme(DefaultTheme.LIGHT.themeName)
}
}
.onLongPressGesture {
ThemeManager.applyTheme(DefaultTheme.SYSTEM_THEME_NAME)
}
}
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
.onAppear {
// This check prevents the call of listUsers after the app is suspended, and the database is closed.
if case .active = scenePhase {
currentUser = m.currentUser?.userId
Task {
do {
let users = try await listUsersAsync()
await MainActor.run {
m.users = users
currentUser = m.currentUser?.userId
}
await MainActor.run { m.users = users }
} catch {
logger.error("Error loading users \(responseError(error))")
}
@@ -120,34 +119,71 @@ struct UserPicker: View {
.modifier(ThemedBackground(grouped: true))
.disabled(switchingProfile)
}
private func userPickerRow(_ users: [UserInfo], size: CGFloat) -> some View {
HStack(spacing: 6) {
let s = ScrollView(.horizontal) {
HStack(spacing: 27) {
ForEach(users) { u in
if !u.user.hidden && u.user.userId != m.currentUser?.userId {
userView(u, size: size)
}
}
}
.padding(.leading, 4)
.padding(.trailing, 22)
}
ZStack(alignment: .trailing) {
if #available(iOS 16.0, *) {
s.scrollIndicators(.hidden)
} else {
s
}
LinearGradient(
colors: [.clear, .black],
startPoint: .leading,
endPoint: .trailing
)
.frame(width: size, height: size + 3)
.blendMode(.destinationOut)
.allowsHitTesting(false)
}
.compositingGroup()
.padding(.top, -3) // to fit unread badge
Spacer()
Image(systemName: "chevron.right")
.foregroundColor(theme.colors.secondary)
.padding(.trailing, 4)
.onTapGesture {
activeSheet = .chatProfiles
}
}
}
private func userView(_ u: UserInfo, size: CGFloat) -> some View {
HStack {
ZStack(alignment: .topTrailing) {
ProfileImage(imageStr: u.user.image, size: size, color: Color(uiColor: .tertiarySystemGroupedBackground))
if (u.unreadCount > 0) {
unreadBadge(u).offset(x: 4, y: -4)
}
ZStack(alignment: .topTrailing) {
ProfileImage(imageStr: u.user.image, size: size, color: Color(uiColor: .tertiarySystemGroupedBackground))
.padding([.top, .trailing], 3)
if (u.unreadCount > 0) {
unreadBadge(u)
}
.padding(.trailing, 6)
Text(u.user.displayName).font(.title2).lineLimit(1)
}
.padding(rowPadding)
.background(Color(.secondarySystemGroupedBackground))
.clipShape(sectionShape)
.frame(width: size)
.onTapGesture {
switchingProfile = true
dismiss()
Task {
do {
try await changeActiveUserAsync_(u.user.userId, viewPwd: nil)
await MainActor.run { switchingProfile = false }
await MainActor.run {
switchingProfile = false
dismiss()
}
} catch {
await MainActor.run {
switchingProfile = false
showAlert(
NSLocalizedString("Error switching profile!", comment: "alertTitle"),
message: String.localizedStringWithFormat(NSLocalizedString("Error: %@", comment: "alert message"), responseError(error))
AlertManager.shared.showAlertMsg(
title: "Error switching profile!",
message: "Error: \(responseError(error))"
)
}
}
@@ -155,14 +191,21 @@ struct UserPicker: View {
}
}
private func openSheetOnTap(_ icon: String, title: LocalizedStringKey, sheet: UserPickerSheet) -> some View {
Button {
activeSheet = sheet
} label: {
settingsRow(icon, color: theme.colors.secondary) {
Text(title).foregroundColor(.primary)
private func openSheetOnTap(title: LocalizedStringKey, icon: String, action: @escaping () -> Void) -> some View {
openSheetOnTap(label: {
ZStack(alignment: .leading) {
Image(systemName: icon).frame(maxWidth: 24, maxHeight: 24, alignment: .center)
.symbolRenderingMode(.monochrome)
.foregroundColor(theme.colors.secondary)
Text(title)
.foregroundColor(.primary)
.padding(.leading, 36)
}
}
}, action: action)
}
private func openSheetOnTap<V: View>(label: () -> V, action: @escaping () -> Void) -> some View {
Button(action: action, label: label)
.frame(maxWidth: .infinity, alignment: .leading)
.contentShape(Rectangle())
}
@@ -1,52 +0,0 @@
//
// StickyScrollView.swift
// SimpleX (iOS)
//
// Created by user on 20/09/2024.
// Copyright © 2024 SimpleX Chat. All rights reserved.
//
import SwiftUI
struct StickyScrollView<Content: View>: UIViewRepresentable {
@ViewBuilder let content: () -> Content
func makeUIView(context: Context) -> UIScrollView {
let hc = context.coordinator.hostingController
hc.view.backgroundColor = .clear
let sv = UIScrollView()
sv.showsHorizontalScrollIndicator = false
sv.addSubview(hc.view)
sv.delegate = context.coordinator
return sv
}
func updateUIView(_ scrollView: UIScrollView, context: Context) {
let hc = context.coordinator.hostingController
hc.rootView = content()
hc.view.frame.size = hc.view.intrinsicContentSize
scrollView.contentSize = hc.view.intrinsicContentSize
}
func makeCoordinator() -> Coordinator {
Coordinator(content: content())
}
class Coordinator: NSObject, UIScrollViewDelegate {
let hostingController: UIHostingController<Content>
init(content: Content) {
self.hostingController = UIHostingController(rootView: content)
}
func scrollViewWillEndDragging(
_ scrollView: UIScrollView,
withVelocity velocity: CGPoint,
targetContentOffset: UnsafeMutablePointer<CGPoint>
) {
if targetContentOffset.pointee.x < 32 {
targetContentOffset.pointee.x = 0
}
}
}
}
@@ -808,7 +808,7 @@ struct ThemeDestinationPicker: View {
@Binding var customizeThemeIsOpen: Bool
var body: some View {
let values = [(nil, NSLocalizedString("All profiles", comment: "profile dropdown"))] + m.users.filter { $0.user.activeUser }.map { ($0.user.userId, $0.user.chatViewName)}
let values = [(nil, "All profiles")] + m.users.filter { $0.user.activeUser }.map { ($0.user.userId, $0.user.chatViewName)}
if values.contains(where: { (userId, text) in userId == themeUserDestination?.0 }) {
Picker("Apply to", selection: $themeUserDest) {
@@ -507,18 +507,18 @@ struct ProfilePreview: View {
HStack {
ProfileImage(imageStr: profileOf.image, size: 44, color: color)
.padding(.trailing, 6)
profileName(profileOf).lineLimit(1)
profileName().lineLimit(1)
}
}
}
func profileName(_ profileOf: NamedChat) -> Text {
var t = Text(profileOf.displayName).fontWeight(.semibold).font(.title2)
if profileOf.fullName != "" && profileOf.fullName != profileOf.displayName {
t = t + Text(" (" + profileOf.fullName + ")")
private func profileName() -> Text {
var t = Text(profileOf.displayName).fontWeight(.semibold).font(.title2)
if profileOf.fullName != "" && profileOf.fullName != profileOf.displayName {
t = t + Text(" (" + profileOf.fullName + ")")
// .font(.callout)
}
return t
}
return t
}
}
struct SettingsView_Previews: PreviewProvider {
@@ -161,31 +161,11 @@
<target>%d дни</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d часа</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d мин.</target>
@@ -1214,7 +1194,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Файлът не може да бъде получен</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2370,10 +2350,6 @@ This is your own one-time link!</source>
<target>Не изпращай история на нови членове.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Не създавай адрес</target>
@@ -2397,8 +2373,7 @@ This is your own one-time link!</source>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>Изтегли</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2414,10 +2389,6 @@ This is your own one-time link!</source>
<target>Свали файл</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<note>No comment provided by engineer.</note>
@@ -2838,7 +2809,7 @@ This is your own one-time link!</source>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Грешка при получаване на файл</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3064,11 +3035,6 @@ This is your own one-time link!</source>
<source>File error</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<note>file error text</note>
@@ -3199,23 +3165,11 @@ This is your own one-time link!</source>
<target>Препрати</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>Препращане и запазване на съобщения</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>Препратено</target>
@@ -3226,10 +3180,6 @@ This is your own one-time link!</source>
<target>Препратено от</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>
<note>No comment provided by engineer.</note>
@@ -3515,10 +3465,6 @@ Error: %2$@</source>
<target>ICE сървъри (по един на ред)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Ако не можете да се срещнете лично, покажете QR код във видеоразговора или споделете линка.</target>
@@ -4200,10 +4146,6 @@ This is your link for group %@!</source>
<source>Messages sent</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>Съобщенията, файловете и разговорите са защитени чрез **криптиране от край до край** с перфектна секретност при препращане, правдоподобно опровержение и възстановяване при взлом.</target>
@@ -4493,10 +4435,6 @@ This is your link for group %@!</source>
<source>Nothing selected</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Известия</target>
@@ -4529,7 +4467,7 @@ This is your link for group %@!</source>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Ок</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4717,11 +4655,6 @@ Requires compatible VPN.</source>
<source>Other %@ servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>PING бройка</target>
@@ -4757,10 +4690,6 @@ Requires compatible VPN.</source>
<target>Кодът за достъп е зададен!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Парола за показване</target>
@@ -4905,10 +4834,6 @@ Error: %@</source>
<target>Полски интерфейс</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Въжможно е пръстовият отпечатък на сертификата в адреса на сървъра да е неправилен</target>
@@ -5085,10 +5010,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>Proxied servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Push известия</target>
@@ -5477,10 +5398,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>SMP server</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<note>No comment provided by engineer.</note>
@@ -5589,10 +5506,6 @@ Enable in *Network &amp; servers* settings.</source>
<target>Запазено съобщение</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<note>No comment provided by engineer.</note>
@@ -5785,7 +5698,7 @@ Enable in *Network &amp; servers* settings.</source>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>Подателят отмени прехвърлянето на файла.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -6825,7 +6738,7 @@ You will be prompted to complete authentication before this feature is enabled.<
</trans-unit>
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -6935,10 +6848,6 @@ To connect, please ask your contact to create another connection link and check
<target>Използвай .onion хостове</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>Използвай сървърите на SimpleX Chat?</target>
@@ -7010,10 +6919,6 @@ To connect, please ask your contact to create another connection link and check
<source>User selection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>Използват се сървърите на SimpleX Chat.</target>
@@ -7243,7 +7148,7 @@ To connect, please ask your contact to create another connection link and check
</trans-unit>
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7642,10 +7547,6 @@ Repeat connection request?</source>
<target>Вашите контакти ще останат свързани.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Вашата текуща чат база данни ще бъде ИЗТРИТА и ЗАМЕНЕНА с импортираната.</target>
@@ -158,31 +158,11 @@
<target>%d dní</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d hodin</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d minuty</target>
@@ -1173,7 +1153,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Nelze přijmout soubor</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2291,10 +2271,6 @@ This is your own one-time link!</source>
<source>Do not send history to new members.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Nevytvářet adresu</target>
@@ -2317,8 +2293,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2333,10 +2308,6 @@ This is your own one-time link!</source>
<target>Stáhnout soubor</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<note>No comment provided by engineer.</note>
@@ -2742,7 +2713,7 @@ This is your own one-time link!</source>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Chyba při příjmu souboru</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -2961,11 +2932,6 @@ This is your own one-time link!</source>
<source>File error</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<note>file error text</note>
@@ -3092,22 +3058,10 @@ This is your own one-time link!</source>
<source>Forward</source>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<note>No comment provided by engineer.</note>
@@ -3116,10 +3070,6 @@ This is your own one-time link!</source>
<source>Forwarded from</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>
<note>No comment provided by engineer.</note>
@@ -3398,10 +3348,6 @@ Error: %2$@</source>
<target>Servery ICE (jeden na řádek)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Pokud se nemůžete setkat osobně, zobrazte QR kód ve videohovoru nebo sdílejte odkaz.</target>
@@ -4056,10 +4002,6 @@ This is your link for group %@!</source>
<source>Messages sent</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<note>No comment provided by engineer.</note>
@@ -4334,10 +4276,6 @@ This is your link for group %@!</source>
<source>Nothing selected</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Oznámení</target>
@@ -4369,7 +4307,7 @@ This is your link for group %@!</source>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Ok</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4549,11 +4487,6 @@ Vyžaduje povolení sítě VPN.</target>
<source>Other %@ servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>Počet PING</target>
@@ -4589,10 +4522,6 @@ Vyžaduje povolení sítě VPN.</target>
<target>Heslo nastaveno!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Heslo k zobrazení</target>
@@ -4729,10 +4658,6 @@ Error: %@</source>
<target>Polské rozhraní</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Je možné, že otisk certifikátu v adrese serveru je nesprávný</target>
@@ -4906,10 +4831,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>Proxied servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Nabízená oznámení</target>
@@ -5287,10 +5208,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>SMP server</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<note>No comment provided by engineer.</note>
@@ -5395,10 +5312,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>Saved message</source>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<note>No comment provided by engineer.</note>
@@ -5587,7 +5500,7 @@ Enable in *Network &amp; servers* settings.</source>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>Odesílatel zrušil přenos souboru.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -6598,7 +6511,7 @@ Před zapnutím této funkce budete vyzváni k dokončení ověření.</target>
</trans-unit>
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -6703,10 +6616,6 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu
<target>Použít hostitele .onion</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>Používat servery SimpleX Chat?</target>
@@ -6775,10 +6684,6 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu
<source>User selection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>Používat servery SimpleX Chat.</target>
@@ -6991,7 +6896,7 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu
</trans-unit>
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7373,10 +7278,6 @@ Repeat connection request?</source>
<target>Vaše kontakty zůstanou připojeny.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Vaše aktuální chat databáze bude ODSTRANĚNA a NAHRAZENA importovanou.</target>
@@ -139,7 +139,6 @@
</trans-unit>
<trans-unit id="%@, %@" xml:space="preserve">
<source>%1$@, %2$@</source>
<target>%1$@, %2$@</target>
<note>format for date separator in chat</note>
</trans-unit>
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
@@ -162,31 +161,11 @@
<target>%d Tage</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d Stunden</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d min</target>
@@ -1047,7 +1026,6 @@
</trans-unit>
<trans-unit id="Auto-accept settings" xml:space="preserve">
<source>Auto-accept settings</source>
<target>Einstellungen automatisch akzeptieren</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="Back" xml:space="preserve">
@@ -1243,7 +1221,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Datei kann nicht empfangen werden</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -1373,7 +1351,6 @@
</trans-unit>
<trans-unit id="Chat preferences were changed." xml:space="preserve">
<source>Chat preferences were changed.</source>
<target>Die Chat-Präferenzen wurden geändert.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Chat theme" xml:space="preserve">
@@ -1777,7 +1754,6 @@ Das ist Ihr eigener Einmal-Link!</target>
</trans-unit>
<trans-unit id="Corner" xml:space="preserve">
<source>Corner</source>
<target>Ecke</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Correct name to %@?" xml:space="preserve">
@@ -2449,10 +2425,6 @@ Das ist Ihr eigener Einmal-Link!</target>
<target>Den Nachrichtenverlauf nicht an neue Mitglieder senden.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Keine Adresse erstellt</target>
@@ -2476,8 +2448,7 @@ Das ist Ihr eigener Einmal-Link!</target>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>Herunterladen</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2494,10 +2465,6 @@ Das ist Ihr eigener Einmal-Link!</target>
<target>Datei herunterladen</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<target>Heruntergeladen</target>
@@ -2775,7 +2742,6 @@ Das ist Ihr eigener Einmal-Link!</target>
</trans-unit>
<trans-unit id="Error changing connection profile" xml:space="preserve">
<source>Error changing connection profile</source>
<target>Fehler beim Wechseln des Verbindungs-Profils</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error changing role" xml:space="preserve">
@@ -2790,7 +2756,6 @@ Das ist Ihr eigener Einmal-Link!</target>
</trans-unit>
<trans-unit id="Error changing to incognito!" xml:space="preserve">
<source>Error changing to incognito!</source>
<target>Fehler beim Wechseln zum Inkognito-Profil!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
@@ -2915,7 +2880,6 @@ Das ist Ihr eigener Einmal-Link!</target>
</trans-unit>
<trans-unit id="Error migrating settings" xml:space="preserve">
<source>Error migrating settings</source>
<target>Fehler beim Migrieren der Einstellungen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error opening chat" xml:space="preserve">
@@ -2926,7 +2890,7 @@ Das ist Ihr eigener Einmal-Link!</target>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Fehler beim Empfangen der Datei</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3020,7 +2984,6 @@ Das ist Ihr eigener Einmal-Link!</target>
</trans-unit>
<trans-unit id="Error switching profile" xml:space="preserve">
<source>Error switching profile</source>
<target>Fehler beim Wechseln des Profils</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error switching profile!" xml:space="preserve">
@@ -3159,11 +3122,6 @@ Das ist Ihr eigener Einmal-Link!</target>
<target>Datei-Fehler</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<target>Datei nicht gefunden - höchstwahrscheinlich wurde die Datei gelöscht oder der Transfer abgebrochen.</target>
@@ -3299,23 +3257,11 @@ Das ist Ihr eigener Einmal-Link!</target>
<target>Weiterleiten</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>Nachrichten weiterleiten und speichern</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>Weitergeleitet</target>
@@ -3326,10 +3272,6 @@ Das ist Ihr eigener Einmal-Link!</target>
<target>Weitergeleitet aus</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>Weiterleitungsserver %@ konnte sich nicht mit dem Zielserver %@ verbinden. Bitte versuchen Sie es später erneut.</target>
@@ -3624,10 +3566,6 @@ Fehler: %2$@</target>
<target>ICE-Server (einer pro Zeile)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Falls Sie sich nicht persönlich treffen können, zeigen Sie den QR-Code in einem Videoanruf oder teilen Sie den Link.</target>
@@ -4275,7 +4213,6 @@ Das ist Ihr Link für die Gruppe %@!</target>
</trans-unit>
<trans-unit id="Message shape" xml:space="preserve">
<source>Message shape</source>
<target>Nachrichten-Form</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Message source remains private." xml:space="preserve">
@@ -4328,10 +4265,6 @@ Das ist Ihr Link für die Gruppe %@!</target>
<target>Gesendete Nachrichten</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>Nachrichten, Dateien und Anrufe sind durch **Ende-zu-Ende-Verschlüsselung** mit Perfect Forward Secrecy, Ablehnung und Einbruchs-Wiederherstellung geschützt.</target>
@@ -4627,10 +4560,6 @@ Das ist Ihr Link für die Gruppe %@!</target>
<target>Nichts ausgewählt</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Benachrichtigungen</target>
@@ -4663,7 +4592,7 @@ Das ist Ihr Link für die Gruppe %@!</target>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Ok</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4854,11 +4783,6 @@ Dies erfordert die Aktivierung eines VPNs.</target>
<target>Andere %@ Server</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>PING-Zähler</target>
@@ -4894,10 +4818,6 @@ Dies erfordert die Aktivierung eines VPNs.</target>
<target>Zugangscode eingestellt!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Passwort anzeigen</target>
@@ -5047,10 +4967,6 @@ Fehler: %@</target>
<target>Polnische Bedienoberfläche</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Der Fingerabdruck des Zertifikats in der Serveradresse ist wahrscheinlich ungültig</target>
@@ -5238,10 +5154,6 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
<target>Proxy-Server</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Push-Benachrichtigungen</target>
@@ -5465,7 +5377,6 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
</trans-unit>
<trans-unit id="Remove archive?" xml:space="preserve">
<source>Remove archive?</source>
<target>Archiv entfernen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Remove image" xml:space="preserve">
@@ -5648,10 +5559,6 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
<target>SMP-Server</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<target>Dateien sicher empfangen</target>
@@ -5740,7 +5647,6 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
</trans-unit>
<trans-unit id="Save your profile?" xml:space="preserve">
<source>Save your profile?</source>
<target>Ihr Profil speichern?</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="Saved" xml:space="preserve">
@@ -5763,10 +5669,6 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
<target>Gespeicherte Nachricht</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<target>Skalieren</target>
@@ -5849,7 +5751,6 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
</trans-unit>
<trans-unit id="Select chat profile" xml:space="preserve">
<source>Select chat profile</source>
<target>Chat-Profil auswählen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Selected %lld" xml:space="preserve">
@@ -5970,7 +5871,7 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>Der Absender hat die Dateiübertragung abgebrochen.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -6189,7 +6090,6 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
</trans-unit>
<trans-unit id="Settings were changed." xml:space="preserve">
<source>Settings were changed.</source>
<target>Die Einstellungen wurden geändert.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Shape profile images" xml:space="preserve">
@@ -6229,7 +6129,6 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
</trans-unit>
<trans-unit id="Share profile" xml:space="preserve">
<source>Share profile</source>
<target>Profil teilen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
@@ -6399,7 +6298,6 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
</trans-unit>
<trans-unit id="Some app settings were not migrated." xml:space="preserve">
<source>Some app settings were not migrated.</source>
<target>Einige App-Einstellungen wurden nicht migriert.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Some file(s) were not exported:" xml:space="preserve">
@@ -6579,7 +6477,6 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
</trans-unit>
<trans-unit id="Tail" xml:space="preserve">
<source>Tail</source>
<target>Sprechblase</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Take picture" xml:space="preserve">
@@ -6776,7 +6673,6 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro
</trans-unit>
<trans-unit id="The uploaded database archive will be permanently removed from the servers." xml:space="preserve">
<source>The uploaded database archive will be permanently removed from the servers.</source>
<target>Das hochgeladene Datenbank-Archiv wird dauerhaft von den Servern entfernt.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Themes" xml:space="preserve">
@@ -7059,7 +6955,7 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<target>Unbekannte Server!</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -7173,10 +7069,6 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
<target>Verwende .onion-Hosts</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>Verwenden Sie SimpleX-Chat-Server?</target>
@@ -7252,10 +7144,6 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
<target>Benutzer-Auswahl</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>Verwendung von SimpleX-Chat-Servern.</target>
@@ -7489,7 +7377,7 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<target>Ohne Tor- oder VPN-Nutzung wird Ihre IP-Adresse für diese XFTP-Relais sichtbar sein: %@.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7872,7 +7760,6 @@ Verbindungsanfrage wiederholen?</target>
</trans-unit>
<trans-unit id="Your chat preferences" xml:space="preserve">
<source>Your chat preferences</source>
<target>Ihre Chat-Präferenzen</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="Your chat profiles" xml:space="preserve">
@@ -7882,7 +7769,6 @@ Verbindungsanfrage wiederholen?</target>
</trans-unit>
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
<target>Ihre Verbindung wurde auf %@ verschoben. Während Sie auf das Profil weitergeleitet wurden trat aber ein unerwarteter Fehler auf.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
@@ -7900,10 +7786,6 @@ Verbindungsanfrage wiederholen?</target>
<target>Ihre Kontakte bleiben weiterhin verbunden.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Ihre aktuelle Chat-Datenbank wird GELÖSCHT und durch die Importierte ERSETZT.</target>
@@ -7941,7 +7823,6 @@ Verbindungsanfrage wiederholen?</target>
</trans-unit>
<trans-unit id="Your profile was changed. If you save it, the updated profile will be sent to all your contacts." xml:space="preserve">
<source>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</source>
<target>Ihr Profil wurde geändert. Wenn Sie es speichern, wird das aktualisierte Profil an alle Ihre Kontakte gesendet.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
@@ -162,36 +162,11 @@
<target>%d days</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<target>%d file(s) are still being downloaded.</target>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<target>%d file(s) failed to download.</target>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<target>%d file(s) were deleted.</target>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<target>%d file(s) were not downloaded.</target>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d hours</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<target>%d messages not forwarded</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d min</target>
@@ -1248,7 +1223,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Cannot receive file</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2454,11 +2429,6 @@ This is your own one-time link!</target>
<target>Do not send history to new members.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<target>Do not use credentials with proxy.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Don't create address</target>
@@ -2482,8 +2452,7 @@ This is your own one-time link!</target>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>Download</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2500,11 +2469,6 @@ This is your own one-time link!</target>
<target>Download file</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<target>Download files</target>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<target>Downloaded</target>
@@ -2933,7 +2897,7 @@ This is your own one-time link!</target>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Error receiving file</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3166,13 +3130,6 @@ This is your own one-time link!</target>
<target>File error</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<target>File errors:
%@</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<target>File not found - most likely file was deleted or cancelled.</target>
@@ -3308,26 +3265,11 @@ This is your own one-time link!</target>
<target>Forward</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<target>Forward %d message(s)?</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>Forward and save messages</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<target>Forward messages</target>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<target>Forward messages without files?</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>Forwarded</target>
@@ -3338,11 +3280,6 @@ This is your own one-time link!</target>
<target>Forwarded from</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<target>Forwarding %lld messages</target>
<note>No comment provided by engineer.</note>
</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>Forwarding server %@ failed to connect to destination server %@. Please try later.</target>
@@ -3637,11 +3574,6 @@ Error: %2$@</target>
<target>ICE servers (one per line)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<target>IP address</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>If you can't meet in person, show QR code in a video call, or share the link.</target>
@@ -4342,11 +4274,6 @@ This is your link for group %@!</target>
<target>Messages sent</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<target>Messages were deleted after you selected them.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</target>
@@ -4642,11 +4569,6 @@ This is your link for group %@!</target>
<target>Nothing selected</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<target>Nothing to forward!</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Notifications</target>
@@ -4679,7 +4601,7 @@ This is your link for group %@!</target>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Ok</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4870,13 +4792,6 @@ Requires compatible VPN.</target>
<target>Other %@ servers</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<target>Other file errors:
%@</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>PING count</target>
@@ -4912,11 +4827,6 @@ Requires compatible VPN.</target>
<target>Passcode set!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<target>Password</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Password to show</target>
@@ -5066,11 +4976,6 @@ Error: %@</target>
<target>Polish interface</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<target>Port</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Possibly, certificate fingerprint in server address is incorrect</target>
@@ -5258,11 +5163,6 @@ Enable in *Network &amp; servers* settings.</target>
<target>Proxied servers</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<target>Proxy requires password</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Push notifications</target>
@@ -5669,11 +5569,6 @@ Enable in *Network &amp; servers* settings.</target>
<target>SMP server</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<target>SOCKS proxy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<target>Safely receive files</target>
@@ -5785,11 +5680,6 @@ Enable in *Network &amp; servers* settings.</target>
<target>Saved message</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<target>Saving %lld messages</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<target>Scale</target>
@@ -5993,7 +5883,7 @@ Enable in *Network &amp; servers* settings.</target>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>Sender cancelled file transfer.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -7082,7 +6972,7 @@ You will be prompted to complete authentication before this feature is enabled.<
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<target>Unknown servers!</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -7196,11 +7086,6 @@ To connect, please ask your contact to create another connection link and check
<target>Use .onion hosts</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<target>Use SOCKS proxy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>Use SimpleX Chat servers?</target>
@@ -7276,11 +7161,6 @@ To connect, please ask your contact to create another connection link and check
<target>User selection</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<target>Username</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>Using SimpleX Chat servers.</target>
@@ -7514,7 +7394,7 @@ To connect, please ask your contact to create another connection link and check
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<target>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7925,11 +7805,6 @@ Repeat connection request?</target>
<target>Your contacts will remain connected.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<target>Your credentials may be sent unencrypted.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Your current chat database will be DELETED and REPLACED with the imported one.</target>
@@ -161,31 +161,11 @@
<target>%d días</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d horas</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d minutos</target>
@@ -1241,7 +1221,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>No se puede recibir el archivo</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2445,10 +2425,6 @@ This is your own one-time link!</source>
<target>No se envía el historial a los miembros nuevos.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>No crear dirección SimpleX</target>
@@ -2472,8 +2448,7 @@ This is your own one-time link!</source>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>Descargar</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2490,10 +2465,6 @@ This is your own one-time link!</source>
<target>Descargar archivo</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<target>Descargado</target>
@@ -2919,7 +2890,7 @@ This is your own one-time link!</source>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Error al recibir archivo</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3151,11 +3122,6 @@ This is your own one-time link!</source>
<target>Error de archivo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<target>Archivo no encontrado, probablemente haya sido borrado o cancelado.</target>
@@ -3291,23 +3257,11 @@ This is your own one-time link!</source>
<target>Reenviar</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>Reenviar y guardar mensajes</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>Reenviado</target>
@@ -3318,10 +3272,6 @@ This is your own one-time link!</source>
<target>Reenviado por</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>El servidor de reenvío %@ no ha podido conectarse al servidor de destino %@. Por favor, intentalo más tarde.</target>
@@ -3616,10 +3566,6 @@ Error: %2$@</target>
<target>Servidores ICE (uno por línea)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Si no puedes reunirte en persona, muestra el código QR por videollamada o comparte el enlace.</target>
@@ -4319,10 +4265,6 @@ This is your link for group %@!</source>
<target>Mensajes enviados</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>Los mensajes, archivos y llamadas están protegidos mediante **cifrado de extremo a extremo** con secreto perfecto hacía adelante, repudio y recuperación tras ataque.</target>
@@ -4618,10 +4560,6 @@ This is your link for group %@!</source>
<target>Nada seleccionado</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Notificaciones</target>
@@ -4654,7 +4592,7 @@ This is your link for group %@!</source>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Ok</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4845,11 +4783,6 @@ Requiere activación de la VPN.</target>
<target>Otros servidores %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>Contador PING</target>
@@ -4885,10 +4818,6 @@ Requiere activación de la VPN.</target>
<target>¡Código de acceso guardado!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Contraseña para hacerlo visible</target>
@@ -5038,10 +4967,6 @@ Error: %@</target>
<target>Interfaz en polaco</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Posiblemente la huella digital del certificado en la dirección del servidor es incorrecta</target>
@@ -5229,10 +5154,6 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
<target>Servidores con proxy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Notificaciones automáticas</target>
@@ -5638,10 +5559,6 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
<target>Servidor SMP</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<target>Recibe archivos de forma segura</target>
@@ -5752,10 +5669,6 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
<target>Mensaje guardado</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<target>Escala</target>
@@ -5958,7 +5871,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>El remitente ha cancelado la transferencia de archivos.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -7042,7 +6955,7 @@ Se te pedirá que completes la autenticación antes de activar esta función.</t
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<target>¡Servidores desconocidos!</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -7156,10 +7069,6 @@ Para conectarte pide a tu contacto que cree otro enlace y comprueba la conexión
<target>Usar hosts .onion</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>¿Usar servidores SimpleX Chat?</target>
@@ -7235,10 +7144,6 @@ Para conectarte pide a tu contacto que cree otro enlace y comprueba la conexión
<target>Selección de usuarios</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>Usar servidores SimpleX Chat.</target>
@@ -7472,7 +7377,7 @@ Para conectarte pide a tu contacto que cree otro enlace y comprueba la conexión
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<target>Sin Tor o VPN, tu dirección IP será visible para estos servidores XFTP: %@.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7881,10 +7786,6 @@ Repeat connection request?</source>
<target>Tus contactos permanecerán conectados.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>La base de datos actual será ELIMINADA y SUSTITUIDA por la importada.</target>
@@ -156,31 +156,11 @@
<target>%d päivää</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d tuntia</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d min</target>
@@ -1166,7 +1146,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Tiedostoa ei voi vastaanottaa</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2284,10 +2264,6 @@ This is your own one-time link!</source>
<source>Do not send history to new members.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Älä luo osoitetta</target>
@@ -2310,8 +2286,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2326,10 +2301,6 @@ This is your own one-time link!</source>
<target>Lataa tiedosto</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<note>No comment provided by engineer.</note>
@@ -2733,7 +2704,7 @@ This is your own one-time link!</source>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Virhe tiedoston vastaanottamisessa</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -2951,11 +2922,6 @@ This is your own one-time link!</source>
<source>File error</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<note>file error text</note>
@@ -3082,22 +3048,10 @@ This is your own one-time link!</source>
<source>Forward</source>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<note>No comment provided by engineer.</note>
@@ -3106,10 +3060,6 @@ This is your own one-time link!</source>
<source>Forwarded from</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>
<note>No comment provided by engineer.</note>
@@ -3388,10 +3338,6 @@ Error: %2$@</source>
<target>ICE-palvelimet (yksi per rivi)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Jos et voi tavata henkilökohtaisesti, näytä QR-koodi videopuhelussa tai jaa linkki.</target>
@@ -4046,10 +3992,6 @@ This is your link for group %@!</source>
<source>Messages sent</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<note>No comment provided by engineer.</note>
@@ -4323,10 +4265,6 @@ This is your link for group %@!</source>
<source>Nothing selected</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Ilmoitukset</target>
@@ -4358,7 +4296,7 @@ This is your link for group %@!</source>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Ok</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4537,11 +4475,6 @@ Edellyttää VPN:n sallimista.</target>
<source>Other %@ servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>PING-määrä</target>
@@ -4577,10 +4510,6 @@ Edellyttää VPN:n sallimista.</target>
<target>Pääsykoodi asetettu!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Salasana näytettäväksi</target>
@@ -4717,10 +4646,6 @@ Error: %@</source>
<target>Puolalainen käyttöliittymä</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Palvelimen osoitteen varmenteen sormenjälki on mahdollisesti virheellinen</target>
@@ -4894,10 +4819,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>Proxied servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Push-ilmoitukset</target>
@@ -5275,10 +5196,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>SMP server</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<note>No comment provided by engineer.</note>
@@ -5383,10 +5300,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>Saved message</source>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<note>No comment provided by engineer.</note>
@@ -5574,7 +5487,7 @@ Enable in *Network &amp; servers* settings.</source>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>Lähettäjä peruutti tiedoston siirron.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -6583,7 +6496,7 @@ Sinua kehotetaan suorittamaan todennus loppuun, ennen kuin tämä ominaisuus ote
</trans-unit>
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -6688,10 +6601,6 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja
<target>Käytä .onion-isäntiä</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>Käytä SimpleX Chat palvelimia?</target>
@@ -6760,10 +6669,6 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja
<source>User selection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>Käyttää SimpleX Chat -palvelimia.</target>
@@ -6976,7 +6881,7 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja
</trans-unit>
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7358,10 +7263,6 @@ Repeat connection request?</source>
<target>Kontaktisi pysyvät yhdistettyinä.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Nykyinen keskustelut-tietokantasi poistetaan ja korvataan tuodulla tietokannalla.</target>
@@ -161,31 +161,11 @@
<target>%d jours</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d heures</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d min</target>
@@ -1241,7 +1221,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Impossible de recevoir le fichier</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2445,10 +2425,6 @@ Il s'agit de votre propre lien unique !</target>
<target>Ne pas envoyer d'historique aux nouveaux membres.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Ne pas créer d'adresse</target>
@@ -2472,8 +2448,7 @@ Il s'agit de votre propre lien unique !</target>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>Télécharger</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2490,10 +2465,6 @@ Il s'agit de votre propre lien unique !</target>
<target>Télécharger le fichier</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<target>Téléchargé</target>
@@ -2919,7 +2890,7 @@ Il s'agit de votre propre lien unique !</target>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Erreur lors de la réception du fichier</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3151,11 +3122,6 @@ Il s'agit de votre propre lien unique !</target>
<target>Erreur de fichier</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<target>Fichier introuvable - le fichier a probablement été supprimé ou annulé.</target>
@@ -3291,23 +3257,11 @@ Il s'agit de votre propre lien unique !</target>
<target>Transférer</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>Transférer et sauvegarder des messages</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>Transféré</target>
@@ -3318,10 +3272,6 @@ Il s'agit de votre propre lien unique !</target>
<target>Transféré depuis</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>Le serveur de redirection %@ n'a pas réussi à se connecter au serveur de destination %@. Veuillez réessayer plus tard.</target>
@@ -3616,10 +3566,6 @@ Erreur: %2$@</target>
<target>Serveurs ICE (un par ligne)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Si vous ne pouvez pas vous rencontrer en personne, montrez le code QR lors d'un appel vidéo ou partagez le lien.</target>
@@ -4319,10 +4265,6 @@ Voici votre lien pour le groupe %@ !</target>
<target>Messages envoyés</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>Les messages, fichiers et appels sont protégés par un chiffrement **de bout en bout** avec une confidentialité persistante, une répudiation et une récupération en cas d'effraction.</target>
@@ -4618,10 +4560,6 @@ Voici votre lien pour le groupe %@ !</target>
<target>Aucune sélection</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Notifications</target>
@@ -4654,7 +4592,7 @@ Voici votre lien pour le groupe %@ !</target>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Ok</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4845,11 +4783,6 @@ Nécessite l'activation d'un VPN.</target>
<target>Autres serveurs %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>Nombre de PING</target>
@@ -4885,10 +4818,6 @@ Nécessite l'activation d'un VPN.</target>
<target>Code d'accès défini !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Mot de passe à entrer</target>
@@ -5038,10 +4967,6 @@ Erreur: %@</target>
<target>Interface en polonais</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Il est possible que l'empreinte du certificat dans l'adresse du serveur soit incorrecte</target>
@@ -5229,10 +5154,6 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
<target>Serveurs routés via des proxy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Notifications push</target>
@@ -5638,10 +5559,6 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
<target>Serveur SMP</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<target>Réception de fichiers en toute sécurité</target>
@@ -5752,10 +5669,6 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
<target>Message enregistré</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<target>Échelle</target>
@@ -5958,7 +5871,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>L'expéditeur a annulé le transfert de fichiers.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -7042,7 +6955,7 @@ Vous serez invité à confirmer l'authentification avant que cette fonction ne s
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<target>Serveurs inconnus!</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -7156,10 +7069,6 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
<target>Utiliser les hôtes .onions</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>Utiliser les serveurs SimpleX Chat?</target>
@@ -7235,10 +7144,6 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
<target>Sélection de l'utilisateur</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>Vous utilisez les serveurs SimpleX.</target>
@@ -7472,7 +7377,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<target>Sans Tor ni VPN, votre adresse IP sera visible par ces relais XFTP: %@.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7881,10 +7786,6 @@ Répéter la demande de connexion ?</target>
<target>Vos contacts resteront connectés.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Votre base de données de chat actuelle va être SUPPRIMEE et REMPLACEE par celle importée.</target>
File diff suppressed because it is too large Load Diff
@@ -139,7 +139,6 @@
</trans-unit>
<trans-unit id="%@, %@" xml:space="preserve">
<source>%1$@, %2$@</source>
<target>%1$@, %2$@</target>
<note>format for date separator in chat</note>
</trans-unit>
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
@@ -162,31 +161,11 @@
<target>%d giorni</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d ore</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d min</target>
@@ -1047,7 +1026,6 @@
</trans-unit>
<trans-unit id="Auto-accept settings" xml:space="preserve">
<source>Auto-accept settings</source>
<target>Accetta automaticamente le impostazioni</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="Back" xml:space="preserve">
@@ -1243,7 +1221,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Impossibile ricevere il file</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -1373,7 +1351,6 @@
</trans-unit>
<trans-unit id="Chat preferences were changed." xml:space="preserve">
<source>Chat preferences were changed.</source>
<target>Le preferenze della chat sono state cambiate.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Chat theme" xml:space="preserve">
@@ -1777,7 +1754,6 @@ Questo è il tuo link una tantum!</target>
</trans-unit>
<trans-unit id="Corner" xml:space="preserve">
<source>Corner</source>
<target>Angolo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Correct name to %@?" xml:space="preserve">
@@ -2449,10 +2425,6 @@ Questo è il tuo link una tantum!</target>
<target>Non inviare la cronologia ai nuovi membri.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Non creare un indirizzo</target>
@@ -2476,8 +2448,7 @@ Questo è il tuo link una tantum!</target>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>Scarica</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2494,10 +2465,6 @@ Questo è il tuo link una tantum!</target>
<target>Scarica file</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<target>Scaricato</target>
@@ -2775,7 +2742,6 @@ Questo è il tuo link una tantum!</target>
</trans-unit>
<trans-unit id="Error changing connection profile" xml:space="preserve">
<source>Error changing connection profile</source>
<target>Errore nel cambio di profilo di connessione</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error changing role" xml:space="preserve">
@@ -2790,7 +2756,6 @@ Questo è il tuo link una tantum!</target>
</trans-unit>
<trans-unit id="Error changing to incognito!" xml:space="preserve">
<source>Error changing to incognito!</source>
<target>Errore nel passaggio a incognito!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
@@ -2915,7 +2880,6 @@ Questo è il tuo link una tantum!</target>
</trans-unit>
<trans-unit id="Error migrating settings" xml:space="preserve">
<source>Error migrating settings</source>
<target>Errore nella migrazione delle impostazioni</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error opening chat" xml:space="preserve">
@@ -2926,7 +2890,7 @@ Questo è il tuo link una tantum!</target>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Errore nella ricezione del file</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3020,7 +2984,6 @@ Questo è il tuo link una tantum!</target>
</trans-unit>
<trans-unit id="Error switching profile" xml:space="preserve">
<source>Error switching profile</source>
<target>Errore nel cambio di profilo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error switching profile!" xml:space="preserve">
@@ -3159,11 +3122,6 @@ Questo è il tuo link una tantum!</target>
<target>Errore del file</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<target>File non trovato - probabilmente è stato eliminato o annullato.</target>
@@ -3299,23 +3257,11 @@ Questo è il tuo link una tantum!</target>
<target>Inoltra</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>Inoltra e salva i messaggi</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>Inoltrato</target>
@@ -3326,10 +3272,6 @@ Questo è il tuo link una tantum!</target>
<target>Inoltrato da</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>Il server di inoltro %@ non è riuscito a connettersi al server di destinazione %@. Riprova più tardi.</target>
@@ -3624,10 +3566,6 @@ Errore: %2$@</target>
<target>Server ICE (uno per riga)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Se non potete incontrarvi di persona, mostra il codice QR in una videochiamata o condividi il link.</target>
@@ -4275,7 +4213,6 @@ Questo è il tuo link per il gruppo %@!</target>
</trans-unit>
<trans-unit id="Message shape" xml:space="preserve">
<source>Message shape</source>
<target>Forma del messaggio</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Message source remains private." xml:space="preserve">
@@ -4328,10 +4265,6 @@ Questo è il tuo link per il gruppo %@!</target>
<target>Messaggi inviati</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>I messaggi, i file e le chiamate sono protetti da **crittografia end-to-end** con perfect forward secrecy, ripudio e recupero da intrusione.</target>
@@ -4627,10 +4560,6 @@ Questo è il tuo link per il gruppo %@!</target>
<target>Nessuna selezione</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Notifiche</target>
@@ -4663,7 +4592,7 @@ Questo è il tuo link per il gruppo %@!</target>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Ok</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4854,11 +4783,6 @@ Richiede l'attivazione della VPN.</target>
<target>Altri %@ server</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>Conteggio PING</target>
@@ -4894,10 +4818,6 @@ Richiede l'attivazione della VPN.</target>
<target>Codice di accesso impostato!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Password per mostrare</target>
@@ -5047,10 +4967,6 @@ Errore: %@</target>
<target>Interfaccia polacca</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Probabilmente l'impronta del certificato nell'indirizzo del server è sbagliata</target>
@@ -5238,10 +5154,6 @@ Attivalo nelle impostazioni *Rete e server*.</target>
<target>Server via proxy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Notifiche push</target>
@@ -5465,7 +5377,6 @@ Attivalo nelle impostazioni *Rete e server*.</target>
</trans-unit>
<trans-unit id="Remove archive?" xml:space="preserve">
<source>Remove archive?</source>
<target>Rimuovere l'archivio?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Remove image" xml:space="preserve">
@@ -5648,10 +5559,6 @@ Attivalo nelle impostazioni *Rete e server*.</target>
<target>Server SMP</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<target>Ricevi i file in sicurezza</target>
@@ -5740,7 +5647,6 @@ Attivalo nelle impostazioni *Rete e server*.</target>
</trans-unit>
<trans-unit id="Save your profile?" xml:space="preserve">
<source>Save your profile?</source>
<target>Salvare il profilo?</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="Saved" xml:space="preserve">
@@ -5763,10 +5669,6 @@ Attivalo nelle impostazioni *Rete e server*.</target>
<target>Messaggio salvato</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<target>Scala</target>
@@ -5849,7 +5751,6 @@ Attivalo nelle impostazioni *Rete e server*.</target>
</trans-unit>
<trans-unit id="Select chat profile" xml:space="preserve">
<source>Select chat profile</source>
<target>Seleziona il profilo di chat</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Selected %lld" xml:space="preserve">
@@ -5970,7 +5871,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>Il mittente ha annullato il trasferimento del file.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -6189,7 +6090,6 @@ Attivalo nelle impostazioni *Rete e server*.</target>
</trans-unit>
<trans-unit id="Settings were changed." xml:space="preserve">
<source>Settings were changed.</source>
<target>Le impostazioni sono state cambiate.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Shape profile images" xml:space="preserve">
@@ -6229,7 +6129,6 @@ Attivalo nelle impostazioni *Rete e server*.</target>
</trans-unit>
<trans-unit id="Share profile" xml:space="preserve">
<source>Share profile</source>
<target>Condividi il profilo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
@@ -6399,7 +6298,6 @@ Attivalo nelle impostazioni *Rete e server*.</target>
</trans-unit>
<trans-unit id="Some app settings were not migrated." xml:space="preserve">
<source>Some app settings were not migrated.</source>
<target>Alcune impostazioni dell'app non sono state migrate.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Some file(s) were not exported:" xml:space="preserve">
@@ -6579,7 +6477,6 @@ Attivalo nelle impostazioni *Rete e server*.</target>
</trans-unit>
<trans-unit id="Tail" xml:space="preserve">
<source>Tail</source>
<target>Coda</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Take picture" xml:space="preserve">
@@ -6776,7 +6673,6 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.</ta
</trans-unit>
<trans-unit id="The uploaded database archive will be permanently removed from the servers." xml:space="preserve">
<source>The uploaded database archive will be permanently removed from the servers.</source>
<target>L'archivio del database caricato verrà rimosso definitivamente dai server.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Themes" xml:space="preserve">
@@ -7059,7 +6955,7 @@ Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzio
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<target>Server sconosciuti!</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -7173,10 +7069,6 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
<target>Usa gli host .onion</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>Usare i server di SimpleX Chat?</target>
@@ -7252,10 +7144,6 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
<target>Selezione utente</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>Utilizzo dei server SimpleX Chat.</target>
@@ -7489,7 +7377,7 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<target>Senza Tor o VPN, il tuo indirizzo IP sarà visibile a questi relay XFTP: %@.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7872,7 +7760,6 @@ Ripetere la richiesta di connessione?</target>
</trans-unit>
<trans-unit id="Your chat preferences" xml:space="preserve">
<source>Your chat preferences</source>
<target>Le tue preferenze della chat</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="Your chat profiles" xml:space="preserve">
@@ -7882,7 +7769,6 @@ Ripetere la richiesta di connessione?</target>
</trans-unit>
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
<target>La tua connessione è stata spostata a %@, ma si è verificato un errore imprevisto durante il reindirizzamento al profilo.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
@@ -7900,10 +7786,6 @@ Ripetere la richiesta di connessione?</target>
<target>I tuoi contatti resteranno connessi.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Il tuo attuale database della chat verrà ELIMINATO e SOSTITUITO con quello importato.</target>
@@ -7941,7 +7823,6 @@ Ripetere la richiesta di connessione?</target>
</trans-unit>
<trans-unit id="Your profile was changed. If you save it, the updated profile will be sent to all your contacts." xml:space="preserve">
<source>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</source>
<target>Il tuo profilo è stato cambiato. Se lo salvi, il profilo aggiornato verrà inviato a tutti i tuoi contatti.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
@@ -161,31 +161,11 @@
<target>%d 日</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d 時</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d 分</target>
@@ -1190,7 +1170,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>ファイル受信ができません</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2308,10 +2288,6 @@ This is your own one-time link!</source>
<source>Do not send history to new members.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>アドレスを作成しないでください</target>
@@ -2334,8 +2310,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2350,10 +2325,6 @@ This is your own one-time link!</source>
<target>ファイルをダウンロード</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<note>No comment provided by engineer.</note>
@@ -2758,7 +2729,7 @@ This is your own one-time link!</source>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>ファイル受信にエラー発生</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -2976,11 +2947,6 @@ This is your own one-time link!</source>
<source>File error</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<note>file error text</note>
@@ -3107,22 +3073,10 @@ This is your own one-time link!</source>
<source>Forward</source>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<note>No comment provided by engineer.</note>
@@ -3131,10 +3085,6 @@ This is your own one-time link!</source>
<source>Forwarded from</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>
<note>No comment provided by engineer.</note>
@@ -3413,10 +3363,6 @@ Error: %2$@</source>
<target>ICEサーバ (1行に1サーバ)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>直接会えない場合は、ビデオ通話で QR コードを表示するか、リンクを共有してください。</target>
@@ -4070,10 +4016,6 @@ This is your link for group %@!</source>
<source>Messages sent</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<note>No comment provided by engineer.</note>
@@ -4348,10 +4290,6 @@ This is your link for group %@!</source>
<source>Nothing selected</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>通知</target>
@@ -4383,7 +4321,7 @@ This is your link for group %@!</source>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>OK</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4563,11 +4501,6 @@ VPN を有効にする必要があります。</target>
<source>Other %@ servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>PING回数</target>
@@ -4603,10 +4536,6 @@ VPN を有効にする必要があります。</target>
<target>パスコードを設定しました!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>パスワードを表示する</target>
@@ -4743,10 +4672,6 @@ Error: %@</source>
<target>ポーランド語UI</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>サーバアドレスの証明証IDが正しくないかもしれません</target>
@@ -4920,10 +4845,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>Proxied servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>プッシュ通知</target>
@@ -5300,10 +5221,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>SMP server</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<note>No comment provided by engineer.</note>
@@ -5408,10 +5325,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>Saved message</source>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<note>No comment provided by engineer.</note>
@@ -5598,7 +5511,7 @@ Enable in *Network &amp; servers* settings.</source>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>送信者がファイル転送をキャンセルしました。</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -6601,7 +6514,7 @@ You will be prompted to complete authentication before this feature is enabled.<
</trans-unit>
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -6706,10 +6619,6 @@ To connect, please ask your contact to create another connection link and check
<target>.onionホストを使う</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>SimpleX チャット サーバーを使用しますか?</target>
@@ -6778,10 +6687,6 @@ To connect, please ask your contact to create another connection link and check
<source>User selection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>SimpleX チャット サーバーを使用する。</target>
@@ -6994,7 +6899,7 @@ To connect, please ask your contact to create another connection link and check
</trans-unit>
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7376,10 +7281,6 @@ Repeat connection request?</source>
<target>連絡先は接続されたままになります。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>現在のチャット データベースは削除され、インポートされたデータベースに置き換えられます。</target>
@@ -139,7 +139,6 @@
</trans-unit>
<trans-unit id="%@, %@" xml:space="preserve">
<source>%1$@, %2$@</source>
<target>%1$@, %2$@</target>
<note>format for date separator in chat</note>
</trans-unit>
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
@@ -162,31 +161,11 @@
<target>%d dagen</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d uren</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d min</target>
@@ -537,7 +516,7 @@
</trans-unit>
<trans-unit id="A separate TCP connection will be used **for each chat profile you have in the app**." xml:space="preserve">
<source>A separate TCP connection will be used **for each chat profile you have in the app**.</source>
<target>Er wordt een aparte TCP-verbinding gebruikt **voor elk chatprofiel dat je in de app hebt**.</target>
<target>Er wordt een aparte TCP-verbinding gebruikt **voor elk chat profiel dat je in de app hebt**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="A separate TCP connection will be used **for each contact and group member**.&#10;**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail." xml:space="preserve">
@@ -1047,7 +1026,6 @@
</trans-unit>
<trans-unit id="Auto-accept settings" xml:space="preserve">
<source>Auto-accept settings</source>
<target>Instellingen automatisch accepteren</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="Back" xml:space="preserve">
@@ -1172,7 +1150,7 @@
</trans-unit>
<trans-unit id="By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)." xml:space="preserve">
<source>By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).</source>
<target>Via chatprofiel (standaard) of [via verbinding](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).</target>
<target>Via chat profiel (standaard) of [via verbinding](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Call already ended!" xml:space="preserve">
@@ -1243,7 +1221,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Kan bestand niet ontvangen</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -1373,7 +1351,6 @@
</trans-unit>
<trans-unit id="Chat preferences were changed." xml:space="preserve">
<source>Chat preferences were changed.</source>
<target>Chatvoorkeuren zijn gewijzigd.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Chat theme" xml:space="preserve">
@@ -1383,7 +1360,7 @@
</trans-unit>
<trans-unit id="Chats" xml:space="preserve">
<source>Chats</source>
<target>Chats</target>
<target>Gesprekken</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Check server address and try again." xml:space="preserve">
@@ -1777,7 +1754,6 @@ Dit is uw eigen eenmalige link!</target>
</trans-unit>
<trans-unit id="Corner" xml:space="preserve">
<source>Corner</source>
<target>Hoek</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Correct name to %@?" xml:space="preserve">
@@ -1991,7 +1967,7 @@ Dit is uw eigen eenmalige link!</target>
</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>Database wachtwoord is vereist om je chats te openen.</target>
<target>Database wachtwoord is vereist om je gesprekken te openen.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Database upgrade" xml:space="preserve">
@@ -2086,12 +2062,12 @@ Dit is uw eigen eenmalige link!</target>
</trans-unit>
<trans-unit id="Delete chat profile" xml:space="preserve">
<source>Delete chat profile</source>
<target>Chatprofiel verwijderen</target>
<target>Chat profiel verwijderen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete chat profile?" xml:space="preserve">
<source>Delete chat profile?</source>
<target>Chatprofiel verwijderen?</target>
<target>Chat profiel verwijderen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete connection" xml:space="preserve">
@@ -2131,7 +2107,7 @@ Dit is uw eigen eenmalige link!</target>
</trans-unit>
<trans-unit id="Delete files for all chat profiles" xml:space="preserve">
<source>Delete files for all chat profiles</source>
<target>Verwijder bestanden voor alle chatprofielen</target>
<target>Verwijder bestanden voor alle chat profielen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete for everyone" xml:space="preserve">
@@ -2449,10 +2425,6 @@ Dit is uw eigen eenmalige link!</target>
<target>Stuur geen geschiedenis naar nieuwe leden.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Maak geen adres aan</target>
@@ -2476,8 +2448,7 @@ Dit is uw eigen eenmalige link!</target>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>Downloaden</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2494,10 +2465,6 @@ Dit is uw eigen eenmalige link!</target>
<target>Download bestand</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<target>Gedownload</target>
@@ -2775,7 +2742,6 @@ Dit is uw eigen eenmalige link!</target>
</trans-unit>
<trans-unit id="Error changing connection profile" xml:space="preserve">
<source>Error changing connection profile</source>
<target>Fout bij wijzigen van verbindingsprofiel</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error changing role" xml:space="preserve">
@@ -2790,7 +2756,6 @@ Dit is uw eigen eenmalige link!</target>
</trans-unit>
<trans-unit id="Error changing to incognito!" xml:space="preserve">
<source>Error changing to incognito!</source>
<target>Fout bij het overschakelen naar incognito!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
@@ -2915,7 +2880,6 @@ Dit is uw eigen eenmalige link!</target>
</trans-unit>
<trans-unit id="Error migrating settings" xml:space="preserve">
<source>Error migrating settings</source>
<target>Fout bij migreren van instellingen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error opening chat" xml:space="preserve">
@@ -2926,7 +2890,7 @@ Dit is uw eigen eenmalige link!</target>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Fout bij ontvangen van bestand</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3020,7 +2984,6 @@ Dit is uw eigen eenmalige link!</target>
</trans-unit>
<trans-unit id="Error switching profile" xml:space="preserve">
<source>Error switching profile</source>
<target>Fout bij wisselen van profiel</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error switching profile!" xml:space="preserve">
@@ -3159,11 +3122,6 @@ Dit is uw eigen eenmalige link!</target>
<target>Bestandsfout</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<target>Bestand niet gevonden - hoogstwaarschijnlijk is het bestand verwijderd of geannuleerd.</target>
@@ -3256,7 +3214,7 @@ Dit is uw eigen eenmalige link!</target>
</trans-unit>
<trans-unit id="Find chats faster" xml:space="preserve">
<source>Find chats faster</source>
<target>Vind chats sneller</target>
<target>Vind gesprekken sneller</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Fix" xml:space="preserve">
@@ -3299,23 +3257,11 @@ Dit is uw eigen eenmalige link!</target>
<target>Doorsturen</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>Berichten doorsturen en opslaan</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>Doorgestuurd</target>
@@ -3326,10 +3272,6 @@ Dit is uw eigen eenmalige link!</target>
<target>Doorgestuurd vanuit</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>De doorstuurserver %@ kon geen verbinding maken met de bestemmingsserver %@. Probeer het later opnieuw.</target>
@@ -3551,7 +3493,7 @@ Fout: %2$@</target>
</trans-unit>
<trans-unit id="Hidden chat profiles" xml:space="preserve">
<source>Hidden chat profiles</source>
<target>Verborgen chatprofielen</target>
<target>Verborgen chat profielen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Hidden profile password" xml:space="preserve">
@@ -3624,10 +3566,6 @@ Fout: %2$@</target>
<target>ICE servers (één per lijn)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Als je elkaar niet persoonlijk kunt ontmoeten, laat dan de QR-code zien in een videogesprek of deel de link.</target>
@@ -3907,7 +3845,7 @@ Fout: %2$@</target>
</trans-unit>
<trans-unit id="It allows having many anonymous connections without any shared data between them in a single chat profile." xml:space="preserve">
<source>It allows having many anonymous connections without any shared data between them in a single chat profile.</source>
<target>Het maakt het mogelijk om veel anonieme verbindingen te hebben zonder enige gedeelde gegevens tussen hen in een enkel chatprofiel.</target>
<target>Het maakt het mogelijk om veel anonieme verbindingen te hebben zonder enige gedeelde gegevens tussen hen in een enkel chat profiel.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="It can happen when you or your connection used the old database backup." xml:space="preserve">
@@ -4275,7 +4213,6 @@ Dit is jouw link voor groep %@!</target>
</trans-unit>
<trans-unit id="Message shape" xml:space="preserve">
<source>Message shape</source>
<target>Berichtvorm</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Message source remains private." xml:space="preserve">
@@ -4328,10 +4265,6 @@ Dit is jouw link voor groep %@!</target>
<target>Berichten verzonden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>Berichten, bestanden en oproepen worden beschermd door **end-to-end codering** met perfecte voorwaartse geheimhouding, afwijzing en inbraakherstel.</target>
@@ -4434,7 +4367,7 @@ Dit is jouw link voor groep %@!</target>
</trans-unit>
<trans-unit id="Multiple chat profiles" xml:space="preserve">
<source>Multiple chat profiles</source>
<target>Meerdere chatprofielen</target>
<target>Meerdere chat profielen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Mute" xml:space="preserve">
@@ -4584,7 +4517,7 @@ Dit is jouw link voor groep %@!</target>
</trans-unit>
<trans-unit id="No filtered chats" xml:space="preserve">
<source>No filtered chats</source>
<target>Geen gefilterde chats</target>
<target>Geen gefilterde gesprekken</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="No group!" xml:space="preserve">
@@ -4627,10 +4560,6 @@ Dit is jouw link voor groep %@!</target>
<target>Niets geselecteerd</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Meldingen</target>
@@ -4663,7 +4592,7 @@ Dit is jouw link voor groep %@!</target>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>OK</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4854,11 +4783,6 @@ Vereist het inschakelen van VPN.</target>
<target>Andere %@ servers</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>PING count</target>
@@ -4894,10 +4818,6 @@ Vereist het inschakelen van VPN.</target>
<target>Toegangscode ingesteld!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Wachtwoord om weer te geven</target>
@@ -4955,7 +4875,7 @@ Vereist het inschakelen van VPN.</target>
</trans-unit>
<trans-unit id="Play from the chat list." xml:space="preserve">
<source>Play from the chat list.</source>
<target>Afspelen via de chat lijst.</target>
<target>Afspelen via de gesprekken lijst.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
@@ -5034,7 +4954,7 @@ Fout: %@</target>
</trans-unit>
<trans-unit id="Please store passphrase securely, you will NOT be able to access chat if you lose it." xml:space="preserve">
<source>Please store passphrase securely, you will NOT be able to access chat if you lose it.</source>
<target>Sla het wachtwoord veilig op. Als u deze kwijtraakt, heeft u GEEN toegang tot de chats.</target>
<target>Sla het wachtwoord veilig op. Als u deze kwijtraakt, heeft u GEEN toegang tot de gesprekken.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Please store passphrase securely, you will NOT be able to change it if you lose it." xml:space="preserve">
@@ -5047,10 +4967,6 @@ Fout: %@</target>
<target>Poolse interface</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Mogelijk is de certificaat vingerafdruk in het server adres onjuist</target>
@@ -5215,7 +5131,7 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="Protect your chat profiles with a password!" xml:space="preserve">
<source>Protect your chat profiles with a password!</source>
<target>Bescherm je chatprofielen met een wachtwoord!</target>
<target>Bescherm je chat profielen met een wachtwoord!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Protocol timeout" xml:space="preserve">
@@ -5238,10 +5154,6 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
<target>Proxied servers</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Push meldingen</target>
@@ -5465,7 +5377,6 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="Remove archive?" xml:space="preserve">
<source>Remove archive?</source>
<target>Archief verwijderen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Remove image" xml:space="preserve">
@@ -5580,7 +5491,7 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="Restart the app to create a new chat profile" xml:space="preserve">
<source>Restart the app to create a new chat profile</source>
<target>Start de app opnieuw om een nieuw chatprofiel aan te maken</target>
<target>Start de app opnieuw om een nieuw chat profiel aan te maken</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Restart the app to use imported chat database" xml:space="preserve">
@@ -5648,10 +5559,6 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
<target>SMP server</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<target>Veilig bestanden ontvangen</target>
@@ -5705,7 +5612,7 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="Save passphrase and open chat" xml:space="preserve">
<source>Save passphrase and open chat</source>
<target>Bewaar het wachtwoord en open je chats</target>
<target>Bewaar het wachtwoord en open je gesprekken</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Save passphrase in Keychain" xml:space="preserve">
@@ -5725,7 +5632,7 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="Save servers" xml:space="preserve">
<source>Save servers</source>
<target>Servers opslaan</target>
<target>Bewaar servers</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Save servers?" xml:space="preserve">
@@ -5740,7 +5647,6 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="Save your profile?" xml:space="preserve">
<source>Save your profile?</source>
<target>Uw profiel opslaan?</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="Saved" xml:space="preserve">
@@ -5763,10 +5669,6 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
<target>Opgeslagen bericht</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<target>Schaal</target>
@@ -5849,7 +5751,6 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="Select chat profile" xml:space="preserve">
<source>Select chat profile</source>
<target>Selecteer chatprofiel</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Selected %lld" xml:space="preserve">
@@ -5970,7 +5871,7 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>Afzender heeft bestandsoverdracht geannuleerd.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -6189,7 +6090,6 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="Settings were changed." xml:space="preserve">
<source>Settings were changed.</source>
<target>Instellingen zijn gewijzigd.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Shape profile images" xml:space="preserve">
@@ -6229,7 +6129,6 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="Share profile" xml:space="preserve">
<source>Share profile</source>
<target>Profiel delen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
@@ -6399,7 +6298,6 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="Some app settings were not migrated." xml:space="preserve">
<source>Some app settings were not migrated.</source>
<target>Sommige app-instellingen zijn niet gemigreerd.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Some file(s) were not exported:" xml:space="preserve">
@@ -6765,7 +6663,7 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast.</target>
</trans-unit>
<trans-unit id="The servers for new connections of your current chat profile **%@**." xml:space="preserve">
<source>The servers for new connections of your current chat profile **%@**.</source>
<target>De servers voor nieuwe verbindingen van uw huidige chatprofiel **%@**.</target>
<target>De servers voor nieuwe verbindingen van uw huidige chat profiel **%@**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The text you pasted is not a SimpleX link." xml:space="preserve">
@@ -6775,7 +6673,6 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast.</target>
</trans-unit>
<trans-unit id="The uploaded database archive will be permanently removed from the servers." xml:space="preserve">
<source>The uploaded database archive will be permanently removed from the servers.</source>
<target>Het geüploade databasearchief wordt permanent van de servers verwijderd.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Themes" xml:space="preserve">
@@ -6855,7 +6752,7 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast.</target>
</trans-unit>
<trans-unit id="This setting applies to messages in your current chat profile **%@**." xml:space="preserve">
<source>This setting applies to messages in your current chat profile **%@**.</source>
<target>Deze instelling is van toepassing op berichten in je huidige chatprofiel **%@**.</target>
<target>Deze instelling is van toepassing op berichten in je huidige chat profiel **%@**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Title" xml:space="preserve">
@@ -6912,7 +6809,7 @@ U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingesc
</trans-unit>
<trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve">
<source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source>
<target>Om uw verborgen profiel te onthullen, voert u een volledig wachtwoord in een zoek veld in op de pagina **Uw chatprofielen**.</target>
<target>Om uw verborgen profiel te onthullen, voert u een volledig wachtwoord in een zoek veld in op de pagina **Uw chat profielen**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve">
@@ -7027,7 +6924,7 @@ U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingesc
</trans-unit>
<trans-unit id="Unhide chat profile" xml:space="preserve">
<source>Unhide chat profile</source>
<target>Chatprofiel zichtbaar maken</target>
<target>Chat profiel zichtbaar maken</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unhide profile" xml:space="preserve">
@@ -7058,7 +6955,7 @@ U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingesc
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<target>Onbekende servers!</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -7172,10 +7069,6 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
<target>Gebruik .onion-hosts</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>SimpleX Chat servers gebruiken?</target>
@@ -7251,10 +7144,6 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
<target>Gebruikersselectie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>SimpleX Chat servers gebruiken.</target>
@@ -7488,7 +7377,7 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<target>Zonder Tor of VPN zal uw IP-adres zichtbaar zijn voor deze XFTP-relays: %@.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7537,7 +7426,7 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
</trans-unit>
<trans-unit id="You already have a chat profile with the same display name. Please choose another name." xml:space="preserve">
<source>You already have a chat profile with the same display name. Please choose another name.</source>
<target>Je hebt al een chatprofiel met dezelfde weergave naam. Kies een andere naam.</target>
<target>Je hebt al een chat profiel met dezelfde weergave naam. Kies een andere naam.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already connected to %@." xml:space="preserve">
@@ -7871,7 +7760,6 @@ Verbindingsverzoek herhalen?</target>
</trans-unit>
<trans-unit id="Your chat preferences" xml:space="preserve">
<source>Your chat preferences</source>
<target>Uw chat voorkeuren</target>
<note>alert title</note>
</trans-unit>
<trans-unit id="Your chat profiles" xml:space="preserve">
@@ -7881,7 +7769,6 @@ Verbindingsverzoek herhalen?</target>
</trans-unit>
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
<target>Uw verbinding is verplaatst naar %@, maar er is een onverwachte fout opgetreden tijdens het omleiden naar het profiel.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
@@ -7899,10 +7786,6 @@ Verbindingsverzoek herhalen?</target>
<target>Uw contacten blijven verbonden.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Uw huidige chat database wordt VERWIJDERD en VERVANGEN door de geïmporteerde.</target>
@@ -7940,7 +7823,6 @@ Verbindingsverzoek herhalen?</target>
</trans-unit>
<trans-unit id="Your profile was changed. If you save it, the updated profile will be sent to all your contacts." xml:space="preserve">
<source>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</source>
<target>Je profiel is gewijzigd. Als je het opslaat, wordt het bijgewerkte profiel naar al je contacten verzonden.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
@@ -9089,7 +8971,7 @@ laatst ontvangen bericht: %2$@</target>
</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>Database wachtwoord is vereist om je chats te openen.</target>
<target>Database wachtwoord is vereist om je gesprekken te openen.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Database upgrade required" xml:space="preserve">
@@ -161,31 +161,11 @@
<target>%d dni</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d godzin</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d min</target>
@@ -1241,7 +1221,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Nie można odebrać pliku</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2445,10 +2425,6 @@ To jest twój jednorazowy link!</target>
<target>Nie wysyłaj historii do nowych członków.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Nie twórz adresu</target>
@@ -2472,8 +2448,7 @@ To jest twój jednorazowy link!</target>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>Pobierz</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2490,10 +2465,6 @@ To jest twój jednorazowy link!</target>
<target>Pobierz plik</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<target>Pobrane</target>
@@ -2919,7 +2890,7 @@ To jest twój jednorazowy link!</target>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Błąd odbioru pliku</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3151,11 +3122,6 @@ To jest twój jednorazowy link!</target>
<target>Błąd pliku</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<target>Nie odnaleziono pliku - najprawdopodobniej plik został usunięty lub anulowany.</target>
@@ -3291,23 +3257,11 @@ To jest twój jednorazowy link!</target>
<target>Przekaż dalej</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>Przesyłaj dalej i zapisuj wiadomości</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>Przekazane dalej</target>
@@ -3318,10 +3272,6 @@ To jest twój jednorazowy link!</target>
<target>Przekazane dalej od</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>
@@ -3616,10 +3566,6 @@ Błąd: %2$@</target>
<target>Serwery ICE (po jednym na linię)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Jeśli nie możesz spotkać się osobiście, pokaż kod QR w rozmowie wideo lub udostępnij link.</target>
@@ -4319,10 +4265,6 @@ To jest twój link do grupy %@!</target>
<target>Wysłane wiadomości</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>Wiadomości, pliki i połączenia są chronione przez **szyfrowanie end-to-end** z doskonałym utajnianiem z wyprzedzeniem i odzyskiem po złamaniu.</target>
@@ -4618,10 +4560,6 @@ To jest twój link do grupy %@!</target>
<target>Nic nie jest zaznaczone</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Powiadomienia</target>
@@ -4654,7 +4592,7 @@ To jest twój link do grupy %@!</target>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Ok</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4845,11 +4783,6 @@ Wymaga włączenia VPN.</target>
<target>Inne %@ serwery</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>Liczba PINGÓW</target>
@@ -4885,10 +4818,6 @@ Wymaga włączenia VPN.</target>
<target>Pin ustawiony!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Hasło do wyświetlenia</target>
@@ -5038,10 +4967,6 @@ Błąd: %@</target>
<target>Polski interfejs</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Możliwe, że odcisk palca certyfikatu w adresie serwera jest nieprawidłowy</target>
@@ -5229,10 +5154,6 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
<target>Serwery trasowane przez proxy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Powiadomienia push</target>
@@ -5638,10 +5559,6 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
<target>Serwer SMP</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<target>Bezpiecznie otrzymuj pliki</target>
@@ -5752,10 +5669,6 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
<target>Zachowano wiadomość</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<target>Skaluj</target>
@@ -5958,7 +5871,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>Nadawca anulował transfer pliku.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -7042,7 +6955,7 @@ Przed włączeniem tej funkcji zostanie wyświetlony monit uwierzytelniania.</ta
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<target>Nieznane serwery!</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -7156,10 +7069,6 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
<target>Użyj hostów .onion</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>Użyć serwerów SimpleX Chat?</target>
@@ -7235,10 +7144,6 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
<target>Wybór użytkownika</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>Używanie serwerów SimpleX Chat.</target>
@@ -7472,7 +7377,7 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<target>Bez Tor lub VPN, Twój adres IP będzie widoczny dla tych przekaźników XFTP: %@.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7881,10 +7786,6 @@ Powtórzyć prośbę połączenia?</target>
<target>Twoje kontakty pozostaną połączone.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Twoja obecna baza danych czatu zostanie usunięta i zastąpiona zaimportowaną.</target>
@@ -161,31 +161,11 @@
<target>%d дней</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d ч.</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d мин</target>
@@ -1241,7 +1221,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Невозможно получить файл</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2445,10 +2425,6 @@ This is your own one-time link!</source>
<target>Не отправлять историю новым членам.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Не создавать адрес</target>
@@ -2472,8 +2448,7 @@ This is your own one-time link!</source>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>Загрузить</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2490,10 +2465,6 @@ This is your own one-time link!</source>
<target>Загрузка файла</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<target>Принято</target>
@@ -2919,7 +2890,7 @@ This is your own one-time link!</source>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Ошибка при получении файла</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3151,11 +3122,6 @@ This is your own one-time link!</source>
<target>Ошибка файла</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<target>Файл не найден - скорее всего, файл был удален или отменен.</target>
@@ -3291,23 +3257,11 @@ This is your own one-time link!</source>
<target>Переслать</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>Переслать и сохранить сообщение</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>Переслано</target>
@@ -3318,10 +3272,6 @@ This is your own one-time link!</source>
<target>Переслано из</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>Пересылающий сервер %@ не смог подключиться к серверу назначения %@. Попробуйте позже.</target>
@@ -3616,10 +3566,6 @@ Error: %2$@</source>
<target>ICE серверы (один на строке)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Если Вы не можете встретиться лично, покажите QR-код во время видеозвонка или поделитесь ссылкой.</target>
@@ -4319,10 +4265,6 @@ This is your link for group %@!</source>
<target>Сообщений отправлено</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>Сообщения, файлы и звонки защищены **end-to-end шифрованием** с прямой секретностью (PFS), правдоподобным отрицанием и восстановлением от взлома.</target>
@@ -4618,10 +4560,6 @@ This is your link for group %@!</source>
<target>Ничего не выбрано</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Уведомления</target>
@@ -4654,7 +4592,7 @@ This is your link for group %@!</source>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Ок</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4845,11 +4783,6 @@ Requires compatible VPN.</source>
<target>Другие %@ серверы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>Количество PING</target>
@@ -4885,10 +4818,6 @@ Requires compatible VPN.</source>
<target>Код доступа установлен!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Пароль чтобы раскрыть</target>
@@ -5038,10 +4967,6 @@ Error: %@</source>
<target>Польский интерфейс</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Возможно, хэш сертификата в адресе сервера неверный</target>
@@ -5229,10 +5154,6 @@ Enable in *Network &amp; servers* settings.</source>
<target>Проксированные серверы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Доставка уведомлений</target>
@@ -5638,10 +5559,6 @@ Enable in *Network &amp; servers* settings.</source>
<target>SMP сервер</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<target>Получайте файлы безопасно</target>
@@ -5752,10 +5669,6 @@ Enable in *Network &amp; servers* settings.</source>
<target>Сохраненное сообщение</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<target>Масштаб</target>
@@ -5958,7 +5871,7 @@ Enable in *Network &amp; servers* settings.</source>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>Отправитель отменил передачу файла.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -7042,7 +6955,7 @@ You will be prompted to complete authentication before this feature is enabled.<
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<target>Неизвестные серверы!</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -7156,10 +7069,6 @@ To connect, please ask your contact to create another connection link and check
<target>Использовать .onion хосты</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>Использовать серверы предосталенные SimpleX Chat?</target>
@@ -7235,10 +7144,6 @@ To connect, please ask your contact to create another connection link and check
<target>Выбор пользователя</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>Используются серверы, предоставленные SimpleX Chat.</target>
@@ -7472,7 +7377,7 @@ To connect, please ask your contact to create another connection link and check
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<target>Без Тора или ВПН, Ваш IP адрес будет доступен этим серверам файлов: %@.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7881,10 +7786,6 @@ Repeat connection request?</source>
<target>Ваши контакты сохранятся.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Текущие данные Вашего чата будет УДАЛЕНЫ и ЗАМЕНЕНЫ импортированными.</target>
@@ -151,31 +151,11 @@
<target>%d วัน</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d ชั่วโมง</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d นาที</target>
@@ -1158,7 +1138,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>ไม่สามารถรับไฟล์ได้</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2271,10 +2251,6 @@ This is your own one-time link!</source>
<source>Do not send history to new members.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>อย่าสร้างที่อยู่</target>
@@ -2297,8 +2273,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2313,10 +2288,6 @@ This is your own one-time link!</source>
<target>ดาวน์โหลดไฟล์</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<note>No comment provided by engineer.</note>
@@ -2718,7 +2689,7 @@ This is your own one-time link!</source>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>เกิดข้อผิดพลาดในการรับไฟล์</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -2936,11 +2907,6 @@ This is your own one-time link!</source>
<source>File error</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<note>file error text</note>
@@ -3067,22 +3033,10 @@ This is your own one-time link!</source>
<source>Forward</source>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<note>No comment provided by engineer.</note>
@@ -3091,10 +3045,6 @@ This is your own one-time link!</source>
<source>Forwarded from</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>
<note>No comment provided by engineer.</note>
@@ -3373,10 +3323,6 @@ Error: %2$@</source>
<target>เซิร์ฟเวอร์ ICE (หนึ่งเครื่องต่อสาย)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>หากคุณไม่สามารถพบกันในชีวิตจริงได้ ให้แสดงคิวอาร์โค้ดในวิดีโอคอล หรือแชร์ลิงก์</target>
@@ -4029,10 +3975,6 @@ This is your link for group %@!</source>
<source>Messages sent</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<note>No comment provided by engineer.</note>
@@ -4304,10 +4246,6 @@ This is your link for group %@!</source>
<source>Nothing selected</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>การแจ้งเตือน</target>
@@ -4339,7 +4277,7 @@ This is your link for group %@!</source>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>ตกลง</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4516,11 +4454,6 @@ Requires compatible VPN.</source>
<source>Other %@ servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>จํานวน PING</target>
@@ -4556,10 +4489,6 @@ Requires compatible VPN.</source>
<target>ตั้งรหัสผ่านเรียบร้อยแล้ว!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>รหัสผ่านที่จะแสดง</target>
@@ -4696,10 +4625,6 @@ Error: %@</source>
<target>อินเตอร์เฟซภาษาโปแลนด์</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>อาจเป็นไปได้ว่าลายนิ้วมือของ certificate ในที่อยู่เซิร์ฟเวอร์ไม่ถูกต้อง</target>
@@ -4873,10 +4798,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>Proxied servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>การแจ้งเตือนแบบทันที</target>
@@ -5252,10 +5173,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>SMP server</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<note>No comment provided by engineer.</note>
@@ -5360,10 +5277,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>Saved message</source>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<note>No comment provided by engineer.</note>
@@ -5551,7 +5464,7 @@ Enable in *Network &amp; servers* settings.</source>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>ผู้ส่งยกเลิกการโอนไฟล์</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -6555,7 +6468,7 @@ You will be prompted to complete authentication before this feature is enabled.<
</trans-unit>
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -6660,10 +6573,6 @@ To connect, please ask your contact to create another connection link and check
<target>ใช้โฮสต์ .onion</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>ใช้เซิร์ฟเวอร์ SimpleX Chat ไหม?</target>
@@ -6730,10 +6639,6 @@ To connect, please ask your contact to create another connection link and check
<source>User selection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>กำลังใช้เซิร์ฟเวอร์ SimpleX Chat อยู่</target>
@@ -6946,7 +6851,7 @@ To connect, please ask your contact to create another connection link and check
</trans-unit>
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7327,10 +7232,6 @@ Repeat connection request?</source>
<target>ผู้ติดต่อของคุณจะยังคงเชื่อมต่ออยู่</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>ฐานข้อมูลแชทปัจจุบันของคุณจะถูกลบและแทนที่ด้วยฐานข้อมูลที่นำเข้า</target>
@@ -161,31 +161,11 @@
<target>%d gün</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d saat</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d dakika</target>
@@ -1216,7 +1196,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Dosya alınamıyor</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2378,10 +2358,6 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
<target>Yeni üyelere geçmişi gönderme.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Adres oluşturma</target>
@@ -2405,8 +2381,7 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>İndir</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2422,10 +2397,6 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
<target>Dosya indir</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<note>No comment provided by engineer.</note>
@@ -2846,7 +2817,7 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Dosya alınırken sorun oluştu</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3072,11 +3043,6 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
<source>File error</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<note>file error text</note>
@@ -3208,23 +3174,11 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
<target>İlet</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>Mesajları ilet ve kaydet</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>İletildi</target>
@@ -3235,10 +3189,6 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
<target>Şuradan iletildi</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>
<note>No comment provided by engineer.</note>
@@ -3528,10 +3478,6 @@ Hata: %2$@</target>
<target>ICE sunucuları (her satıra bir tane)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Eğer onunla buluşamıyorsan görüntülü aramada QR kod göster veya bağlantığı paylaş.</target>
@@ -4215,10 +4161,6 @@ Bu senin grup için bağlantın %@!</target>
<source>Messages sent</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>Mesajlar, dosyalar ve aramalar **uçtan uca şifreleme** ile mükemmel ileri gizlilik, inkar ve izinsiz giriş kurtarma ile korunur.</target>
@@ -4509,10 +4451,6 @@ Bu senin grup için bağlantın %@!</target>
<source>Nothing selected</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Bildirimler</target>
@@ -4545,7 +4483,7 @@ Bu senin grup için bağlantın %@!</target>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Tamam</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4733,11 +4671,6 @@ VPN'nin etkinleştirilmesi gerekir.</target>
<source>Other %@ servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>PING sayısı</target>
@@ -4773,10 +4706,6 @@ VPN'nin etkinleştirilmesi gerekir.</target>
<target>Şifre ayarlandı!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Gösterilecek şifre</target>
@@ -4921,10 +4850,6 @@ Hata: %@</target>
<target>Lehçe arayüz</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Muhtemelen, sunucu adresindeki parmakizi sertifikası doğru değil</target>
@@ -5107,10 +5032,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>Proxied servers</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Anında bildirimler</target>
@@ -5499,10 +5420,6 @@ Enable in *Network &amp; servers* settings.</source>
<source>SMP server</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<target>Dosyaları güvenle alın</target>
@@ -5612,10 +5529,6 @@ Enable in *Network &amp; servers* settings.</source>
<target>Kaydedilmiş mesaj</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<note>No comment provided by engineer.</note>
@@ -5810,7 +5723,7 @@ Enable in *Network &amp; servers* settings.</source>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>Gönderici dosya gönderimini iptal etti.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -6857,7 +6770,7 @@ Bu özellik etkinleştirilmeden önce kimlik doğrulamayı tamamlamanız istenec
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<target>Bilinmeyen sunucular!</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -6967,10 +6880,6 @@ Bağlanmak için lütfen kişinizden başka bir bağlantı oluşturmasını iste
<target>.onion ana bilgisayarlarını kullan</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>SimpleX Chat sunucuları kullanılsın mı?</target>
@@ -7044,10 +6953,6 @@ Bağlanmak için lütfen kişinizden başka bir bağlantı oluşturmasını iste
<source>User selection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>SimpleX Chat sunucuları kullanılıyor.</target>
@@ -7279,7 +7184,7 @@ Bağlanmak için lütfen kişinizden başka bir bağlantı oluşturmasını iste
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<target>Tor veya VPN olmadan, IP adresiniz bu XFTP aktarıcıları tarafından görülebilir: %@.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7679,10 +7584,6 @@ Bağlantı isteği tekrarlansın mı?</target>
<target>Kişileriniz bağlı kalacaktır.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Mevcut sohbet veritabanınız SİLİNECEK ve içe aktarılan veritabanıyla DEĞİŞTİRİLECEKTİR.</target>
@@ -161,31 +161,11 @@
<target>%d днів</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d годин</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d хв</target>
@@ -1241,7 +1221,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>Не вдається отримати файл</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2445,10 +2425,6 @@ This is your own one-time link!</source>
<target>Не надсилайте історію новим користувачам.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>Не створювати адресу</target>
@@ -2472,8 +2448,7 @@ This is your own one-time link!</source>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>Завантажити</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2490,10 +2465,6 @@ This is your own one-time link!</source>
<target>Завантажити файл</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<target>Завантажено</target>
@@ -2919,7 +2890,7 @@ This is your own one-time link!</source>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>Помилка отримання файлу</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3151,11 +3122,6 @@ This is your own one-time link!</source>
<target>Помилка файлу</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<target>Файл не знайдено - найімовірніше, файл було видалено або скасовано.</target>
@@ -3291,23 +3257,11 @@ This is your own one-time link!</source>
<target>Пересилання</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>Пересилання та збереження повідомлень</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>Переслано</target>
@@ -3318,10 +3272,6 @@ This is your own one-time link!</source>
<target>Переслано з</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>Серверу переадресації %@ не вдалося з'єднатися з сервером призначення %@. Спробуйте пізніше.</target>
@@ -3616,10 +3566,6 @@ Error: %2$@</source>
<target>Сервери ICE (по одному на лінію)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>Якщо ви не можете зустрітися особисто, покажіть QR-код у відеодзвінку або поділіться посиланням.</target>
@@ -4319,10 +4265,6 @@ This is your link for group %@!</source>
<target>Надіслані повідомлення</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>Повідомлення, файли та дзвінки захищені **наскрізним шифруванням** з ідеальною секретністю переадресації, відмовою та відновленням після злому.</target>
@@ -4618,10 +4560,6 @@ This is your link for group %@!</source>
<target>Нічого не вибрано</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Сповіщення</target>
@@ -4654,7 +4592,7 @@ This is your link for group %@!</source>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>Гаразд</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4845,11 +4783,6 @@ Requires compatible VPN.</source>
<target>Інші сервери %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>Кількість PING</target>
@@ -4885,10 +4818,6 @@ Requires compatible VPN.</source>
<target>Пароль встановлено!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>Показати пароль</target>
@@ -5038,10 +4967,6 @@ Error: %@</source>
<target>Польський інтерфейс</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>Можливо, в адресі сервера неправильно вказано відбиток сертифіката</target>
@@ -5229,10 +5154,6 @@ Enable in *Network &amp; servers* settings.</source>
<target>Проксі-сервери</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>Push-повідомлення</target>
@@ -5638,10 +5559,6 @@ Enable in *Network &amp; servers* settings.</source>
<target>Сервер SMP</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<target>Безпечне отримання файлів</target>
@@ -5752,10 +5669,6 @@ Enable in *Network &amp; servers* settings.</source>
<target>Збережене повідомлення</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<target>Масштаб</target>
@@ -5958,7 +5871,7 @@ Enable in *Network &amp; servers* settings.</source>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>Відправник скасував передачу файлу.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -7042,7 +6955,7 @@ You will be prompted to complete authentication before this feature is enabled.<
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<target>Невідомі сервери!</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -7156,10 +7069,6 @@ To connect, please ask your contact to create another connection link and check
<target>Використовуйте хости .onion</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>Використовувати сервери SimpleX Chat?</target>
@@ -7235,10 +7144,6 @@ To connect, please ask your contact to create another connection link and check
<target>Вибір користувача</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>Використання серверів SimpleX Chat.</target>
@@ -7472,7 +7377,7 @@ To connect, please ask your contact to create another connection link and check
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<target>Без Tor або VPN ваша IP-адреса буде видимою для цих XFTP-ретрансляторів: %@.</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7881,10 +7786,6 @@ Repeat connection request?</source>
<target>Ваші контакти залишаться на зв'язку.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>Ваша поточна база даних чату буде ВИДАЛЕНА і ЗАМІНЕНА імпортованою.</target>
@@ -161,31 +161,11 @@
<target>%d 天</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
<source>%d file(s) are still being downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
<source>%d file(s) failed to download.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
<source>%d file(s) were deleted.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
<source>%d file(s) were not downloaded.</source>
<note>forward confirmation reason</note>
</trans-unit>
<trans-unit id="%d hours" xml:space="preserve">
<source>%d hours</source>
<target>%d 小时</target>
<note>time interval</note>
</trans-unit>
<trans-unit id="%d messages not forwarded" xml:space="preserve">
<source>%d messages not forwarded</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="%d min" xml:space="preserve">
<source>%d min</source>
<target>%d 分钟</target>
@@ -1241,7 +1221,7 @@
<trans-unit id="Cannot receive file" xml:space="preserve">
<source>Cannot receive file</source>
<target>无法接收文件</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Capacity exceeded - recipient did not receive previously sent messages." xml:space="preserve">
<source>Capacity exceeded - recipient did not receive previously sent messages.</source>
@@ -2445,10 +2425,6 @@ This is your own one-time link!</source>
<target>不给新成员发送历史消息。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
<source>Do not use credentials with proxy.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Don't create address" xml:space="preserve">
<source>Don't create address</source>
<target>不创建地址</target>
@@ -2472,8 +2448,7 @@ This is your own one-time link!</source>
<trans-unit id="Download" xml:space="preserve">
<source>Download</source>
<target>下载</target>
<note>alert button
chat item action</note>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Download errors" xml:space="preserve">
<source>Download errors</source>
@@ -2490,10 +2465,6 @@ This is your own one-time link!</source>
<target>下载文件</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Download files" xml:space="preserve">
<source>Download files</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Downloaded" xml:space="preserve">
<source>Downloaded</source>
<target>已下载</target>
@@ -2919,7 +2890,7 @@ This is your own one-time link!</source>
<trans-unit id="Error receiving file" xml:space="preserve">
<source>Error receiving file</source>
<target>接收文件错误</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error reconnecting server" xml:space="preserve">
<source>Error reconnecting server</source>
@@ -3151,11 +3122,6 @@ This is your own one-time link!</source>
<target>文件错误</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="File errors:&#10;%@" xml:space="preserve">
<source>File errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
<source>File not found - most likely file was deleted or cancelled.</source>
<target>找不到文件 - 很可能文件已被删除或取消。</target>
@@ -3291,23 +3257,11 @@ This is your own one-time link!</source>
<target>转发</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
<source>Forward %d message(s)?</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Forward and save messages" xml:space="preserve">
<source>Forward and save messages</source>
<target>转发并保存消息</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forward messages" xml:space="preserve">
<source>Forward messages</source>
<note>alert action</note>
</trans-unit>
<trans-unit id="Forward messages without files?" xml:space="preserve">
<source>Forward messages without files?</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
<source>Forwarded</source>
<target>已转发</target>
@@ -3318,10 +3272,6 @@ This is your own one-time link!</source>
<target>转发自</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
<source>Forwarding %lld messages</source>
<note>No comment provided by engineer.</note>
</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>转发服务器 %@ 无法连接到目标服务器 %@。请稍后尝试。</target>
@@ -3616,10 +3566,6 @@ Error: %2$@</source>
<target>ICE 服务器(每行一个)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="IP address" xml:space="preserve">
<source>IP address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
<target>如果您不能亲自见面,可以在视频通话中展示二维码,或分享链接。</target>
@@ -4319,10 +4265,6 @@ This is your link for group %@!</source>
<target>已发送的消息</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
<source>Messages were deleted after you selected them.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>消息、文件和通话受到 **端到端加密** 的保护,具有完全正向保密、否认和闯入恢复。</target>
@@ -4618,10 +4560,6 @@ This is your link for group %@!</source>
<target>未选中任何内容</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Nothing to forward!" xml:space="preserve">
<source>Nothing to forward!</source>
<note>alert title</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>通知</target>
@@ -4654,7 +4592,7 @@ This is your link for group %@!</source>
<trans-unit id="Ok" xml:space="preserve">
<source>Ok</source>
<target>好的</target>
<note>alert button</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Old database" xml:space="preserve">
<source>Old database</source>
@@ -4845,11 +4783,6 @@ Requires compatible VPN.</source>
<target>其他 %@ 服务器</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Other file errors:&#10;%@" xml:space="preserve">
<source>Other file errors:
%@</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>PING 次数</target>
@@ -4885,10 +4818,6 @@ Requires compatible VPN.</source>
<target>密码已设置!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password" xml:space="preserve">
<source>Password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Password to show" xml:space="preserve">
<source>Password to show</source>
<target>显示密码</target>
@@ -5038,10 +4967,6 @@ Error: %@</source>
<target>波兰语界面</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Port" xml:space="preserve">
<source>Port</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
<source>Possibly, certificate fingerprint in server address is incorrect</source>
<target>服务器地址中的证书指纹可能不正确</target>
@@ -5229,10 +5154,6 @@ Enable in *Network &amp; servers* settings.</source>
<target>代理服务器</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxy requires password" xml:space="preserve">
<source>Proxy requires password</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Push notifications" xml:space="preserve">
<source>Push notifications</source>
<target>推送通知</target>
@@ -5638,10 +5559,6 @@ Enable in *Network &amp; servers* settings.</source>
<target>SMP 服务器</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="SOCKS proxy" xml:space="preserve">
<source>SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Safely receive files" xml:space="preserve">
<source>Safely receive files</source>
<target>安全接收文件</target>
@@ -5752,10 +5669,6 @@ Enable in *Network &amp; servers* settings.</source>
<target>已保存的消息</target>
<note>message info title</note>
</trans-unit>
<trans-unit id="Saving %lld messages" xml:space="preserve">
<source>Saving %lld messages</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scale" xml:space="preserve">
<source>Scale</source>
<target>规模</target>
@@ -5958,7 +5871,7 @@ Enable in *Network &amp; servers* settings.</source>
<trans-unit id="Sender cancelled file transfer." xml:space="preserve">
<source>Sender cancelled file transfer.</source>
<target>发送人已取消文件传输。</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sender may have deleted the connection request." xml:space="preserve">
<source>Sender may have deleted the connection request.</source>
@@ -7042,7 +6955,7 @@ You will be prompted to complete authentication before this feature is enabled.<
<trans-unit id="Unknown servers!" xml:space="preserve">
<source>Unknown servers!</source>
<target>未知服务器!</target>
<note>alert title</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions." xml:space="preserve">
<source>Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.</source>
@@ -7156,10 +7069,6 @@ To connect, please ask your contact to create another connection link and check
<target>使用 .onion 主机</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
<source>Use SOCKS proxy</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
<source>Use SimpleX Chat servers?</source>
<target>使用 SimpleX Chat 服务器?</target>
@@ -7235,10 +7144,6 @@ To connect, please ask your contact to create another connection link and check
<target>用户选择</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
<source>Using SimpleX Chat servers.</source>
<target>使用 SimpleX Chat 服务器。</target>
@@ -7472,7 +7377,7 @@ To connect, please ask your contact to create another connection link and check
<trans-unit id="Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." xml:space="preserve">
<source>Without Tor or VPN, your IP address will be visible to these XFTP relays: %@.</source>
<target>如果没有 Tor 或 VPN,您的 IP 地址将对以下 XFTP 中继可见:%@。</target>
<note>alert message</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Wrong database passphrase" xml:space="preserve">
<source>Wrong database passphrase</source>
@@ -7881,10 +7786,6 @@ Repeat connection request?</source>
<target>与您的联系人保持连接。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
<source>Your credentials may be sent unencrypted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
<target>您当前的聊天数据库将被删除并替换为导入的数据库。</target>
@@ -17,7 +17,7 @@
"Comment" = "Hozzászólás";
/* No comment provided by engineer. */
"Currently maximum supported file size is %@." = "Jelenleg a maximálisan támogatott fájlméret: %@.";
"Currently maximum supported file size is %@." = "Jelenleg a maximális támogatott fájlméret %@.";
/* No comment provided by engineer. */
"Database downgrade required" = "Adatbázis visszafejlesztése szükséges";
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "Hibás adatbázis jelmondat";
/* No comment provided by engineer. */
"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "A megosztást az Adatvédelem és biztonság / SimpleX-zár menüben engedélyezheti.";
"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "A megosztást az Adatvédelem és biztonság / SimpleX zár menüben engedélyezheti.";
@@ -32,7 +32,7 @@
"Database passphrase is different from saved in the keychain." = "Het wachtwoord van de database verschilt van het wachtwoord die in de keychain is opgeslagen.";
/* No comment provided by engineer. */
"Database passphrase is required to open chat." = "Database wachtwoord is vereist om je chats te openen.";
"Database passphrase is required to open chat." = "Database wachtwoord is vereist om je gesprekken te openen.";
/* No comment provided by engineer. */
"Database upgrade required" = "Database upgrade vereist";
+34 -34
View File
@@ -204,7 +204,7 @@
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = CE38A29B2C3FCD72005ED185 /* SwiftyGif */; };
CE75480A2C622630009579B7 /* SwipeLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE7548092C622630009579B7 /* SwipeLabel.swift */; };
CE984D4B2C36C5D500E3AEFF /* ChatItemClipShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */; };
CEDB245B2C9CD71800FBC5F6 /* StickyScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDB245A2C9CD71800FBC5F6 /* StickyScrollView.swift */; };
CEA034032C9C0F1800B587E7 /* TranslateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA034022C9C0F1800B587E7 /* TranslateView.swift */; };
CEDE70222C48FD9500233B1F /* SEChatState.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDE70212C48FD9500233B1F /* SEChatState.swift */; };
CEE723AA2C3BD3D70009AE93 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE723A92C3BD3D70009AE93 /* ShareViewController.swift */; };
CEE723B12C3BD3D70009AE93 /* SimpleX SE.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = CEE723A72C3BD3D70009AE93 /* SimpleX SE.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
@@ -218,11 +218,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 */; };
E5D826852CA5F56100A9B74D /* libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5D826802CA5F56100A9B74D /* libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi-ghc9.6.3.a */; };
E5D826862CA5F56100A9B74D /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5D826812CA5F56100A9B74D /* libffi.a */; };
E5D826872CA5F56100A9B74D /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5D826822CA5F56100A9B74D /* libgmp.a */; };
E5D826882CA5F56100A9B74D /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5D826832CA5F56100A9B74D /* libgmpxx.a */; };
E5D826892CA5F56100A9B74D /* libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5D826842CA5F56100A9B74D /* libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi.a */; };
E55128E72C9AD063001D165C /* libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E55128E22C9AD063001D165C /* libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt.a */; };
E55128E82C9AD063001D165C /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E55128E32C9AD063001D165C /* libgmp.a */; };
E55128E92C9AD063001D165C /* libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E55128E42C9AD063001D165C /* libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt-ghc9.6.3.a */; };
E55128EA2C9AD063001D165C /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E55128E52C9AD063001D165C /* libgmpxx.a */; };
E55128EB2C9AD063001D165C /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E55128E62C9AD063001D165C /* 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 */; };
@@ -544,7 +544,7 @@
CE3097FA2C4C0C9F00180898 /* ErrorAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorAlert.swift; sourceTree = "<group>"; };
CE7548092C622630009579B7 /* SwipeLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeLabel.swift; sourceTree = "<group>"; };
CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemClipShape.swift; sourceTree = "<group>"; };
CEDB245A2C9CD71800FBC5F6 /* StickyScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickyScrollView.swift; sourceTree = "<group>"; };
CEA034022C9C0F1800B587E7 /* TranslateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslateView.swift; sourceTree = "<group>"; };
CEDE70212C48FD9500233B1F /* SEChatState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SEChatState.swift; sourceTree = "<group>"; };
CEE723A72C3BD3D70009AE93 /* SimpleX SE.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "SimpleX SE.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
CEE723A92C3BD3D70009AE93 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
@@ -558,11 +558,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>"; };
E5D826802CA5F56100A9B74D /* libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi-ghc9.6.3.a"; sourceTree = "<group>"; };
E5D826812CA5F56100A9B74D /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
E5D826822CA5F56100A9B74D /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
E5D826832CA5F56100A9B74D /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
E5D826842CA5F56100A9B74D /* libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi.a"; sourceTree = "<group>"; };
E55128E22C9AD063001D165C /* libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt.a"; sourceTree = "<group>"; };
E55128E32C9AD063001D165C /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
E55128E42C9AD063001D165C /* libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt-ghc9.6.3.a"; sourceTree = "<group>"; };
E55128E52C9AD063001D165C /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
E55128E62C9AD063001D165C /* 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>"; };
@@ -653,14 +653,14 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E5D826852CA5F56100A9B74D /* libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi-ghc9.6.3.a in Frameworks */,
E55128E72C9AD063001D165C /* libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt.a in Frameworks */,
E55128E82C9AD063001D165C /* libgmp.a in Frameworks */,
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
E5D826892CA5F56100A9B74D /* libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi.a in Frameworks */,
E55128EB2C9AD063001D165C /* libffi.a in Frameworks */,
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
E5D826862CA5F56100A9B74D /* libffi.a in Frameworks */,
E5D826872CA5F56100A9B74D /* libgmp.a in Frameworks */,
E55128E92C9AD063001D165C /* libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt-ghc9.6.3.a in Frameworks */,
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
E5D826882CA5F56100A9B74D /* libgmpxx.a in Frameworks */,
E55128EA2C9AD063001D165C /* libgmpxx.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -729,6 +729,7 @@
5CBE6C132944CC12002D9531 /* ScanCodeView.swift */,
64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */,
648679AA2BC96A74006456E7 /* ChatItemForwardingView.swift */,
CEA034022C9C0F1800B587E7 /* TranslateView.swift */,
8CE848A22C5A0FA000D5C7C8 /* SelectableChatItemToolbars.swift */,
);
path = Chat;
@@ -737,11 +738,11 @@
5C764E5C279C70B7000C6508 /* Libraries */ = {
isa = PBXGroup;
children = (
E5D826812CA5F56100A9B74D /* libffi.a */,
E5D826822CA5F56100A9B74D /* libgmp.a */,
E5D826832CA5F56100A9B74D /* libgmpxx.a */,
E5D826802CA5F56100A9B74D /* libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi-ghc9.6.3.a */,
E5D826842CA5F56100A9B74D /* libHSsimplex-chat-6.1.0.4-5C0H3SCWHuhICcJbTCMAKi.a */,
E55128E62C9AD063001D165C /* libffi.a */,
E55128E32C9AD063001D165C /* libgmp.a */,
E55128E52C9AD063001D165C /* libgmpxx.a */,
E55128E42C9AD063001D165C /* libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt-ghc9.6.3.a */,
E55128E22C9AD063001D165C /* libHSsimplex-chat-6.1.0.2-ItgztLmvKyzFsOmChHMkFt.a */,
);
path = Libraries;
sourceTree = "<group>";
@@ -798,7 +799,6 @@
CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */,
CE7548092C622630009579B7 /* SwipeLabel.swift */,
CE176F1F2C87014C00145DBC /* InvertedForegroundStyle.swift */,
CEDB245A2C9CD71800FBC5F6 /* StickyScrollView.swift */,
);
path = Helpers;
sourceTree = "<group>";
@@ -1396,6 +1396,7 @@
5CB634A829E437960066AD6B /* PasscodeEntry.swift in Sources */,
5CFA59C42860BC6200863A68 /* MigrateToAppGroupView.swift in Sources */,
648010AB281ADD15009009B9 /* CIFileView.swift in Sources */,
CEA034032C9C0F1800B587E7 /* TranslateView.swift in Sources */,
644EFFE2292D089800525D5B /* FramedCIVoiceView.swift in Sources */,
5C4B3B0A285FB130003915F2 /* DatabaseView.swift in Sources */,
5CB2084F28DA4B4800D024EC /* RTCServers.swift in Sources */,
@@ -1499,7 +1500,6 @@
5C93293F2928E0FD0090FFF9 /* AudioRecPlay.swift in Sources */,
5C029EA82837DBB3004A9677 /* CICallItemView.swift in Sources */,
5CE4407227ADB1D0007B033A /* Emoji.swift in Sources */,
CEDB245B2C9CD71800FBC5F6 /* StickyScrollView.swift in Sources */,
5C9CC7A928C532AB00BEF955 /* DatabaseErrorView.swift in Sources */,
5C1A4C1E27A715B700EAD5AD /* ChatItemView.swift in Sources */,
64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */,
@@ -1895,7 +1895,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 240;
CURRENT_PROJECT_VERSION = 237;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
@@ -1944,7 +1944,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 240;
CURRENT_PROJECT_VERSION = 237;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
@@ -1985,7 +1985,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 240;
CURRENT_PROJECT_VERSION = 237;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
@@ -2005,7 +2005,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 240;
CURRENT_PROJECT_VERSION = 237;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
@@ -2030,7 +2030,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 240;
CURRENT_PROJECT_VERSION = 237;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = s;
@@ -2067,7 +2067,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 240;
CURRENT_PROJECT_VERSION = 237;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_CODE_COVERAGE = NO;
@@ -2104,7 +2104,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 240;
CURRENT_PROJECT_VERSION = 237;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2155,7 +2155,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 240;
CURRENT_PROJECT_VERSION = 237;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2206,7 +2206,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 240;
CURRENT_PROJECT_VERSION = 237;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
@@ -2240,7 +2240,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 240;
CURRENT_PROJECT_VERSION = 237;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
+54 -2
View File
@@ -177,14 +177,66 @@ public func fromCString(_ c: UnsafeMutablePointer<CChar>) -> String {
return s
}
// TODO: Remove after XCode 16 crash has been resolved/merged
class ThreadExecutor<ResultType> {
private var stackSize: Int
private var qos: QualityOfService
/// Initialize by specifying the stack size
init(stackSize: Int, qos: QualityOfService) {
self.stackSize = stackSize
self.qos = qos
}
/// Execute a closure synchronously on a separate thread and return the result
func executeSync(_ task: @escaping () throws -> ResultType) throws -> ResultType {
// Initialize the semaphore (initially locked)
let semaphore = DispatchSemaphore(value: 0)
var result: Result<ResultType, Error>?
// Initialize the thread
let thread = Thread {
do {
let taskResult = try task()
result = .success(taskResult)
} catch {
result = .failure(error)
}
// Release the semaphore when the task is completed
semaphore.signal()
}
thread.stackSize = stackSize
thread.qualityOfService = qos
thread.start()
// Wait until the thread completes
semaphore.wait()
// Return the result
switch result! {
case .success(let result):
return result
case .failure(let error):
throw error
}
}
}
public func chatResponse(_ s: String) -> ChatResponse {
let d = s.data(using: .utf8)!
// TODO is there a way to do it without copying the data? e.g:
// let p = UnsafeMutableRawPointer.init(mutating: UnsafeRawPointer(cjson))
// let d = Data.init(bytesNoCopy: p, count: strlen(cjson), deallocator: .free)
do {
let r = try jsonDecoder.decode(APIResponse.self, from: d)
return r.resp
let executor = ThreadExecutor<APIResponse>(
stackSize: 2*1024*1024, // 2MiB
qos: Thread.current.qualityOfService // inherit priority
)
return try executor.executeSync {
try jsonDecoder.decode(APIResponse.self, from: d)
}.resp
} catch {
logger.error("chatResponse jsonDecoder.decode error: \(error.localizedDescription)")
}
+1 -24
View File
@@ -17,7 +17,6 @@ public struct User: Identifiable, Decodable, UserLike, NamedChat, Hashable {
public var profile: LocalProfile
public var fullPreferences: FullPreferences
public var activeUser: Bool
public var activeOrder: Int64
public var displayName: String { get { profile.displayName } }
public var fullName: String { get { profile.fullName } }
@@ -50,7 +49,6 @@ public struct User: Identifiable, Decodable, UserLike, NamedChat, Hashable {
profile: LocalProfile.sampleData,
fullPreferences: FullPreferences.sampleData,
activeUser: true,
activeOrder: 0,
showNtfs: true,
sendRcptsContacts: true,
sendRcptsSmallGroups: false
@@ -2765,16 +2763,9 @@ public struct CITimed: Decodable, Hashable {
let msgTimeFormat = Date.FormatStyle.dateTime.hour().minute()
let msgDateFormat = Date.FormatStyle.dateTime.day(.twoDigits).month(.twoDigits)
let msgDateYearFormat = Date.FormatStyle.dateTime.day(.twoDigits).month(.twoDigits).year(.twoDigits)
public func formatTimestampText(_ date: Date) -> Text {
Text(verbatim: date.formatted(
recent(date)
? msgTimeFormat
: Calendar.current.isDate(date, equalTo: .now, toGranularity: .year)
? msgDateFormat
: msgDateYearFormat
))
Text(verbatim: date.formatted(recent(date) ? msgTimeFormat : msgDateFormat))
}
public func formatTimestampMeta(_ date: Date) -> String {
@@ -2820,20 +2811,6 @@ public enum CIStatus: Decodable, Hashable {
case .invalid: return "invalid"
}
}
public var sent: Bool {
switch self {
case .sndNew: true
case .sndSent: true
case .sndRcvd: true
case .sndErrorAuth: true
case .sndError: true
case .sndWarning: true
case .rcvNew: false
case .rcvRead: false
case .invalid: false
}
}
public func statusIcon(_ metaColor: Color, _ paleMetaColor: Color, _ primaryColor: Color = .accentColor) -> (Image, Color)? {
switch self {
+5 -6
View File
@@ -709,7 +709,7 @@
/* No comment provided by engineer. */
"Cannot access keychain to save database password" = "Няма достъп до Keychain за запазване на паролата за базата данни";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "Файлът не може да бъде получен";
/* No comment provided by engineer. */
@@ -1395,8 +1395,7 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Понижи версията и отвори чата";
/* alert button
chat item action */
/* chat item action */
"Download" = "Изтегли";
/* No comment provided by engineer. */
@@ -1684,7 +1683,7 @@
/* No comment provided by engineer. */
"Error opening chat" = "Грешка при отваряне на чата";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Грешка при получаване на файл";
/* No comment provided by engineer. */
@@ -2686,7 +2685,7 @@
/* feature offered item */
"offered %@: %@" = "предлага %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "Ок";
/* No comment provided by engineer. */
@@ -3366,7 +3365,7 @@
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "Изпращане до последните 100 съобщения на нови членове.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "Подателят отмени прехвърлянето на файла.";
/* No comment provided by engineer. */
+4 -4
View File
@@ -571,7 +571,7 @@
/* No comment provided by engineer. */
"Cannot access keychain to save database password" = "Nelze získat přístup ke klíčence pro uložení hesla databáze";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "Nelze přijmout soubor";
/* No comment provided by engineer. */
@@ -1380,7 +1380,7 @@
/* No comment provided by engineer. */
"Error loading %@ servers" = "Chyba načítání %@ serverů";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Chyba při příjmu souboru";
/* No comment provided by engineer. */
@@ -2187,7 +2187,7 @@
/* feature offered item */
"offered %@: %@" = "nabídl %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "Ok";
/* No comment provided by engineer. */
@@ -2735,7 +2735,7 @@
/* No comment provided by engineer. */
"Send them from gallery or custom keyboards." = "Odeslat je z galerie nebo vlastní klávesnice.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "Odesílatel zrušil přenos souboru.";
/* No comment provided by engineer. */
+7 -68
View File
@@ -160,9 +160,6 @@
/* notification title */
"%@ wants to connect!" = "%@ will sich mit Ihnen verbinden!";
/* format for date separator in chat */
"%@, %@" = "%1$@, %2$@";
/* No comment provided by engineer. */
"%@, %@ and %lld members" = "%@, %@ und %lld Mitglieder";
@@ -652,9 +649,6 @@
/* No comment provided by engineer. */
"Auto-accept images" = "Bilder automatisch akzeptieren";
/* alert title */
"Auto-accept settings" = "Einstellungen automatisch akzeptieren";
/* No comment provided by engineer. */
"Back" = "Zurück";
@@ -802,7 +796,7 @@
/* No comment provided by engineer. */
"Cannot forward message" = "Die Nachricht kann nicht weitergeleitet werden";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "Datei kann nicht empfangen werden";
/* snd error text */
@@ -896,9 +890,6 @@
/* No comment provided by engineer. */
"Chat preferences" = "Chat-Präferenzen";
/* alert message */
"Chat preferences were changed." = "Die Chat-Präferenzen wurden geändert.";
/* No comment provided by engineer. */
"Chat theme" = "Chat-Design";
@@ -1187,9 +1178,6 @@
/* No comment provided by engineer. */
"Core version: v%@" = "Core Version: v%@";
/* No comment provided by engineer. */
"Corner" = "Ecke";
/* No comment provided by engineer. */
"Correct name to %@?" = "Richtiger Name für %@?";
@@ -1641,8 +1629,7 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Datenbank herabstufen und den Chat öffnen";
/* alert button
chat item action */
/* chat item action */
"Download" = "Herunterladen";
/* No comment provided by engineer. */
@@ -1870,18 +1857,12 @@
/* No comment provided by engineer. */
"Error changing address" = "Fehler beim Wechseln der Empfängeradresse";
/* No comment provided by engineer. */
"Error changing connection profile" = "Fehler beim Wechseln des Verbindungs-Profils";
/* No comment provided by engineer. */
"Error changing role" = "Fehler beim Ändern der Rolle";
/* No comment provided by engineer. */
"Error changing setting" = "Fehler beim Ändern der Einstellung";
/* No comment provided by engineer. */
"Error changing to incognito!" = "Fehler beim Wechseln zum Inkognito-Profil!";
/* No comment provided by engineer. */
"Error connecting to forwarding server %@. Please try later." = "Fehler beim Verbinden mit dem Weiterleitungsserver %@. Bitte versuchen Sie es später erneut.";
@@ -1954,13 +1935,10 @@
/* No comment provided by engineer. */
"Error loading %@ servers" = "Fehler beim Laden von %@ Servern";
/* No comment provided by engineer. */
"Error migrating settings" = "Fehler beim Migrieren der Einstellungen";
/* No comment provided by engineer. */
"Error opening chat" = "Fehler beim Öffnen des Chats";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Fehler beim Empfangen der Datei";
/* No comment provided by engineer. */
@@ -2017,9 +1995,6 @@
/* No comment provided by engineer. */
"Error stopping chat" = "Fehler beim Beenden des Chats";
/* No comment provided by engineer. */
"Error switching profile" = "Fehler beim Wechseln des Profils";
/* No comment provided by engineer. */
"Error switching profile!" = "Fehler beim Umschalten des Profils!";
@@ -2840,9 +2815,6 @@
/* No comment provided by engineer. */
"Message servers" = "Nachrichten-Server";
/* No comment provided by engineer. */
"Message shape" = "Nachrichten-Form";
/* No comment provided by engineer. */
"Message source remains private." = "Die Nachrichtenquelle bleibt privat.";
@@ -3109,7 +3081,7 @@
/* feature offered item */
"offered %@: %@" = "angeboten %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "Ok";
/* No comment provided by engineer. */
@@ -3608,9 +3580,6 @@
/* No comment provided by engineer. */
"Remove" = "Entfernen";
/* No comment provided by engineer. */
"Remove archive?" = "Archiv entfernen?";
/* No comment provided by engineer. */
"Remove image" = "Bild entfernen";
@@ -3783,9 +3752,6 @@
/* No comment provided by engineer. */
"Save welcome message?" = "Begrüßungsmeldung speichern?";
/* alert title */
"Save your profile?" = "Ihr Profil speichern?";
/* No comment provided by engineer. */
"saved" = "abgespeichert";
@@ -3867,9 +3833,6 @@
/* chat item action */
"Select" = "Auswählen";
/* No comment provided by engineer. */
"Select chat profile" = "Chat-Profil auswählen";
/* No comment provided by engineer. */
"Selected %lld" = "%lld ausgewählt";
@@ -3942,7 +3905,7 @@
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "Bis zu 100 der letzten Nachrichten an neue Gruppenmitglieder senden.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "Der Absender hat die Dateiübertragung abgebrochen.";
/* No comment provided by engineer. */
@@ -4083,9 +4046,6 @@
/* No comment provided by engineer. */
"Settings" = "Einstellungen";
/* alert message */
"Settings were changed." = "Die Einstellungen wurden geändert.";
/* No comment provided by engineer. */
"Shape profile images" = "Form der Profil-Bilder";
@@ -4107,9 +4067,6 @@
/* No comment provided by engineer. */
"Share link" = "Link teilen";
/* No comment provided by engineer. */
"Share profile" = "Profil teilen";
/* No comment provided by engineer. */
"Share this 1-time invite link" = "Teilen Sie diesen Einmal-Einladungslink";
@@ -4212,9 +4169,6 @@
/* blur media */
"Soft" = "Weich";
/* No comment provided by engineer. */
"Some app settings were not migrated." = "Einige App-Einstellungen wurden nicht migriert.";
/* No comment provided by engineer. */
"Some file(s) were not exported:" = "Einzelne Datei(en) wurde(n) nicht exportiert:";
@@ -4314,9 +4268,6 @@
/* No comment provided by engineer. */
"System authentication" = "System-Authentifizierung";
/* No comment provided by engineer. */
"Tail" = "Sprechblase";
/* No comment provided by engineer. */
"Take picture" = "Machen Sie ein Foto";
@@ -4446,9 +4397,6 @@
/* No comment provided by engineer. */
"The text you pasted is not a SimpleX link." = "Der von Ihnen eingefügte Text ist kein SimpleX-Link.";
/* No comment provided by engineer. */
"The uploaded database archive will be permanently removed from the servers." = "Das hochgeladene Datenbank-Archiv wird dauerhaft von den Servern entfernt.";
/* No comment provided by engineer. */
"Themes" = "Design";
@@ -4626,7 +4574,7 @@
/* No comment provided by engineer. */
"unknown servers" = "Unbekannte Relais";
/* alert title */
/* No comment provided by engineer. */
"Unknown servers!" = "Unbekannte Server!";
/* No comment provided by engineer. */
@@ -4932,7 +4880,7 @@
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to file servers." = "Ohne Tor- oder VPN-Nutzung wird Ihre IP-Adresse für Datei-Server sichtbar sein.";
/* alert message */
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." = "Ohne Tor- oder VPN-Nutzung wird Ihre IP-Adresse für diese XFTP-Relais sichtbar sein: %@.";
/* No comment provided by engineer. */
@@ -5193,15 +5141,9 @@
/* No comment provided by engineer. */
"Your chat database is not encrypted - set passphrase to encrypt it." = "Ihre Chat-Datenbank ist nicht verschlüsselt. Bitte legen Sie ein Passwort fest, um sie zu schützen.";
/* alert title */
"Your chat preferences" = "Ihre Chat-Präferenzen";
/* No comment provided by engineer. */
"Your chat profiles" = "Ihre Chat-Profile";
/* No comment provided by engineer. */
"Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." = "Ihre Verbindung wurde auf %@ verschoben. Während Sie auf das Profil weitergeleitet wurden trat aber ein unerwarteter Fehler auf.";
/* No comment provided by engineer. */
"Your contact sent a file that is larger than currently supported maximum size (%@)." = "Ihr Kontakt hat eine Datei gesendet, die größer ist als die derzeit unterstützte maximale Größe (%@).";
@@ -5235,9 +5177,6 @@
/* No comment provided by engineer. */
"Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." = "Ihr Profil wird auf Ihrem Gerät gespeichert und nur mit Ihren Kontakten geteilt. SimpleX-Server können Ihr Profil nicht einsehen.";
/* alert message */
"Your profile was changed. If you save it, the updated profile will be sent to all your contacts." = "Ihr Profil wurde geändert. Wenn Sie es speichern, wird das aktualisierte Profil an alle Ihre Kontakte gesendet.";
/* No comment provided by engineer. */
"Your profile, contacts and delivered messages are stored on your device." = "Ihr Profil, Ihre Kontakte und zugestellten Nachrichten werden auf Ihrem Gerät gespeichert.";
+7 -8
View File
@@ -796,7 +796,7 @@
/* No comment provided by engineer. */
"Cannot forward message" = "No se puede reenviar el mensaje";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "No se puede recibir el archivo";
/* snd error text */
@@ -1629,8 +1629,7 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Degradar y abrir Chat";
/* alert button
chat item action */
/* chat item action */
"Download" = "Descargar";
/* No comment provided by engineer. */
@@ -1939,7 +1938,7 @@
/* No comment provided by engineer. */
"Error opening chat" = "Error al abrir chat";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Error al recibir archivo";
/* No comment provided by engineer. */
@@ -3082,7 +3081,7 @@
/* feature offered item */
"offered %@: %@" = "ofrecido %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "Ok";
/* No comment provided by engineer. */
@@ -3906,7 +3905,7 @@
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "Se envían hasta 100 mensajes más recientes a los miembros nuevos.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "El remitente ha cancelado la transferencia de archivos.";
/* No comment provided by engineer. */
@@ -4575,7 +4574,7 @@
/* No comment provided by engineer. */
"unknown servers" = "con servidores desconocidos";
/* alert title */
/* No comment provided by engineer. */
"Unknown servers!" = "¡Servidores desconocidos!";
/* No comment provided by engineer. */
@@ -4881,7 +4880,7 @@
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to file servers." = "Sin Tor o VPN, tu dirección IP será visible para los servidores de archivos.";
/* alert message */
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." = "Sin Tor o VPN, tu dirección IP será visible para estos servidores XFTP: %@.";
/* No comment provided by engineer. */
+4 -4
View File
@@ -556,7 +556,7 @@
/* No comment provided by engineer. */
"Cannot access keychain to save database password" = "Ei pääsyä avainnippuun tietokannan salasanan tallentamiseksi";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "Tiedostoa ei voi vastaanottaa";
/* No comment provided by engineer. */
@@ -1356,7 +1356,7 @@
/* No comment provided by engineer. */
"Error loading %@ servers" = "Virhe %@-palvelimien lataamisessa";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Virhe tiedoston vastaanottamisessa";
/* No comment provided by engineer. */
@@ -2160,7 +2160,7 @@
/* feature offered item */
"offered %@: %@" = "tarjottu %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "Ok";
/* No comment provided by engineer. */
@@ -2699,7 +2699,7 @@
/* No comment provided by engineer. */
"Send them from gallery or custom keyboards." = "Lähetä ne galleriasta tai mukautetuista näppäimistöistä.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "Lähettäjä peruutti tiedoston siirron.";
/* No comment provided by engineer. */
+7 -8
View File
@@ -796,7 +796,7 @@
/* No comment provided by engineer. */
"Cannot forward message" = "Impossible de transférer le message";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "Impossible de recevoir le fichier";
/* snd error text */
@@ -1629,8 +1629,7 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Rétrograder et ouvrir le chat";
/* alert button
chat item action */
/* chat item action */
"Download" = "Télécharger";
/* No comment provided by engineer. */
@@ -1939,7 +1938,7 @@
/* No comment provided by engineer. */
"Error opening chat" = "Erreur lors de l'ouverture du chat";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Erreur lors de la réception du fichier";
/* No comment provided by engineer. */
@@ -3082,7 +3081,7 @@
/* feature offered item */
"offered %@: %@" = "propose %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "Ok";
/* No comment provided by engineer. */
@@ -3906,7 +3905,7 @@
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "Envoi des 100 derniers messages aux nouveaux membres.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "L'expéditeur a annulé le transfert de fichiers.";
/* No comment provided by engineer. */
@@ -4575,7 +4574,7 @@
/* No comment provided by engineer. */
"unknown servers" = "relais inconnus";
/* alert title */
/* No comment provided by engineer. */
"Unknown servers!" = "Serveurs inconnus!";
/* No comment provided by engineer. */
@@ -4881,7 +4880,7 @@
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to file servers." = "Sans Tor ou un VPN, votre adresse IP sera visible par les serveurs de fichiers.";
/* alert message */
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." = "Sans Tor ni VPN, votre adresse IP sera visible par ces relais XFTP: %@.";
/* No comment provided by engineer. */
File diff suppressed because it is too large Load Diff
+7 -68
View File
@@ -160,9 +160,6 @@
/* notification title */
"%@ wants to connect!" = "%@ si vuole connettere!";
/* format for date separator in chat */
"%@, %@" = "%1$@, %2$@";
/* No comment provided by engineer. */
"%@, %@ and %lld members" = "%@, %@ e %lld membri";
@@ -652,9 +649,6 @@
/* No comment provided by engineer. */
"Auto-accept images" = "Auto-accetta immagini";
/* alert title */
"Auto-accept settings" = "Accetta automaticamente le impostazioni";
/* No comment provided by engineer. */
"Back" = "Indietro";
@@ -802,7 +796,7 @@
/* No comment provided by engineer. */
"Cannot forward message" = "Impossibile inoltrare il messaggio";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "Impossibile ricevere il file";
/* snd error text */
@@ -896,9 +890,6 @@
/* No comment provided by engineer. */
"Chat preferences" = "Preferenze della chat";
/* alert message */
"Chat preferences were changed." = "Le preferenze della chat sono state cambiate.";
/* No comment provided by engineer. */
"Chat theme" = "Tema della chat";
@@ -1187,9 +1178,6 @@
/* No comment provided by engineer. */
"Core version: v%@" = "Versione core: v%@";
/* No comment provided by engineer. */
"Corner" = "Angolo";
/* No comment provided by engineer. */
"Correct name to %@?" = "Correggere il nome a %@?";
@@ -1641,8 +1629,7 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Esegui downgrade e apri chat";
/* alert button
chat item action */
/* chat item action */
"Download" = "Scarica";
/* No comment provided by engineer. */
@@ -1870,18 +1857,12 @@
/* No comment provided by engineer. */
"Error changing address" = "Errore nella modifica dell'indirizzo";
/* No comment provided by engineer. */
"Error changing connection profile" = "Errore nel cambio di profilo di connessione";
/* No comment provided by engineer. */
"Error changing role" = "Errore nel cambio di ruolo";
/* No comment provided by engineer. */
"Error changing setting" = "Errore nella modifica dell'impostazione";
/* No comment provided by engineer. */
"Error changing to incognito!" = "Errore nel passaggio a incognito!";
/* No comment provided by engineer. */
"Error connecting to forwarding server %@. Please try later." = "Errore di connessione al server di inoltro %@. Riprova più tardi.";
@@ -1954,13 +1935,10 @@
/* No comment provided by engineer. */
"Error loading %@ servers" = "Errore nel caricamento dei server %@";
/* No comment provided by engineer. */
"Error migrating settings" = "Errore nella migrazione delle impostazioni";
/* No comment provided by engineer. */
"Error opening chat" = "Errore di apertura della chat";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Errore nella ricezione del file";
/* No comment provided by engineer. */
@@ -2017,9 +1995,6 @@
/* No comment provided by engineer. */
"Error stopping chat" = "Errore nell'interruzione della chat";
/* No comment provided by engineer. */
"Error switching profile" = "Errore nel cambio di profilo";
/* No comment provided by engineer. */
"Error switching profile!" = "Errore nel cambio di profilo!";
@@ -2840,9 +2815,6 @@
/* No comment provided by engineer. */
"Message servers" = "Server dei messaggi";
/* No comment provided by engineer. */
"Message shape" = "Forma del messaggio";
/* No comment provided by engineer. */
"Message source remains private." = "La fonte del messaggio resta privata.";
@@ -3109,7 +3081,7 @@
/* feature offered item */
"offered %@: %@" = "offerto %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "Ok";
/* No comment provided by engineer. */
@@ -3608,9 +3580,6 @@
/* No comment provided by engineer. */
"Remove" = "Rimuovi";
/* No comment provided by engineer. */
"Remove archive?" = "Rimuovere l'archivio?";
/* No comment provided by engineer. */
"Remove image" = "Rimuovi immagine";
@@ -3783,9 +3752,6 @@
/* No comment provided by engineer. */
"Save welcome message?" = "Salvare il messaggio di benvenuto?";
/* alert title */
"Save your profile?" = "Salvare il profilo?";
/* No comment provided by engineer. */
"saved" = "salvato";
@@ -3867,9 +3833,6 @@
/* chat item action */
"Select" = "Seleziona";
/* No comment provided by engineer. */
"Select chat profile" = "Seleziona il profilo di chat";
/* No comment provided by engineer. */
"Selected %lld" = "%lld selezionato";
@@ -3942,7 +3905,7 @@
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "Invia fino a 100 ultimi messaggi ai nuovi membri.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "Il mittente ha annullato il trasferimento del file.";
/* No comment provided by engineer. */
@@ -4083,9 +4046,6 @@
/* No comment provided by engineer. */
"Settings" = "Impostazioni";
/* alert message */
"Settings were changed." = "Le impostazioni sono state cambiate.";
/* No comment provided by engineer. */
"Shape profile images" = "Forma delle immagini del profilo";
@@ -4107,9 +4067,6 @@
/* No comment provided by engineer. */
"Share link" = "Condividi link";
/* No comment provided by engineer. */
"Share profile" = "Condividi il profilo";
/* No comment provided by engineer. */
"Share this 1-time invite link" = "Condividi questo link di invito una tantum";
@@ -4212,9 +4169,6 @@
/* blur media */
"Soft" = "Leggera";
/* No comment provided by engineer. */
"Some app settings were not migrated." = "Alcune impostazioni dell'app non sono state migrate.";
/* No comment provided by engineer. */
"Some file(s) were not exported:" = "Alcuni file non sono stati esportati:";
@@ -4314,9 +4268,6 @@
/* No comment provided by engineer. */
"System authentication" = "Autenticazione di sistema";
/* No comment provided by engineer. */
"Tail" = "Coda";
/* No comment provided by engineer. */
"Take picture" = "Scatta foto";
@@ -4446,9 +4397,6 @@
/* No comment provided by engineer. */
"The text you pasted is not a SimpleX link." = "Il testo che hai incollato non è un link SimpleX.";
/* No comment provided by engineer. */
"The uploaded database archive will be permanently removed from the servers." = "L'archivio del database caricato verrà rimosso definitivamente dai server.";
/* No comment provided by engineer. */
"Themes" = "Temi";
@@ -4626,7 +4574,7 @@
/* No comment provided by engineer. */
"unknown servers" = "relay sconosciuti";
/* alert title */
/* No comment provided by engineer. */
"Unknown servers!" = "Server sconosciuti!";
/* No comment provided by engineer. */
@@ -4932,7 +4880,7 @@
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to file servers." = "Senza Tor o VPN, il tuo indirizzo IP sarà visibile ai server di file.";
/* alert message */
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." = "Senza Tor o VPN, il tuo indirizzo IP sarà visibile a questi relay XFTP: %@.";
/* No comment provided by engineer. */
@@ -5193,15 +5141,9 @@
/* No comment provided by engineer. */
"Your chat database is not encrypted - set passphrase to encrypt it." = "Il tuo database della chat non è crittografato: imposta la password per crittografarlo.";
/* alert title */
"Your chat preferences" = "Le tue preferenze della chat";
/* No comment provided by engineer. */
"Your chat profiles" = "I tuoi profili di chat";
/* No comment provided by engineer. */
"Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." = "La tua connessione è stata spostata a %@, ma si è verificato un errore imprevisto durante il reindirizzamento al profilo.";
/* No comment provided by engineer. */
"Your contact sent a file that is larger than currently supported maximum size (%@)." = "Il tuo contatto ha inviato un file più grande della dimensione massima attualmente supportata (%@).";
@@ -5235,9 +5177,6 @@
/* No comment provided by engineer. */
"Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." = "Il tuo profilo è memorizzato sul tuo dispositivo e condiviso solo con i tuoi contatti. I server di SimpleX non possono vedere il tuo profilo.";
/* alert message */
"Your profile was changed. If you save it, the updated profile will be sent to all your contacts." = "Il tuo profilo è stato cambiato. Se lo salvi, il profilo aggiornato verrà inviato a tutti i tuoi contatti.";
/* No comment provided by engineer. */
"Your profile, contacts and delivered messages are stored on your device." = "Il tuo profilo, i contatti e i messaggi recapitati sono memorizzati sul tuo dispositivo.";
+4 -4
View File
@@ -628,7 +628,7 @@
/* No comment provided by engineer. */
"Cannot access keychain to save database password" = "データベースのパスワードを保存するためのキーチェーンにアクセスできません";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "ファイル受信ができません";
/* No comment provided by engineer. */
@@ -1431,7 +1431,7 @@
/* No comment provided by engineer. */
"Error loading %@ servers" = "%@ サーバーのロード中にエラーが発生";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "ファイル受信にエラー発生";
/* No comment provided by engineer. */
@@ -2235,7 +2235,7 @@
/* feature offered item */
"offered %@: %@" = "提供された %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "OK";
/* No comment provided by engineer. */
@@ -2771,7 +2771,7 @@
/* No comment provided by engineer. */
"Send them from gallery or custom keyboards." = "ギャラリーまたはカスタム キーボードから送信します。";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "送信者がファイル転送をキャンセルしました。";
/* No comment provided by engineer. */
+30 -88
View File
@@ -160,9 +160,6 @@
/* notification title */
"%@ wants to connect!" = "%@ wil verbinding maken!";
/* format for date separator in chat */
"%@, %@" = "%1$@, %2$@";
/* No comment provided by engineer. */
"%@, %@ and %lld members" = "%@, %@ en %lld leden";
@@ -311,7 +308,7 @@
"A new random profile will be shared." = "Een nieuw willekeurig profiel wordt gedeeld.";
/* No comment provided by engineer. */
"A separate TCP connection will be used **for each chat profile you have in the app**." = "Er wordt een aparte TCP-verbinding gebruikt **voor elk chatprofiel dat je in de app hebt**.";
"A separate TCP connection will be used **for each chat profile you have in the app**." = "Er wordt een aparte TCP-verbinding gebruikt **voor elk chat profiel dat je in de app hebt**.";
/* No comment provided by engineer. */
"A separate TCP connection will be used **for each contact and group member**.\n**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail." = "Er wordt een aparte TCP-verbinding gebruikt **voor elk contact en groepslid**.\n**Let op**: als u veel verbindingen heeft, kan uw batterij- en verkeersverbruik aanzienlijk hoger zijn en kunnen sommige verbindingen uitvallen.";
@@ -652,9 +649,6 @@
/* No comment provided by engineer. */
"Auto-accept images" = "Afbeeldingen automatisch accepteren";
/* alert title */
"Auto-accept settings" = "Instellingen automatisch accepteren";
/* No comment provided by engineer. */
"Back" = "Terug";
@@ -746,7 +740,7 @@
"Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!" = "Bulgaars, Fins, Thais en Oekraïens - dankzij de gebruikers en [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!";
/* 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)." = "Via chatprofiel (standaard) of [via verbinding](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).";
"By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)." = "Via chat profiel (standaard) of [via verbinding](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA).";
/* No comment provided by engineer. */
"call" = "bellen";
@@ -802,7 +796,7 @@
/* No comment provided by engineer. */
"Cannot forward message" = "Kan bericht niet doorsturen";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "Kan bestand niet ontvangen";
/* snd error text */
@@ -896,14 +890,11 @@
/* No comment provided by engineer. */
"Chat preferences" = "Gesprek voorkeuren";
/* alert message */
"Chat preferences were changed." = "Chatvoorkeuren zijn gewijzigd.";
/* No comment provided by engineer. */
"Chat theme" = "Chat thema";
/* No comment provided by engineer. */
"Chats" = "Chats";
"Chats" = "Gesprekken";
/* No comment provided by engineer. */
"Check server address and try again." = "Controleer het server adres en probeer het opnieuw.";
@@ -1187,9 +1178,6 @@
/* No comment provided by engineer. */
"Core version: v%@" = "Core versie: v% @";
/* No comment provided by engineer. */
"Corner" = "Hoek";
/* No comment provided by engineer. */
"Correct name to %@?" = "Juiste naam voor %@?";
@@ -1320,7 +1308,7 @@
"Database passphrase is different from saved in the keychain." = "Het wachtwoord van de database verschilt van het wachtwoord dat is opgeslagen in de keychain.";
/* No comment provided by engineer. */
"Database passphrase is required to open chat." = "Database wachtwoord is vereist om je chats te openen.";
"Database passphrase is required to open chat." = "Database wachtwoord is vereist om je gesprekken te openen.";
/* No comment provided by engineer. */
"Database upgrade" = "Database upgrade";
@@ -1393,10 +1381,10 @@
"Delete chat archive?" = "Chat archief verwijderen?";
/* No comment provided by engineer. */
"Delete chat profile" = "Chatprofiel verwijderen";
"Delete chat profile" = "Chat profiel verwijderen";
/* No comment provided by engineer. */
"Delete chat profile?" = "Chatprofiel verwijderen?";
"Delete chat profile?" = "Chat profiel verwijderen?";
/* No comment provided by engineer. */
"Delete connection" = "Verbinding verwijderen";
@@ -1420,7 +1408,7 @@
"Delete files and media?" = "Bestanden en media verwijderen?";
/* No comment provided by engineer. */
"Delete files for all chat profiles" = "Verwijder bestanden voor alle chatprofielen";
"Delete files for all chat profiles" = "Verwijder bestanden voor alle chat profielen";
/* chat feature */
"Delete for everyone" = "Verwijderen voor iedereen";
@@ -1641,8 +1629,7 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Downgraden en chat openen";
/* alert button
chat item action */
/* chat item action */
"Download" = "Downloaden";
/* No comment provided by engineer. */
@@ -1870,18 +1857,12 @@
/* No comment provided by engineer. */
"Error changing address" = "Fout bij wijzigen van adres";
/* No comment provided by engineer. */
"Error changing connection profile" = "Fout bij wijzigen van verbindingsprofiel";
/* No comment provided by engineer. */
"Error changing role" = "Fout bij wisselen van rol";
/* No comment provided by engineer. */
"Error changing setting" = "Fout bij wijzigen van instelling";
/* No comment provided by engineer. */
"Error changing to incognito!" = "Fout bij het overschakelen naar incognito!";
/* No comment provided by engineer. */
"Error connecting to forwarding server %@. Please try later." = "Fout bij het verbinden met doorstuurserver %@. Probeer het later opnieuw.";
@@ -1954,13 +1935,10 @@
/* No comment provided by engineer. */
"Error loading %@ servers" = "Fout bij het laden van %@ servers";
/* No comment provided by engineer. */
"Error migrating settings" = "Fout bij migreren van instellingen";
/* No comment provided by engineer. */
"Error opening chat" = "Fout bij het openen van de chat";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Fout bij ontvangen van bestand";
/* No comment provided by engineer. */
@@ -2017,9 +1995,6 @@
/* No comment provided by engineer. */
"Error stopping chat" = "Fout bij het stoppen van de chat";
/* No comment provided by engineer. */
"Error switching profile" = "Fout bij wisselen van profiel";
/* No comment provided by engineer. */
"Error switching profile!" = "Fout bij wisselen van profiel!";
@@ -2163,7 +2138,7 @@
"Finally, we have them! 🚀" = "Eindelijk, we hebben ze! 🚀";
/* No comment provided by engineer. */
"Find chats faster" = "Vind chats sneller";
"Find chats faster" = "Vind gesprekken sneller";
/* No comment provided by engineer. */
"Fix" = "Herstel";
@@ -2337,7 +2312,7 @@
"Hidden" = "Verborgen";
/* No comment provided by engineer. */
"Hidden chat profiles" = "Verborgen chatprofielen";
"Hidden chat profiles" = "Verborgen chat profielen";
/* No comment provided by engineer. */
"Hidden profile password" = "Verborgen profiel wachtwoord";
@@ -2598,7 +2573,7 @@
"Irreversible message deletion is prohibited in this group." = "Het onomkeerbaar verwijderen van berichten is verboden in deze groep.";
/* No comment provided by engineer. */
"It allows having many anonymous connections without any shared data between them in a single chat profile." = "Het maakt het mogelijk om veel anonieme verbindingen te hebben zonder enige gedeelde gegevens tussen hen in een enkel chatprofiel.";
"It allows having many anonymous connections without any shared data between them in a single chat profile." = "Het maakt het mogelijk om veel anonieme verbindingen te hebben zonder enige gedeelde gegevens tussen hen in een enkel chat profiel.";
/* No comment provided by engineer. */
"It can happen when you or your connection used the old database backup." = "Het kan gebeuren wanneer u of de ander een oude database back-up gebruikt.";
@@ -2840,9 +2815,6 @@
/* No comment provided by engineer. */
"Message servers" = "Berichtservers";
/* No comment provided by engineer. */
"Message shape" = "Berichtvorm";
/* No comment provided by engineer. */
"Message source remains private." = "Berichtbron blijft privé.";
@@ -2949,7 +2921,7 @@
"Most likely this connection is deleted." = "Hoogstwaarschijnlijk is deze verbinding verwijderd.";
/* No comment provided by engineer. */
"Multiple chat profiles" = "Meerdere chatprofielen";
"Multiple chat profiles" = "Meerdere chat profielen";
/* No comment provided by engineer. */
"mute" = "dempen";
@@ -3054,7 +3026,7 @@
"no e2e encryption" = "geen e2e versleuteling";
/* No comment provided by engineer. */
"No filtered chats" = "Geen gefilterde chats";
"No filtered chats" = "Geen gefilterde gesprekken";
/* No comment provided by engineer. */
"No group!" = "Groep niet gevonden!";
@@ -3109,7 +3081,7 @@
/* feature offered item */
"offered %@: %@" = "voorgesteld %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "OK";
/* No comment provided by engineer. */
@@ -3299,7 +3271,7 @@
"PING interval" = "PING interval";
/* No comment provided by engineer. */
"Play from the chat list." = "Afspelen via de chat lijst.";
"Play from the chat list." = "Afspelen via de gesprekken lijst.";
/* No comment provided by engineer. */
"Please ask your contact to enable calls." = "Vraag uw contactpersoon om oproepen in te schakelen.";
@@ -3344,7 +3316,7 @@
"Please restart the app and migrate the database to enable push notifications." = "Start de app opnieuw en migreer de database om push meldingen in te schakelen.";
/* No comment provided by engineer. */
"Please store passphrase securely, you will NOT be able to access chat if you lose it." = "Sla het wachtwoord veilig op. Als u deze kwijtraakt, heeft u GEEN toegang tot de chats.";
"Please store passphrase securely, you will NOT be able to access chat if you lose it." = "Sla het wachtwoord veilig op. Als u deze kwijtraakt, heeft u GEEN toegang tot de gesprekken.";
/* No comment provided by engineer. */
"Please store passphrase securely, you will NOT be able to change it if you lose it." = "Bewaar het wachtwoord veilig, u kunt deze NIET wijzigen als u het kwijtraakt.";
@@ -3446,7 +3418,7 @@
"Protect IP address" = "Bescherm het IP-adres";
/* No comment provided by engineer. */
"Protect your chat profiles with a password!" = "Bescherm je chatprofielen met een wachtwoord!";
"Protect your chat profiles with a password!" = "Bescherm je chat profielen met een wachtwoord!";
/* No comment provided by engineer. */
"Protect your IP address from the messaging relays chosen by your contacts.\nEnable in *Network & servers* settings." = "Bescherm uw IP-adres tegen de berichtenrelais die door uw contacten zijn gekozen.\nSchakel dit in in *Netwerk en servers*-instellingen.";
@@ -3608,9 +3580,6 @@
/* No comment provided by engineer. */
"Remove" = "Verwijderen";
/* No comment provided by engineer. */
"Remove archive?" = "Archief verwijderen?";
/* No comment provided by engineer. */
"Remove image" = "Verwijder afbeelding";
@@ -3693,7 +3662,7 @@
"Reset to user theme" = "Terugzetten naar gebruikersthema";
/* No comment provided by engineer. */
"Restart the app to create a new chat profile" = "Start de app opnieuw om een nieuw chatprofiel aan te maken";
"Restart the app to create a new chat profile" = "Start de app opnieuw om een nieuw chat profiel aan te maken";
/* No comment provided by engineer. */
"Restart the app to use imported chat database" = "Start de app opnieuw om de geïmporteerde chat database te gebruiken";
@@ -3763,7 +3732,7 @@
"Save group profile" = "Groep profiel opslaan";
/* No comment provided by engineer. */
"Save passphrase and open chat" = "Bewaar het wachtwoord en open je chats";
"Save passphrase and open chat" = "Bewaar het wachtwoord en open je gesprekken";
/* No comment provided by engineer. */
"Save passphrase in Keychain" = "Sla het wachtwoord op in de Keychain";
@@ -3775,7 +3744,7 @@
"Save profile password" = "Bewaar profiel wachtwoord";
/* No comment provided by engineer. */
"Save servers" = "Servers opslaan";
"Save servers" = "Bewaar servers";
/* No comment provided by engineer. */
"Save servers?" = "Servers opslaan?";
@@ -3783,9 +3752,6 @@
/* No comment provided by engineer. */
"Save welcome message?" = "Welkom bericht opslaan?";
/* alert title */
"Save your profile?" = "Uw profiel opslaan?";
/* No comment provided by engineer. */
"saved" = "opgeslagen";
@@ -3867,9 +3833,6 @@
/* chat item action */
"Select" = "Selecteer";
/* No comment provided by engineer. */
"Select chat profile" = "Selecteer chatprofiel";
/* No comment provided by engineer. */
"Selected %lld" = "%lld geselecteerd";
@@ -3942,7 +3905,7 @@
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "Stuur tot 100 laatste berichten naar nieuwe leden.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "Afzender heeft bestandsoverdracht geannuleerd.";
/* No comment provided by engineer. */
@@ -4083,9 +4046,6 @@
/* No comment provided by engineer. */
"Settings" = "Instellingen";
/* alert message */
"Settings were changed." = "Instellingen zijn gewijzigd.";
/* No comment provided by engineer. */
"Shape profile images" = "Vorm profiel afbeeldingen";
@@ -4107,9 +4067,6 @@
/* No comment provided by engineer. */
"Share link" = "Deel link";
/* No comment provided by engineer. */
"Share profile" = "Profiel delen";
/* No comment provided by engineer. */
"Share this 1-time invite link" = "Deel deze eenmalige uitnodigingslink";
@@ -4212,9 +4169,6 @@
/* blur media */
"Soft" = "Soft";
/* No comment provided by engineer. */
"Some app settings were not migrated." = "Sommige app-instellingen zijn niet gemigreerd.";
/* No comment provided by engineer. */
"Some file(s) were not exported:" = "Sommige bestanden zijn niet geëxporteerd:";
@@ -4438,14 +4392,11 @@
"The sender will NOT be notified" = "De afzender wordt NIET op de hoogte gebracht";
/* No comment provided by engineer. */
"The servers for new connections of your current chat profile **%@**." = "De servers voor nieuwe verbindingen van uw huidige chatprofiel **%@**.";
"The servers for new connections of your current chat profile **%@**." = "De servers voor nieuwe verbindingen van uw huidige chat profiel **%@**.";
/* No comment provided by engineer. */
"The text you pasted is not a SimpleX link." = "De tekst die u hebt geplakt is geen SimpleX link.";
/* No comment provided by engineer. */
"The uploaded database archive will be permanently removed from the servers." = "Het geüploade databasearchief wordt permanent van de servers verwijderd.";
/* No comment provided by engineer. */
"Themes" = "Thema's";
@@ -4495,7 +4446,7 @@
"This link was used with another mobile device, please create a new link on the desktop." = "Deze link is gebruikt met een ander mobiel apparaat. Maak een nieuwe link op de desktop.";
/* No comment provided by engineer. */
"This setting applies to messages in your current chat profile **%@**." = "Deze instelling is van toepassing op berichten in je huidige chatprofiel **%@**.";
"This setting applies to messages in your current chat profile **%@**." = "Deze instelling is van toepassing op berichten in je huidige chat profiel **%@**.";
/* No comment provided by engineer. */
"Title" = "Titel";
@@ -4528,7 +4479,7 @@
"To record voice message please grant permission to use Microphone." = "Geef toestemming om de microfoon te gebruiken om een spraakbericht op te nemen.";
/* No comment provided by engineer. */
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "Om uw verborgen profiel te onthullen, voert u een volledig wachtwoord in een zoek veld in op de pagina **Uw chatprofielen**.";
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "Om uw verborgen profiel te onthullen, voert u een volledig wachtwoord in een zoek veld in op de pagina **Uw chat profielen**.";
/* No comment provided by engineer. */
"To support instant push notifications the chat database has to be migrated." = "Om directe push meldingen te ondersteunen, moet de chat database worden gemigreerd.";
@@ -4600,7 +4551,7 @@
"Unhide" = "zichtbaar maken";
/* No comment provided by engineer. */
"Unhide chat profile" = "Chatprofiel zichtbaar maken";
"Unhide chat profile" = "Chat profiel zichtbaar maken";
/* No comment provided by engineer. */
"Unhide profile" = "Profiel zichtbaar maken";
@@ -4623,7 +4574,7 @@
/* No comment provided by engineer. */
"unknown servers" = "onbekende relays";
/* alert title */
/* No comment provided by engineer. */
"Unknown servers!" = "Onbekende servers!";
/* No comment provided by engineer. */
@@ -4929,7 +4880,7 @@
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to file servers." = "Zonder Tor of VPN is uw IP-adres zichtbaar voor bestandsservers.";
/* alert message */
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." = "Zonder Tor of VPN zal uw IP-adres zichtbaar zijn voor deze XFTP-relays: %@.";
/* No comment provided by engineer. */
@@ -4966,7 +4917,7 @@
"You allow" = "Jij staat toe";
/* No comment provided by engineer. */
"You already have a chat profile with the same display name. Please choose another name." = "Je hebt al een chatprofiel met dezelfde weergave naam. Kies een andere naam.";
"You already have a chat profile with the same display name. Please choose another name." = "Je hebt al een chat profiel met dezelfde weergave naam. Kies een andere naam.";
/* No comment provided by engineer. */
"You are already connected to %@." = "U bent al verbonden met %@.";
@@ -5190,15 +5141,9 @@
/* No comment provided by engineer. */
"Your chat database is not encrypted - set passphrase to encrypt it." = "Uw chat database is niet versleuteld, stel een wachtwoord in om deze te versleutelen.";
/* alert title */
"Your chat preferences" = "Uw chat voorkeuren";
/* No comment provided by engineer. */
"Your chat profiles" = "Uw chat profielen";
/* No comment provided by engineer. */
"Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." = "Uw verbinding is verplaatst naar %@, maar er is een onverwachte fout opgetreden tijdens het omleiden naar het profiel.";
/* No comment provided by engineer. */
"Your contact sent a file that is larger than currently supported maximum size (%@)." = "Uw contact heeft een bestand verzonden dat groter is dan de momenteel ondersteunde maximale grootte (%@).";
@@ -5232,9 +5177,6 @@
/* No comment provided by engineer. */
"Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." = "Uw profiel wordt op uw apparaat opgeslagen en alleen gedeeld met uw contacten. SimpleX servers kunnen uw profiel niet zien.";
/* alert message */
"Your profile was changed. If you save it, the updated profile will be sent to all your contacts." = "Je profiel is gewijzigd. Als je het opslaat, wordt het bijgewerkte profiel naar al je contacten verzonden.";
/* No comment provided by engineer. */
"Your profile, contacts and delivered messages are stored on your device." = "Uw profiel, contacten en afgeleverde berichten worden op uw apparaat opgeslagen.";
+7 -8
View File
@@ -796,7 +796,7 @@
/* No comment provided by engineer. */
"Cannot forward message" = "Nie można przekazać wiadomości";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "Nie można odebrać pliku";
/* snd error text */
@@ -1629,8 +1629,7 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Obniż wersję i otwórz czat";
/* alert button
chat item action */
/* chat item action */
"Download" = "Pobierz";
/* No comment provided by engineer. */
@@ -1939,7 +1938,7 @@
/* No comment provided by engineer. */
"Error opening chat" = "Błąd otwierania czatu";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Błąd odbioru pliku";
/* No comment provided by engineer. */
@@ -3082,7 +3081,7 @@
/* feature offered item */
"offered %@: %@" = "zaoferował %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "Ok";
/* No comment provided by engineer. */
@@ -3906,7 +3905,7 @@
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "Wysyłaj do 100 ostatnich wiadomości do nowych członków.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "Nadawca anulował transfer pliku.";
/* No comment provided by engineer. */
@@ -4575,7 +4574,7 @@
/* No comment provided by engineer. */
"unknown servers" = "nieznane przekaźniki";
/* alert title */
/* No comment provided by engineer. */
"Unknown servers!" = "Nieznane serwery!";
/* No comment provided by engineer. */
@@ -4881,7 +4880,7 @@
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to file servers." = "Bez Tor lub VPN, Twój adres IP będzie widoczny do serwerów plików.";
/* alert message */
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." = "Bez Tor lub VPN, Twój adres IP będzie widoczny dla tych przekaźników XFTP: %@.";
/* No comment provided by engineer. */
+7 -8
View File
@@ -796,7 +796,7 @@
/* No comment provided by engineer. */
"Cannot forward message" = "Невозможно переслать сообщение";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "Невозможно получить файл";
/* snd error text */
@@ -1629,8 +1629,7 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Откатить версию и открыть чат";
/* alert button
chat item action */
/* chat item action */
"Download" = "Загрузить";
/* No comment provided by engineer. */
@@ -1939,7 +1938,7 @@
/* No comment provided by engineer. */
"Error opening chat" = "Ошибка доступа к чату";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Ошибка при получении файла";
/* No comment provided by engineer. */
@@ -3082,7 +3081,7 @@
/* feature offered item */
"offered %@: %@" = "предложил(a) %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "Ок";
/* No comment provided by engineer. */
@@ -3906,7 +3905,7 @@
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "Отправить до 100 последних сообщений новым членам.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "Отправитель отменил передачу файла.";
/* No comment provided by engineer. */
@@ -4575,7 +4574,7 @@
/* No comment provided by engineer. */
"unknown servers" = "неизвестные серверы";
/* alert title */
/* No comment provided by engineer. */
"Unknown servers!" = "Неизвестные серверы!";
/* No comment provided by engineer. */
@@ -4881,7 +4880,7 @@
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to file servers." = "Без Тора или ВПН, Ваш IP адрес будет доступен серверам файлов.";
/* alert message */
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." = "Без Тора или ВПН, Ваш IP адрес будет доступен этим серверам файлов: %@.";
/* No comment provided by engineer. */
+4 -4
View File
@@ -532,7 +532,7 @@
/* No comment provided by engineer. */
"Cannot access keychain to save database password" = "ไม่สามารถเข้าถึง keychain เพื่อบันทึกรหัสผ่านฐานข้อมูล";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "ไม่สามารถรับไฟล์ได้";
/* No comment provided by engineer. */
@@ -1308,7 +1308,7 @@
/* No comment provided by engineer. */
"Error loading %@ servers" = "โหลดเซิร์ฟเวอร์ %@ ผิดพลาด";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "เกิดข้อผิดพลาดในการรับไฟล์";
/* No comment provided by engineer. */
@@ -2097,7 +2097,7 @@
/* feature offered item */
"offered %@: %@" = "เสนอแล้ว %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "ตกลง";
/* No comment provided by engineer. */
@@ -2630,7 +2630,7 @@
/* No comment provided by engineer. */
"Send them from gallery or custom keyboards." = "ส่งจากแกลเลอรีหรือแป้นพิมพ์แบบกำหนดเอง";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "ผู้ส่งยกเลิกการโอนไฟล์";
/* No comment provided by engineer. */
+7 -8
View File
@@ -715,7 +715,7 @@
/* No comment provided by engineer. */
"Cannot access keychain to save database password" = "Veritabanı şifresini kaydetmek için Anahtar Zinciri'ne erişilemiyor";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "Dosya alınamıyor";
/* snd error text */
@@ -1419,8 +1419,7 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Sürüm düşür ve sohbeti aç";
/* alert button
chat item action */
/* chat item action */
"Download" = "İndir";
/* No comment provided by engineer. */
@@ -1708,7 +1707,7 @@
/* No comment provided by engineer. */
"Error opening chat" = "Sohbeti açarken sorun oluştu";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Dosya alınırken sorun oluştu";
/* No comment provided by engineer. */
@@ -2728,7 +2727,7 @@
/* feature offered item */
"offered %@: %@" = "%1$@: %2$@ teklif etti";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "Tamam";
/* No comment provided by engineer. */
@@ -3432,7 +3431,7 @@
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "Yeni üyelere 100 adete kadar son mesajları gönderin.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "Gönderici dosya gönderimini iptal etti.";
/* No comment provided by engineer. */
@@ -3987,7 +3986,7 @@
/* No comment provided by engineer. */
"unknown servers" = "bilinmeyen yönlendiriciler";
/* alert title */
/* No comment provided by engineer. */
"Unknown servers!" = "Bilinmeyen sunucular!";
/* No comment provided by engineer. */
@@ -4263,7 +4262,7 @@
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to file servers." = "Tor veya VPN olmadan, IP adresiniz dosya sunucularına görülebilir.";
/* alert message */
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." = "Tor veya VPN olmadan, IP adresiniz bu XFTP aktarıcıları tarafından görülebilir: %@.";
/* No comment provided by engineer. */
+7 -8
View File
@@ -796,7 +796,7 @@
/* No comment provided by engineer. */
"Cannot forward message" = "Неможливо переслати повідомлення";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "Не вдається отримати файл";
/* snd error text */
@@ -1629,8 +1629,7 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "Пониження та відкритий чат";
/* alert button
chat item action */
/* chat item action */
"Download" = "Завантажити";
/* No comment provided by engineer. */
@@ -1939,7 +1938,7 @@
/* No comment provided by engineer. */
"Error opening chat" = "Помилка відкриття чату";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "Помилка отримання файлу";
/* No comment provided by engineer. */
@@ -3082,7 +3081,7 @@
/* feature offered item */
"offered %@: %@" = "запропонував %1$@: %2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "Гаразд";
/* No comment provided by engineer. */
@@ -3906,7 +3905,7 @@
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "Надішліть до 100 останніх повідомлень новим користувачам.";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "Відправник скасував передачу файлу.";
/* No comment provided by engineer. */
@@ -4575,7 +4574,7 @@
/* No comment provided by engineer. */
"unknown servers" = "невідомі реле";
/* alert title */
/* No comment provided by engineer. */
"Unknown servers!" = "Невідомі сервери!";
/* No comment provided by engineer. */
@@ -4881,7 +4880,7 @@
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to file servers." = "Без Tor або VPN ваша IP-адреса буде видимою для файлових серверів.";
/* alert message */
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." = "Без Tor або VPN ваша IP-адреса буде видимою для цих XFTP-ретрансляторів: %@.";
/* No comment provided by engineer. */
+8 -9
View File
@@ -796,7 +796,7 @@
/* No comment provided by engineer. */
"Cannot forward message" = "无法转发消息";
/* alert title */
/* No comment provided by engineer. */
"Cannot receive file" = "无法接收文件";
/* snd error text */
@@ -1629,8 +1629,7 @@
/* No comment provided by engineer. */
"Downgrade and open chat" = "降级并打开聊天";
/* alert button
chat item action */
/* chat item action */
"Download" = "下载";
/* No comment provided by engineer. */
@@ -1939,7 +1938,7 @@
/* No comment provided by engineer. */
"Error opening chat" = "打开聊天时出错";
/* alert title */
/* No comment provided by engineer. */
"Error receiving file" = "接收文件错误";
/* No comment provided by engineer. */
@@ -3082,7 +3081,7 @@
/* feature offered item */
"offered %@: %@" = "已提供 %1$@%2$@";
/* alert button */
/* No comment provided by engineer. */
"Ok" = "好的";
/* No comment provided by engineer. */
@@ -3521,7 +3520,7 @@
"Receiving via" = "接收通过";
/* No comment provided by engineer. */
"Recent history and improved [directory bot](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion)." = "最近的历史记录和改进的 [目录机器人](simplex/contact#/v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion.";
"Recent history and improved [directory bot](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion)." = "最近的历史记录和改进的 [目录机器人](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion.";
/* No comment provided by engineer. */
"Recipient(s) can't see who this message is from." = "收件人看不到这条消息来自何人。";
@@ -3906,7 +3905,7 @@
/* No comment provided by engineer. */
"Send up to 100 last messages to new members." = "给新成员发送最多 100 条历史消息。";
/* alert message */
/* No comment provided by engineer. */
"Sender cancelled file transfer." = "发送人已取消文件传输。";
/* No comment provided by engineer. */
@@ -4575,7 +4574,7 @@
/* No comment provided by engineer. */
"unknown servers" = "未知服务器";
/* alert title */
/* No comment provided by engineer. */
"Unknown servers!" = "未知服务器!";
/* No comment provided by engineer. */
@@ -4881,7 +4880,7 @@
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to file servers." = "如果没有 Tor 或 VPN,您的 IP 地址将对文件服务器可见。";
/* alert message */
/* No comment provided by engineer. */
"Without Tor or VPN, your IP address will be visible to these XFTP relays: %@." = "如果没有 Tor 或 VPN,您的 IP 地址将对以下 XFTP 中继可见:%@。";
/* No comment provided by engineer. */
@@ -2,7 +2,6 @@ package chat.simplex.app
import android.app.*
import android.content.*
import android.content.pm.PackageManager
import android.content.pm.ServiceInfo
import android.graphics.Bitmap
import android.graphics.BitmapFactory
@@ -84,7 +83,7 @@ class CallService: Service() {
generalGetString(MR.strings.notification_preview_somebody)
else
call?.contact?.profile?.displayName ?: ""
val text = generalGetString(if (call?.hasVideo == true) MR.strings.call_service_notification_video_call else MR.strings.call_service_notification_audio_call)
val text = generalGetString(if (call?.supportsVideo() == true) MR.strings.call_service_notification_video_call else MR.strings.call_service_notification_audio_call)
val image = call?.contact?.image
val largeIcon = if (image == null || previewMode == NotificationPreviewMode.HIDDEN.name)
BitmapFactory.decodeResource(resources, R.drawable.icon)
@@ -106,7 +105,7 @@ class CallService: Service() {
0
}
} else if (Build.VERSION.SDK_INT >= 30) {
if (call.hasVideo && ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
if (call.supportsVideo()) {
ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE or ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
} else {
ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
@@ -150,9 +150,12 @@ fun processIntent(intent: Intent?) {
"android.intent.action.VIEW" -> {
val uri = intent.data
if (uri != null) {
chatModel.appOpenUrl.value = null to uri.toString()
} else {
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_parsing_uri_title), generalGetString(MR.strings.error_parsing_uri_desc))
val transformedUri = uri.toURIOrNull()
if (transformedUri != null) {
chatModel.appOpenUrl.value = null to transformedUri
} else {
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_parsing_uri_title), generalGetString(MR.strings.error_parsing_uri_desc))
}
}
}
}
@@ -287,23 +287,13 @@ class SimplexApp: Application(), LifecycleEventObserver {
// Blend status bar color to the animated color
val colors = CurrentColors.value.colors
val baseBackgroundColor = if (toolbarOnTop) colors.background.mixWith(colors.onBackground, 0.97f) else colors.background
var statusBar = baseBackgroundColor.mixWith(drawerShadingColor.copy(1f), 1 - drawerShadingColor.alpha).toArgb()
var statusBarLight = isLight
// SimplexGreen while in call
if (window.statusBarColor == SimplexGreen.toArgb()) {
statusBarColorAfterCall.intValue = statusBar
statusBar = SimplexGreen.toArgb()
statusBarLight = false
}
window.statusBarColor = statusBar
window.statusBarColor = baseBackgroundColor.mixWith(drawerShadingColor.copy(1f), 1 - drawerShadingColor.alpha).toArgb()
val navBar = navBarColor.toArgb()
if (windowInsetController?.isAppearanceLightStatusBars != statusBarLight) {
windowInsetController?.isAppearanceLightStatusBars = statusBarLight
}
if (window.navigationBarColor != navBar) {
window.navigationBarColor = navBar
}
if (windowInsetController?.isAppearanceLightNavigationBars != isLight) {
windowInsetController?.isAppearanceLightNavigationBars = isLight
}
@@ -323,13 +313,11 @@ class SimplexApp: Application(), LifecycleEventObserver {
backgroundColor
}
}).toArgb()
var statusBarLight = isLight
// SimplexGreen while in call
if (window.statusBarColor == SimplexGreen.toArgb()) {
statusBarColorAfterCall.intValue = statusBar
statusBar = SimplexGreen.toArgb()
statusBarLight = false
}
val navBar = (if (hasBottom && appPrefs.onboardingStage.get() == OnboardingStage.OnboardingComplete) {
backgroundColor.mixWith(CurrentColors.value.colors.onBackground, 0.97f)
@@ -339,8 +327,8 @@ class SimplexApp: Application(), LifecycleEventObserver {
if (window.statusBarColor != statusBar) {
window.statusBarColor = statusBar
}
if (windowInsetController?.isAppearanceLightStatusBars != statusBarLight) {
windowInsetController?.isAppearanceLightStatusBars = statusBarLight
if (windowInsetController?.isAppearanceLightStatusBars != isLight) {
windowInsetController?.isAppearanceLightStatusBars = isLight
}
if (window.navigationBarColor != navBar) {
window.navigationBarColor = navBar
@@ -116,7 +116,7 @@ class CallActivity: ComponentActivity(), ServiceConnection {
private fun hasGrantedPermissions(): Boolean {
val grantedAudio = ContextCompat.checkSelfPermission(this, android.Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
val grantedCamera = !callHasVideo() || ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
val grantedCamera = !callSupportsVideo() || ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
return grantedAudio && grantedCamera
}
@@ -124,7 +124,7 @@ class CallActivity: ComponentActivity(), ServiceConnection {
override fun onBackPressed() {
if (isOnLockScreenNow()) {
super.onBackPressed()
} else if (!hasGrantedPermissions() && !callHasVideo()) {
} else if (!hasGrantedPermissions() && !callSupportsVideo()) {
val call = m.activeCall.value
if (call != null) {
withBGApi { chatModel.callManager.endCall(call) }
@@ -142,7 +142,7 @@ class CallActivity: ComponentActivity(), ServiceConnection {
override fun onUserLeaveHint() {
super.onUserLeaveHint()
// On Android 12+ PiP is enabled automatically when a user hides the app
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R && callHasVideo() && platform.androidPictureInPictureAllowed()) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R && callSupportsVideo() && platform.androidPictureInPictureAllowed()) {
enterPictureInPictureMode()
}
}
@@ -198,7 +198,7 @@ class CallActivity: ComponentActivity(), ServiceConnection {
fun getKeyguardManager(context: Context): KeyguardManager =
context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
private fun callHasVideo() = m.activeCall.value?.hasVideo == true || m.activeCallInvitation.value?.callType?.media == CallMediaType.Video
private fun callSupportsVideo() = m.activeCall.value?.supportsVideo() == true || m.activeCallInvitation.value?.callType?.media == CallMediaType.Video
@Composable
fun CallActivityView() {
@@ -212,7 +212,7 @@ fun CallActivityView() {
.collect { collapsed ->
when {
collapsed -> {
if (!platform.androidPictureInPictureAllowed() || !callHasVideo()) {
if (!platform.androidPictureInPictureAllowed() || !callSupportsVideo()) {
activity.moveTaskToBack(true)
activity.startActivity(Intent(activity, MainActivity::class.java))
} else if (!activity.isInPictureInPictureMode && activity.lifecycle.currentState == Lifecycle.State.RESUMED) {
@@ -221,7 +221,7 @@ fun CallActivityView() {
activity.enterPictureInPictureMode()
}
}
callHasVideo() && !platform.androidPictureInPictureAllowed() -> {
callSupportsVideo() && !platform.androidPictureInPictureAllowed() -> {
// PiP disabled by user
platform.androidStartCallActivity(false)
}
@@ -242,43 +242,28 @@ fun CallActivityView() {
Box(Modifier.background(Color.Black)) {
if (call != null) {
val permissionsState = rememberMultiplePermissionsState(
permissions = if (callHasVideo()) {
permissions = if (callSupportsVideo()) {
listOf(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)
} else {
listOf(Manifest.permission.RECORD_AUDIO)
}
)
// callState == connected is needed in a situation when a peer enabled camera in audio call while a user didn't grant camera permission yet,
// so no need to hide active call view in this case
if (permissionsState.allPermissionsGranted || call.callState == CallState.Connected) {
if (permissionsState.allPermissionsGranted) {
ActiveCallView()
LaunchedEffect(Unit) {
activity.startServiceAndBind()
}
}
if ((!permissionsState.allPermissionsGranted && call.callState != CallState.Connected) || call.wantsToEnableCamera) {
CallPermissionsView(remember { m.activeCallViewIsCollapsed }.value, callHasVideo() || call.wantsToEnableCamera) {
} else {
CallPermissionsView(remember { m.activeCallViewIsCollapsed }.value, callSupportsVideo()) {
withBGApi { chatModel.callManager.endCall(call) }
}
val cameraAndMicPermissions = rememberMultiplePermissionsState(permissions = listOf(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO))
DisposableEffect(cameraAndMicPermissions.allPermissionsGranted) {
onDispose {
if (call.wantsToEnableCamera && cameraAndMicPermissions.allPermissionsGranted) {
val activeCall = chatModel.activeCall.value
if (activeCall != null && activeCall.contact.apiId == call.contact.apiId) {
chatModel.activeCall.value = activeCall.copy(wantsToEnableCamera = false)
chatModel.callCommand.add(WCallCommand.Media(CallMediaSource.Camera, enable = true))
}
}
}
}
}
val view = LocalView.current
if (callHasVideo()) {
if (callSupportsVideo()) {
val scope = rememberCoroutineScope()
LaunchedEffect(Unit) {
scope.launch {
activity.setPipParams(callHasVideo(), viewRatio = Rational(view.width, view.height))
activity.setPipParams(callSupportsVideo(), viewRatio = Rational(view.width, view.height))
activity.trackPipAnimationHintView(view)
}
}
@@ -47,7 +47,7 @@ class PostSCallAudioDeviceManager: CallAudioDeviceManagerInterface {
Log.d(TAG, "Added audio devices2: ${devices.value.map { it.type }}")
if (devices.value.size - oldDevices.size > 0) {
selectLastExternalDeviceOrDefault(chatModel.activeCall.value?.hasVideo == true, false)
selectLastExternalDeviceOrDefault(chatModel.activeCall.value?.supportsVideo() == true, false)
}
}
@@ -116,14 +116,14 @@ class PreSCallAudioDeviceManager: CallAudioDeviceManagerInterface {
Log.d(TAG, "Added audio devices: ${addedDevices.map { it.type }}")
super.onAudioDevicesAdded(addedDevices)
devices.value = am.getDevices(AudioManager.GET_DEVICES_OUTPUTS).filter { it.hasSupportedType() }.excludeSameType().excludeEarpieceIfWired()
selectLastExternalDeviceOrDefault(chatModel.activeCall.value?.hasVideo == true, false)
selectLastExternalDeviceOrDefault(chatModel.activeCall.value?.supportsVideo() == true, false)
}
override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>) {
Log.d(TAG, "Removed audio devices: ${removedDevices.map { it.type }}")
super.onAudioDevicesRemoved(removedDevices)
devices.value = am.getDevices(AudioManager.GET_DEVICES_OUTPUTS).filter { it.hasSupportedType() }.excludeSameType().excludeEarpieceIfWired()
selectLastExternalDeviceOrDefault(chatModel.activeCall.value?.hasVideo == true, true)
selectLastExternalDeviceOrDefault(chatModel.activeCall.value?.supportsVideo() == true, true)
}
}
@@ -7,7 +7,6 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.content.*
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.media.*
import android.os.Build
import android.os.PowerManager
@@ -17,12 +16,9 @@ import android.view.ViewGroup
import android.webkit.*
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.*
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.snapshots.SnapshotStateList
@@ -31,13 +27,12 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.*
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.content.ContextCompat
import androidx.lifecycle.*
import androidx.webkit.WebViewAssetLoader
import androidx.webkit.WebViewClientCompat
@@ -124,26 +119,26 @@ actual fun ActiveCallView() {
val callRh = call.remoteHostId
when (val r = apiMsg.resp) {
is WCallResponse.Capabilities -> withBGApi {
val callType = CallType(call.initialCallType, r.capabilities)
val callType = CallType(call.localMedia, r.capabilities)
chatModel.controller.apiSendCallInvitation(callRh, call.contact, callType)
updateActiveCall(call) { it.copy(callState = CallState.InvitationSent, localCapabilities = r.capabilities) }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
// Starting is delayed to make Android <= 11 working good with Bluetooth
callAudioDeviceManager.start()
} else {
callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.hasVideo, true)
callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.supportsVideo(), true)
}
CallSoundsPlayer.startConnectingCallSound(scope)
activeCallWaitDeliveryReceipt(scope)
}
is WCallResponse.Offer -> withBGApi {
chatModel.controller.apiSendCallOffer(callRh, call.contact, r.offer, r.iceCandidates, call.initialCallType, r.capabilities)
chatModel.controller.apiSendCallOffer(callRh, call.contact, r.offer, r.iceCandidates, call.localMedia, r.capabilities)
updateActiveCall(call) { it.copy(callState = CallState.OfferSent, localCapabilities = r.capabilities) }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
// Starting is delayed to make Android <= 11 working good with Bluetooth
callAudioDeviceManager.start()
} else {
callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.hasVideo, true)
callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.supportsVideo(), true)
}
}
is WCallResponse.Answer -> withBGApi {
@@ -167,17 +162,6 @@ actual fun ActiveCallView() {
is WCallResponse.Connected -> {
updateActiveCall(call) { it.copy(callState = CallState.Connected, connectionInfo = r.connectionInfo) }
}
is WCallResponse.PeerMedia -> {
updateActiveCall(call) {
val sources = it.peerMediaSources
when (r.source) {
CallMediaSource.Mic -> it.copy(peerMediaSources = sources.copy(mic = r.enabled))
CallMediaSource.Camera -> it.copy(peerMediaSources = sources.copy(camera = r.enabled))
CallMediaSource.ScreenAudio -> it.copy(peerMediaSources = sources.copy(screenAudio = r.enabled))
CallMediaSource.ScreenVideo -> it.copy(peerMediaSources = sources.copy(screenVideo = r.enabled))
}
}
}
is WCallResponse.End -> {
withBGApi { chatModel.callManager.endCall(call) }
}
@@ -190,19 +174,16 @@ actual fun ActiveCallView() {
updateActiveCall(call) { it.copy(callState = CallState.Negotiated) }
is WCallCommand.Media -> {
updateActiveCall(call) {
val sources = it.localMediaSources
when (cmd.source) {
CallMediaSource.Mic -> it.copy(localMediaSources = sources.copy(mic = cmd.enable))
CallMediaSource.Camera -> it.copy(localMediaSources = sources.copy(camera = cmd.enable))
CallMediaSource.ScreenAudio -> it.copy(localMediaSources = sources.copy(screenAudio = cmd.enable))
CallMediaSource.ScreenVideo -> it.copy(localMediaSources = sources.copy(screenVideo = cmd.enable))
when (cmd.media) {
CallMediaType.Video -> it.copy(videoEnabled = cmd.enable)
CallMediaType.Audio -> it.copy(audioEnabled = cmd.enable)
}
}
}
is WCallCommand.Camera -> {
updateActiveCall(call) { it.copy(localCamera = cmd.camera) }
if (!call.localMediaSources.mic) {
chatModel.callCommand.add(WCallCommand.Media(CallMediaSource.Mic, enable = false))
if (!call.audioEnabled) {
chatModel.callCommand.add(WCallCommand.Media(CallMediaType.Audio, enable = false))
}
}
is WCallCommand.End -> {
@@ -219,6 +200,7 @@ actual fun ActiveCallView() {
val showOverlay = when {
call == null -> false
!platform.androidPictureInPictureAllowed() -> true
!call.supportsVideo() -> true
!chatModel.activeCallViewIsCollapsed.value -> true
else -> false
}
@@ -226,11 +208,6 @@ actual fun ActiveCallView() {
ActiveCallOverlay(call, chatModel, callAudioDeviceManager)
}
}
KeyChangeEffect(call?.hasVideo) {
if (call != null) {
callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.hasVideo, true)
}
}
val context = LocalContext.current
DisposableEffect(Unit) {
val activity = context as? Activity ?: return@DisposableEffect onDispose {}
@@ -260,15 +237,9 @@ private fun ActiveCallOverlay(call: Call, chatModel: ChatModel, callAudioDeviceM
devices = remember { callAudioDeviceManager.devices }.value,
currentDevice = remember { callAudioDeviceManager.currentDevice },
dismiss = { withBGApi { chatModel.callManager.endCall(call) } },
toggleAudio = { chatModel.callCommand.add(WCallCommand.Media(CallMediaSource.Mic, enable = !call.localMediaSources.mic)) },
toggleAudio = { chatModel.callCommand.add(WCallCommand.Media(CallMediaType.Audio, enable = !call.audioEnabled)) },
selectDevice = { callAudioDeviceManager.selectDevice(it.id) },
toggleVideo = {
if (ContextCompat.checkSelfPermission(androidAppContext, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
chatModel.callCommand.add(WCallCommand.Media(CallMediaSource.Camera, enable = !call.localMediaSources.camera))
} else {
updateActiveCall(call) { it.copy(wantsToEnableCamera = true) }
}
},
toggleVideo = { chatModel.callCommand.add(WCallCommand.Media(CallMediaType.Video, enable = !call.videoEnabled)) },
toggleSound = {
val enableSpeaker = callAudioDeviceManager.currentDevice.value?.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
val preferredInternalDevice = callAudioDeviceManager.devices.value.firstOrNull { it.type == if (enableSpeaker) AudioDeviceInfo.TYPE_BUILTIN_SPEAKER else AudioDeviceInfo.TYPE_BUILTIN_EARPIECE }
@@ -322,30 +293,30 @@ private fun ActiveCallOverlayLayout(
flipCamera: () -> Unit
) {
Column {
val media = call.peerMedia ?: call.localMedia
CloseSheetBar({ chatModel.activeCallViewIsCollapsed.value = true }, true, tintColor = Color(0xFFFFFFD8)) {
if (call.hasVideo) {
if (media == CallMediaType.Video) {
Text(call.contact.chatViewName, Modifier.fillMaxWidth().padding(end = DEFAULT_PADDING), color = Color(0xFFFFFFD8), style = MaterialTheme.typography.h2, overflow = TextOverflow.Ellipsis, maxLines = 1)
}
}
Column(Modifier.padding(horizontal = DEFAULT_PADDING)) {
@Composable
fun SelectSoundDevice(size: Dp) {
fun SelectSoundDevice() {
if (devices.size == 2 &&
devices.all { it.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE || it.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER } ||
currentDevice.value == null ||
devices.none { it.id == currentDevice.value?.id }
) {
val isSpeaker = currentDevice.value?.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
ToggleSoundButton(enabled, isSpeaker, !call.peerMediaSources.mic, toggleSound, size = size)
ToggleSoundButton(call, enabled, isSpeaker, toggleSound)
} else {
ExposedDropDownSettingWithIcon(
devices.map { Triple(it, if (call.peerMediaSources.mic) it.icon else MR.images.ic_volume_off, if (it.name != null) generalGetString(it.name!!) else it.productName.toString()) },
devices.map { Triple(it, it.icon, if (it.name != null) generalGetString(it.name!!) else it.productName.toString()) },
currentDevice,
fontSize = 18.sp,
boxSize = size,
iconSize = 40.dp,
listIconSize = 30.dp,
iconColor = Color(0xFFFFFFD8),
background = controlButtonsBackground(),
minWidth = 300.dp,
onSelected = {
if (it != null) {
@@ -356,9 +327,29 @@ private fun ActiveCallOverlayLayout(
}
}
when (call.hasVideo) {
true -> VideoCallInfoView(call)
false -> {
when (media) {
CallMediaType.Video -> {
VideoCallInfoView(call)
Box(Modifier.fillMaxWidth().fillMaxHeight().weight(1f), contentAlignment = Alignment.BottomCenter) {
DisabledBackgroundCallsButton()
}
Row(Modifier.fillMaxWidth().padding(horizontal = 6.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
ToggleAudioButton(call, enabled, toggleAudio)
SelectSoundDevice()
IconButton(onClick = dismiss, enabled = enabled) {
Icon(painterResource(MR.images.ic_call_end_filled), stringResource(MR.strings.icon_descr_hang_up), tint = if (enabled) Color.Red else MaterialTheme.colors.secondary, modifier = Modifier.size(64.dp))
}
if (call.videoEnabled) {
ControlButton(call, painterResource(MR.images.ic_flip_camera_android_filled), MR.strings.icon_descr_flip_camera, enabled, flipCamera)
ControlButton(call, painterResource(MR.images.ic_videocam_filled), MR.strings.icon_descr_video_off, enabled, toggleVideo)
} else {
Spacer(Modifier.size(48.dp))
ControlButton(call, painterResource(MR.images.ic_videocam_off), MR.strings.icon_descr_video_on, enabled, toggleVideo)
}
}
}
CallMediaType.Audio -> {
Spacer(Modifier.fillMaxHeight().weight(1f))
Column(
Modifier.fillMaxWidth(),
@@ -368,26 +359,23 @@ private fun ActiveCallOverlayLayout(
ProfileImage(size = 192.dp, image = call.contact.profile.image)
AudioCallInfoView(call)
}
}
}
Box(Modifier.fillMaxWidth().fillMaxHeight().weight(1f), contentAlignment = Alignment.BottomCenter) {
DisabledBackgroundCallsButton()
}
BoxWithConstraints(Modifier.padding(start = 6.dp, end = 6.dp, bottom = DEFAULT_PADDING).align(Alignment.CenterHorizontally)) {
val size = ((maxWidth - DEFAULT_PADDING_HALF * 4) / 5).coerceIn(0.dp, 60.dp)
// limiting max width for tablets/wide screens, will be displayed in the center
val padding = ((min(420.dp, maxWidth) - size * 5) / 4).coerceAtLeast(0.dp)
Row(horizontalArrangement = Arrangement.spacedBy(padding), verticalAlignment = Alignment.CenterVertically) {
ToggleMicButton(call, enabled, toggleAudio, size = size)
SelectSoundDevice(size = size)
ControlButton(painterResource(MR.images.ic_call_end_filled), MR.strings.icon_descr_hang_up, enabled = enabled, dismiss, background = Color.Red, size = size, iconPaddingPercent = 0.166f)
if (call.localMediaSources.camera) {
ControlButton(painterResource(MR.images.ic_flip_camera_android_filled), MR.strings.icon_descr_flip_camera, enabled, flipCamera, size = size)
ControlButton(painterResource(MR.images.ic_videocam_filled), MR.strings.icon_descr_video_off, enabled, toggleVideo, size = size)
} else {
Spacer(Modifier.size(size))
ControlButton(painterResource(MR.images.ic_videocam_off), MR.strings.icon_descr_video_on, enabled, toggleVideo, size = size)
Box(Modifier.fillMaxWidth().fillMaxHeight().weight(1f), contentAlignment = Alignment.BottomCenter) {
DisabledBackgroundCallsButton()
}
Box(Modifier.fillMaxWidth().padding(bottom = DEFAULT_BOTTOM_PADDING), contentAlignment = Alignment.CenterStart) {
Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
IconButton(onClick = dismiss, enabled = enabled) {
Icon(painterResource(MR.images.ic_call_end_filled), stringResource(MR.strings.icon_descr_hang_up), tint = if (enabled) Color.Red else MaterialTheme.colors.secondary, modifier = Modifier.size(64.dp))
}
}
Box(Modifier.padding(start = 32.dp)) {
ToggleAudioButton(call, enabled, toggleAudio)
}
Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.CenterEnd) {
Box(Modifier.padding(end = 32.dp)) {
SelectSoundDevice()
}
}
}
}
}
@@ -396,51 +384,33 @@ private fun ActiveCallOverlayLayout(
}
@Composable
private fun ControlButton(icon: Painter, iconText: StringResource, enabled: Boolean = true, action: () -> Unit, background: Color = controlButtonsBackground(), size: Dp, iconPaddingPercent: Float = 0.2f) {
ControlButtonWrap(enabled, action, background, size) {
Icon(icon, stringResource(iconText), tint = if (enabled) Color(0xFFFFFFD8) else MaterialTheme.colors.secondary, modifier = Modifier.padding(size * iconPaddingPercent).fillMaxSize())
}
}
@Composable
private fun ControlButtonWrap(enabled: Boolean = true, action: () -> Unit, background: Color = controlButtonsBackground(), size: Dp, content: @Composable () -> Unit) {
Box(
Modifier
.background(background, CircleShape)
.size(size)
.clickable(
onClick = action,
role = Role.Button,
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = false, radius = size / 2, color = background.lighter(0.1f)),
enabled = enabled
),
contentAlignment = Alignment.Center
) {
content()
}
}
@Composable
private fun ToggleMicButton(call: Call, enabled: Boolean = true, toggleAudio: () -> Unit, size: Dp) {
if (call.localMediaSources.mic) {
ControlButton(painterResource(MR.images.ic_mic), MR.strings.icon_descr_audio_off, enabled, toggleAudio, size = size)
private fun ControlButton(call: Call, icon: Painter, iconText: StringResource, enabled: Boolean = true, action: () -> Unit) {
if (call.hasMedia) {
IconButton(onClick = action, enabled = enabled) {
Icon(icon, stringResource(iconText), tint = if (enabled) Color(0xFFFFFFD8) else MaterialTheme.colors.secondary, modifier = Modifier.size(40.dp))
}
} else {
ControlButton(painterResource(MR.images.ic_mic_off), MR.strings.icon_descr_audio_on, enabled, toggleAudio, size = size)
Spacer(Modifier.size(40.dp))
}
}
@Composable
private fun ToggleSoundButton(enabled: Boolean, speaker: Boolean, muted: Boolean, toggleSound: () -> Unit, size: Dp) {
when {
muted -> ControlButton(painterResource(MR.images.ic_volume_off), MR.strings.icon_descr_sound_muted, enabled, toggleSound, size = size)
speaker -> ControlButton(painterResource(MR.images.ic_volume_up), MR.strings.icon_descr_speaker_off, enabled, toggleSound, size = size)
else -> ControlButton(painterResource(MR.images.ic_volume_down), MR.strings.icon_descr_speaker_on, enabled, toggleSound, size = size)
private fun ToggleAudioButton(call: Call, enabled: Boolean = true, toggleAudio: () -> Unit) {
if (call.audioEnabled) {
ControlButton(call, painterResource(MR.images.ic_mic), MR.strings.icon_descr_audio_off, enabled, toggleAudio)
} else {
ControlButton(call, painterResource(MR.images.ic_mic_off), MR.strings.icon_descr_audio_on, enabled, toggleAudio)
}
}
@Composable
fun controlButtonsBackground(): Color = if (chatModel.activeCall.value?.peerMediaSources?.hasVideo == true) Color.Black.copy(0.2f) else Color.White.copy(0.2f)
private fun ToggleSoundButton(call: Call, enabled: Boolean, speaker: Boolean, toggleSound: () -> Unit) {
if (speaker) {
ControlButton(call, painterResource(MR.images.ic_volume_up), MR.strings.icon_descr_speaker_off, enabled, toggleSound)
} else {
ControlButton(call, painterResource(MR.images.ic_volume_down), MR.strings.icon_descr_speaker_on, enabled, toggleSound)
}
}
@Composable
fun AudioCallInfoView(call: Call) {
@@ -583,39 +553,38 @@ fun CallPermissionsView(pipActive: Boolean, hasVideo: Boolean, cancel: () -> Uni
}
}
} else {
ModalView(background = Color.Black, showClose = false, close = {}) {
ColumnWithScrollBar(Modifier.fillMaxSize()) {
AppBarTitle(stringResource(MR.strings.permissions_required))
Spacer(Modifier.weight(1f))
val onClick = {
if (permissionsState.shouldShowRationale) {
context.showAllowPermissionInSettingsAlert()
} else {
permissionsState.launchMultiplePermissionRequestWithFallback(buttonEnabled, context::showAllowPermissionInSettingsAlert)
}
}
Text(stringResource(MR.strings.permissions_grant), Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING), textAlign = TextAlign.Center, color = Color(0xFFFFFFD8))
SectionSpacer()
SectionView {
Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
val text = if (hasVideo && audioPermission.status is PermissionStatus.Denied && cameraPermission.status is PermissionStatus.Denied) {
stringResource(MR.strings.permissions_camera_and_record_audio)
} else if (audioPermission.status is PermissionStatus.Denied) {
stringResource(MR.strings.permissions_record_audio)
} else if (hasVideo && cameraPermission.status is PermissionStatus.Denied) {
stringResource(MR.strings.permissions_camera)
} else null
if (text != null) {
GrantPermissionButton(text, buttonEnabled.value, onClick)
}
}
}
ColumnWithScrollBar(Modifier.fillMaxSize()) {
Spacer(Modifier.height(AppBarHeight * fontSizeSqrtMultiplier))
Spacer(Modifier.weight(1f))
Box(Modifier.fillMaxWidth().padding(bottom = DEFAULT_PADDING), contentAlignment = Alignment.Center) {
SimpleButtonFrame(cancel, Modifier.height(60.dp)) {
Text(stringResource(MR.strings.call_service_notification_end_call), fontSize = 20.sp, color = Color(0xFFFFFFD8))
}
AppBarTitle(stringResource(MR.strings.permissions_required))
Spacer(Modifier.weight(1f))
val onClick = {
if (permissionsState.shouldShowRationale) {
context.showAllowPermissionInSettingsAlert()
} else {
permissionsState.launchMultiplePermissionRequestWithFallback(buttonEnabled, context::showAllowPermissionInSettingsAlert)
}
}
Text(stringResource(MR.strings.permissions_grant), Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING), textAlign = TextAlign.Center, color = Color(0xFFFFFFD8))
SectionSpacer()
SectionView {
Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
val text = if (hasVideo && audioPermission.status is PermissionStatus.Denied && cameraPermission.status is PermissionStatus.Denied) {
stringResource(MR.strings.permissions_camera_and_record_audio)
} else if (audioPermission.status is PermissionStatus.Denied) {
stringResource(MR.strings.permissions_record_audio)
} else if (hasVideo && cameraPermission.status is PermissionStatus.Denied) {
stringResource(MR.strings.permissions_camera)
} else ""
GrantPermissionButton(text, buttonEnabled.value, onClick)
}
}
Spacer(Modifier.weight(1f))
Box(Modifier.fillMaxWidth().padding(bottom = if (hasVideo) 0.dp else DEFAULT_BOTTOM_PADDING), contentAlignment = Alignment.Center) {
SimpleButtonFrame(cancel, Modifier.height(64.dp)) {
Text(stringResource(MR.strings.call_service_notification_end_call), fontSize = 20.sp, color = Color(0xFFFFFFD8))
}
}
}
@@ -799,8 +768,8 @@ fun PreviewActiveCallOverlayVideo() {
userProfile = Profile.sampleData,
contact = Contact.sampleData,
callState = CallState.Negotiated,
initialCallType = CallMediaType.Video,
peerMediaSources = CallMediaSources(),
localMedia = CallMediaType.Video,
peerMedia = CallMediaType.Video,
callUUID = "",
connectionInfo = ConnectionInfo(
RTCIceCandidate(RTCIceCandidateType.Host, "tcp"),
@@ -829,8 +798,8 @@ fun PreviewActiveCallOverlayAudio() {
userProfile = Profile.sampleData,
contact = Contact.sampleData,
callState = CallState.Negotiated,
initialCallType = CallMediaType.Audio,
peerMediaSources = CallMediaSources(),
localMedia = CallMediaType.Audio,
peerMedia = CallMediaType.Audio,
callUUID = "",
connectionInfo = ConnectionInfo(
RTCIceCandidate(RTCIceCandidateType.Host, "udp"),
@@ -54,7 +54,8 @@ actual fun ActiveCallInteractiveArea(call: Call) {
.align(Alignment.BottomCenter),
contentAlignment = Alignment.Center
) {
if (call.hasVideo) {
val media = call.peerMedia ?: call.localMedia
if (media == CallMediaType.Video) {
Icon(painterResource(MR.images.ic_videocam_filled), null, Modifier.size(27.dp).offset(x = 2.5.dp, y = 2.dp), tint = Color.White)
} else {
Icon(painterResource(MR.images.ic_call_filled), null, Modifier.size(27.dp).offset(x = -0.5.dp, y = 2.dp), tint = Color.White)
@@ -5,19 +5,14 @@ import androidx.compose.foundation.*
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.DrawerDefaults.ScrimOpacity
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.*
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.*
import chat.simplex.common.model.ChatController.appPrefs
import chat.simplex.common.model.User
@@ -26,101 +21,95 @@ import chat.simplex.common.platform.*
import chat.simplex.common.ui.theme.*
import chat.simplex.common.views.helpers.*
import chat.simplex.common.views.onboarding.OnboardingStage
import chat.simplex.res.MR
import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
private val USER_PICKER_IMAGE_SIZE = 44.dp
private val USER_PICKER_ROW_PADDING = 16.dp
@Composable
actual fun UserPickerUsersSection(
actual fun UserPickerInactiveUsersSection(
users: List<UserInfo>,
stopped: Boolean,
onShowAllProfilesClicked: () -> Unit,
onUserClicked: (user: User) -> Unit,
) {
val scrollState = rememberScrollState()
val screenWidthDp = windowWidth()
if (users.isNotEmpty()) {
SectionItemView(
padding = PaddingValues(),
padding = PaddingValues(
start = 16.dp,
top = if (windowOrientation() == WindowOrientation.PORTRAIT) DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL else DEFAULT_PADDING_HALF,
bottom = DEFAULT_PADDING_HALF),
disabled = stopped
) {
Box {
Row(
modifier = Modifier.horizontalScroll(scrollState),
modifier = Modifier.padding(end = DEFAULT_PADDING + 30.dp).horizontalScroll(scrollState)
) {
Spacer(Modifier.width(DEFAULT_PADDING))
Row(horizontalArrangement = Arrangement.spacedBy(USER_PICKER_ROW_PADDING)) {
users.forEach { u ->
UserPickerUserBox(u, stopped, modifier = Modifier.userBoxWidth(u.user, users.size, screenWidthDp)) {
onUserClicked(it)
withBGApi {
delay(500)
scrollState.scrollTo(0)
}
users.forEach { u ->
UserPickerInactiveUserBadge(u, stopped) {
onUserClicked(it)
withBGApi {
delay(500)
scrollState.scrollTo(0)
}
}
Spacer(Modifier.width(20.dp))
}
Spacer(Modifier.width(60.dp))
}
Row(
horizontalArrangement = Arrangement.End,
modifier = Modifier
.fillMaxWidth()
.padding(end = DEFAULT_PADDING + 30.dp)
.height(60.dp)
) {
Canvas(modifier = Modifier.size(60.dp)) {
drawRect(
brush = Brush.horizontalGradient(
colors = listOf(
Color.Transparent,
CurrentColors.value.colors.surface,
)
),
)
}
}
Row(
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.height(60.dp)
.fillMaxWidth()
.padding(end = DEFAULT_PADDING)
) {
IconButton(
onClick = onShowAllProfilesClicked,
enabled = !stopped
) {
Icon(
painterResource(MR.images.ic_chevron_right),
stringResource(MR.strings.your_chat_profiles),
tint = MaterialTheme.colors.secondary,
modifier = Modifier.size(34.dp)
)
}
Spacer(Modifier.width(DEFAULT_PADDING))
}
}
}
}
}
@Composable
fun UserPickerUserBox(
userInfo: UserInfo,
stopped: Boolean,
modifier: Modifier = Modifier,
onClick: (user: User) -> Unit,
) {
Row(
modifier = modifier
.userPickerBoxModifier()
.clickable (
onClick = { onClick(userInfo.user) },
enabled = !stopped
)
.background(MaterialTheme.colors.background)
.padding(USER_PICKER_ROW_PADDING),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(USER_PICKER_ROW_PADDING)
) {
Box {
ProfileImageForActiveCall(size = USER_PICKER_IMAGE_SIZE, image = userInfo.user.profile.image, color = MaterialTheme.colors.secondaryVariant)
if (userInfo.unreadCount > 0 && !userInfo.user.activeUser) {
unreadBadge(userInfo.unreadCount, userInfo.user.showNtfs, false)
}
}
val user = userInfo.user
Text(
user.displayName,
fontWeight = if (user.activeUser) FontWeight.Bold else FontWeight.Normal,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
} else {
UserPickerOptionRow(
painterResource(MR.images.ic_manage_accounts),
stringResource(MR.strings.your_chat_profiles),
onShowAllProfilesClicked
)
}
}
@Composable
private fun Modifier.userPickerBoxModifier(): Modifier {
val percent = remember { appPreferences.profileImageCornerRadius.state }
val r = kotlin.math.max(0f, percent.value)
val cornerSize = when {
r >= 50 -> 50
r <= 0 -> 0
else -> r.toInt()
}
val shape = RoundedCornerShape(CornerSize(cornerSize))
return this.clip(shape).border(1.dp, MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, 1 - userPickerAlpha() - 0.02f), shape)
}
private fun calculateFraction(pos: Float) =
(pos / 1f).coerceIn(0f, 1f)
@@ -161,7 +150,7 @@ actual fun PlatformUserPicker(modifier: Modifier, pickerState: MutableStateFlow<
isLight = colors.isLight,
drawerShadingColor = shadingColor,
toolbarOnTop = !appPrefs.oneHandUI.get(),
navBarColor = colors.background.mixWith(colors.onBackground, 1 - userPickerAlpha())
navBarColor = colors.surface
)
} else if (ModalManager.start.modalCount.value == 0) {
platform.androidSetDrawerStatusAndNavBarColor(
@@ -231,13 +220,3 @@ private fun Modifier.draggableBottomDrawerModifier(
orientation = Orientation.Vertical,
resistance = null
)
private fun Modifier.userBoxWidth(user: User, totalUsers: Int, windowWidth: Dp): Modifier {
return if (totalUsers == 1) {
this.width(windowWidth - DEFAULT_PADDING * 2)
} else if (user.activeUser) {
this.width(windowWidth - DEFAULT_PADDING - (USER_PICKER_ROW_PADDING * 3) - USER_PICKER_IMAGE_SIZE)
} else {
this.widthIn(max = (windowWidth - (DEFAULT_PADDING * 2)) * 0.618f)
}
}
@@ -82,7 +82,7 @@ object ChatModel {
val desktopOnboardingRandomPassword = mutableStateOf(false)
// set when app is opened via contact or invitation URI (rhId, uri)
val appOpenUrl = mutableStateOf<Pair<Long?, String>?>(null)
val appOpenUrl = mutableStateOf<Pair<Long?, URI>?>(null)
// Needed to check for bottom nav bar and to apply or not navigation bar color on Android
val newChatSheetVisible = mutableStateOf(false)
@@ -806,7 +806,6 @@ data class User(
val profile: LocalProfile,
val fullPreferences: FullChatPreferences,
override val activeUser: Boolean,
val activeOrder: Long,
override val showNtfs: Boolean,
val sendRcptsContacts: Boolean,
val sendRcptsSmallGroups: Boolean,
@@ -834,7 +833,6 @@ data class User(
profile = LocalProfile.sampleData,
fullPreferences = FullChatPreferences.sampleData,
activeUser = true,
activeOrder = 0,
showNtfs = true,
sendRcptsContacts = true,
sendRcptsSmallGroups = false,
@@ -1406,14 +1404,6 @@ class Group (
var members: List<GroupMember>
)
@Serializable
sealed class ForwardConfirmation {
@Serializable @SerialName("filesNotAccepted") data class FilesNotAccepted(val fileIds: List<Long>) : ForwardConfirmation()
@Serializable @SerialName("filesInProgress") data class FilesInProgress(val filesCount: Int) : ForwardConfirmation()
@Serializable @SerialName("filesMissing") data class FilesMissing(val filesCount: Int) : ForwardConfirmation()
@Serializable @SerialName("filesFailed") data class FilesFailed(val filesCount: Int) : ForwardConfirmation()
}
@Serializable
data class GroupInfo (
val groupId: Long,
@@ -2356,8 +2346,7 @@ data class CIMeta (
val deletable: Boolean,
val editable: Boolean
) {
val timestampText: String get() = getTimestampText(itemTs, true)
val timestampText: String get() = getTimestampText(itemTs)
val recent: Boolean get() = updatedAt + 10.toDuration(DurationUnit.SECONDS) > Clock.System.now()
val isLive: Boolean get() = itemLive == true
val disappearing: Boolean get() = !isRcvNew && itemTimed?.deleteAt != null
@@ -2421,18 +2410,7 @@ data class CITimed(
val deleteAt: Instant?
)
fun getTimestampDateText(t: Instant): String {
val tz = TimeZone.currentSystemDefault()
val time = t.toLocalDateTime(tz).toJavaLocalDateTime()
val weekday = time.format(DateTimeFormatter.ofPattern("EEE"))
val dayMonthYear = time.format(DateTimeFormatter.ofPattern(
if (Clock.System.now().toLocalDateTime(tz).year == time.year) "d MMM" else "d MMM YYYY")
)
return "$weekday, $dayMonthYear"
}
fun getTimestampText(t: Instant, shortFormat: Boolean = false): String {
fun getTimestampText(t: Instant): String {
val tz = TimeZone.currentSystemDefault()
val now: LocalDateTime = Clock.System.now().toLocalDateTime(tz)
val time: LocalDateTime = t.toLocalDateTime(tz)
@@ -2440,23 +2418,16 @@ fun getTimestampText(t: Instant, shortFormat: Boolean = false): String {
val recent = now.date == time.date ||
(period.years == 0 && period.months == 0 && period.days == 1 && now.hour < 12 && time.hour >= 18 )
val dateFormatter =
if (recent || shortFormat) {
if (recent) {
DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
} else {
val dayMonthFormat = when (Locale.getDefault().country) {
"US" -> "M/dd"
"DE" -> "dd.MM"
"RU" -> "dd.MM"
else -> "dd/MM"
}
val dayMonthYearFormat = when (Locale.getDefault().country) {
"US" -> "M/dd/yy"
"DE" -> "dd.MM.yy"
"RU" -> "dd.MM.yy"
else -> "dd/MM/yy"
}
DateTimeFormatter.ofPattern(
if (now.year == time.year) dayMonthFormat else dayMonthYearFormat
when (Locale.getDefault().country) {
"US" -> "M/dd"
"DE" -> "dd.MM"
"RU" -> "dd.MM"
else -> "dd/MM"
}
)
// DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
}
@@ -1,19 +1,18 @@
package chat.simplex.common.model
import SectionItemView
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import chat.simplex.common.views.helpers.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import chat.simplex.common.model.ChatController.getNetCfg
import chat.simplex.common.model.ChatController.setNetCfg
import chat.simplex.common.model.ChatModel.changingActiveUserMutex
@@ -906,15 +905,7 @@ object ChatController {
return processSendMessageCmd(rh, cmd)?.map { it.chatItem }
}
suspend fun apiPlanForwardChatItems(rh: Long?, fromChatType: ChatType, fromChatId: Long, chatItemIds: List<Long>): CR.ForwardPlan? {
return when (val r = sendCmd(rh, CC.ApiPlanForwardChatItems(fromChatType, fromChatId, chatItemIds))) {
is CR.ForwardPlan -> r
else -> {
apiErrorAlert("apiPlanForwardChatItems", generalGetString(MR.strings.error_forwarding_messages), r)
null
}
}
}
suspend fun apiUpdateChatItem(rh: Long?, type: ChatType, id: Long, itemId: Long, mc: MsgContent, live: Boolean = false): AChatItem? {
val r = sendCmd(rh, CC.ApiUpdateChatItem(type, id, itemId, mc, live))
@@ -1550,134 +1541,52 @@ object ChatController {
}
}
suspend fun receiveFiles(rhId: Long?, user: UserLike, fileIds: List<Long>, userApprovedRelays: Boolean = false, auto: Boolean = false) {
val fileIdsToApprove = mutableListOf<Long>()
val srvsToApprove = mutableSetOf<String>()
val otherFileErrs = mutableListOf<CR>()
for (fileId in fileIds) {
val r = sendCmd(
rhId, CC.ReceiveFile(
fileId,
userApprovedRelays = userApprovedRelays || !appPrefs.privacyAskToApproveRelays.get(),
encrypt = appPrefs.privacyEncryptLocalFiles.get(),
inline = null
)
)
if (r is CR.RcvFileAccepted) {
chatItemSimpleUpdate(rhId, user, r.chatItem)
} else {
val maybeChatError = chatError(r)
if (maybeChatError is ChatErrorType.FileNotApproved) {
fileIdsToApprove.add(maybeChatError.fileId)
srvsToApprove.addAll(maybeChatError.unknownServers.map { serverHostname(it) })
} else {
otherFileErrs.add(r)
suspend fun apiReceiveFile(rh: Long?, fileId: Long, userApprovedRelays: Boolean, encrypted: Boolean, inline: Boolean? = null, auto: Boolean = false): AChatItem? {
// -1 here is to override default behavior of providing current remote host id because file can be asked by local device while remote is connected
val r = sendCmd(rh, CC.ReceiveFile(fileId, userApprovedRelays = userApprovedRelays, encrypt = encrypted, inline = inline))
return when (r) {
is CR.RcvFileAccepted -> r.chatItem
is CR.RcvFileAcceptedSndCancelled -> {
Log.d(TAG, "apiReceiveFile error: sender cancelled file transfer")
if (!auto) {
AlertManager.shared.showAlertMsg(
generalGetString(MR.strings.cannot_receive_file),
generalGetString(MR.strings.sender_cancelled_file_transfer)
)
}
null
}
}
if (!auto) {
// If there are not approved files, alert is shown the same way both in case of singular and plural files reception
if (fileIdsToApprove.isNotEmpty()) {
showFilesToApproveAlert(
srvsToApprove = srvsToApprove,
otherFileErrs = otherFileErrs,
approveFiles = {
withBGApi {
receiveFiles(
rhId = rhId,
user = user,
fileIds = fileIdsToApprove,
userApprovedRelays = true
else -> {
if (!(networkErrorAlert(r))) {
val maybeChatError = chatError(r)
if (maybeChatError is ChatErrorType.FileCancelled || maybeChatError is ChatErrorType.FileAlreadyReceiving) {
Log.d(TAG, "apiReceiveFile ignoring FileCancelled or FileAlreadyReceiving error")
} else if (maybeChatError is ChatErrorType.FileNotApproved) {
Log.d(TAG, "apiReceiveFile FileNotApproved error")
if (!auto) {
val srvs = maybeChatError.unknownServers.map{ serverHostname(it) }
AlertManager.shared.showAlertDialog(
title = generalGetString(MR.strings.file_not_approved_title),
text = generalGetString(MR.strings.file_not_approved_descr).format(srvs.sorted().joinToString(separator = ", ")),
confirmText = generalGetString(MR.strings.download_file),
onConfirm = {
val user = chatModel.currentUser.value
if (user != null) {
withBGApi { chatModel.controller.receiveFile(rh, user, fileId, userApprovedRelays = true) }
}
},
)
}
}
)
} else if (otherFileErrs.size == 1) { // If there is a single other error, we differentiate on it
when (val errCR = otherFileErrs.first()) {
is CR.RcvFileAcceptedSndCancelled -> {
Log.d(TAG, "receiveFiles error: sender cancelled file transfer")
AlertManager.shared.showAlertMsg(
generalGetString(MR.strings.cannot_receive_file),
generalGetString(MR.strings.sender_cancelled_file_transfer)
)
}
else -> {
val maybeChatError = chatError(errCR)
if (maybeChatError is ChatErrorType.FileCancelled || maybeChatError is ChatErrorType.FileAlreadyReceiving) {
Log.d(TAG, "receiveFiles ignoring FileCancelled or FileAlreadyReceiving error")
} else {
apiErrorAlert("receiveFiles", generalGetString(MR.strings.error_receiving_file), errCR)
}
} else if (!auto) {
apiErrorAlert("apiReceiveFile", generalGetString(MR.strings.error_receiving_file), r)
}
}
} else if (otherFileErrs.size > 1) { // If there are multiple other errors, we show general alert
val errsStr = otherFileErrs.map { json.encodeToString(it) }.joinToString(separator = "\n")
AlertManager.shared.showAlertMsg(
generalGetString(MR.strings.error_receiving_file),
text = String.format(generalGetString(MR.strings.n_file_errors), otherFileErrs.size, errsStr),
shareText = true
)
null
}
}
}
private fun showFilesToApproveAlert(
srvsToApprove: Set<String>,
otherFileErrs: List<CR>,
approveFiles: (() -> Unit)
) {
val srvsToApproveStr = srvsToApprove.sorted().joinToString(separator = ", ")
val alertText =
generalGetString(MR.strings.file_not_approved_descr).format(srvsToApproveStr) +
(if (otherFileErrs.isNotEmpty()) "\n" + generalGetString(MR.strings.n_other_file_errors).format(otherFileErrs.size) else "")
AlertManager.shared.showAlertDialogButtonsColumn(generalGetString(MR.strings.file_not_approved_title), alertText, belowTextContent = {
if (otherFileErrs.isNotEmpty()) {
val clipboard = LocalClipboardManager.current
SimpleButtonFrame(click = {
clipboard.setText(AnnotatedString(otherFileErrs.map { json.encodeToString(it) }.joinToString(separator = "\n")))
}) {
Icon(
painterResource(MR.images.ic_content_copy),
contentDescription = null,
tint = MaterialTheme.colors.primary,
modifier = Modifier.padding(end = 8.dp)
)
Text(generalGetString(MR.strings.copy_error), color = MaterialTheme.colors.primary)
}
}
}) {
Row(
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING),
horizontalArrangement = Arrangement.SpaceBetween
) {
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
// Wait before focusing to prevent auto-confirming if a user used Enter key on hardware keyboard
delay(200)
focusRequester.requestFocus()
}
TextButton(onClick = AlertManager.shared::hideAlert) { Text(generalGetString(MR.strings.cancel_verb)) }
TextButton(onClick = {
approveFiles.invoke()
AlertManager.shared.hideAlert()
}, Modifier.focusRequester(focusRequester)) { Text(generalGetString(MR.strings.download_file)) }
}
}
}
suspend fun receiveFile(rhId: Long?, user: UserLike, fileId: Long, userApprovedRelays: Boolean = false, auto: Boolean = false) {
receiveFiles(
rhId = rhId,
user = user,
fileIds = listOf(fileId),
userApprovedRelays = userApprovedRelays,
auto = auto
)
}
suspend fun cancelFile(rh: Long?, user: User, fileId: Long) {
val chatItem = apiCancelFile(rh, fileId)
if (chatItem != null) {
@@ -2525,7 +2434,7 @@ object ChatController {
// TODO askConfirmation?
// TODO check encryption is compatible
withCall(r, r.contact) { call ->
chatModel.activeCall.value = call.copy(callState = CallState.OfferReceived, sharedKey = r.sharedKey)
chatModel.activeCall.value = call.copy(callState = CallState.OfferReceived, peerMedia = r.callType.media, sharedKey = r.sharedKey)
val useRelay = appPrefs.webrtcPolicyRelay.get()
val iceServers = getIceServers()
Log.d(TAG, ".callOffer iceServers $iceServers")
@@ -2780,6 +2689,19 @@ object ChatController {
}
}
suspend fun receiveFile(rhId: Long?, user: UserLike, fileId: Long, userApprovedRelays: Boolean = false, auto: Boolean = false) {
val chatItem = apiReceiveFile(
rhId,
fileId,
userApprovedRelays = userApprovedRelays || !appPrefs.privacyAskToApproveRelays.get(),
encrypted = appPrefs.privacyEncryptLocalFiles.get(),
auto = auto
)
if (chatItem != null) {
chatItemSimpleUpdate(rhId, user, chatItem)
}
}
suspend fun leaveGroup(rh: Long?, groupId: Long) {
val groupInfo = apiLeaveGroup(rh, groupId)
if (groupInfo != null) {
@@ -2992,7 +2914,6 @@ sealed class 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 ApiPlanForwardChatItems(val fromChatType: ChatType, val fromChatId: Long, val chatItemIds: List<Long>): 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()
@@ -3151,9 +3072,6 @@ sealed class CC {
val ttlStr = if (ttl != null) "$ttl" else "default"
"/_forward ${chatRef(toChatType, toChatId)} ${chatRef(fromChatType, fromChatId)} ${itemIds.joinToString(",")} ttl=${ttlStr}"
}
is ApiPlanForwardChatItems -> {
"/_forward plan ${chatRef(fromChatType, fromChatId)} ${chatItemIds.joinToString(",")}"
}
is ApiNewGroup -> "/_group $userId incognito=${onOff(incognito)} ${json.encodeToString(groupProfile)}"
is ApiAddMember -> "/_add #$groupId $contactId ${memberRole.memberRole}"
is ApiJoinGroup -> "/_join #$groupId"
@@ -3298,7 +3216,6 @@ sealed class CC {
is ApiDeleteMemberChatItem -> "apiDeleteMemberChatItem"
is ApiChatItemReaction -> "apiChatItemReaction"
is ApiForwardChatItems -> "apiForwardChatItems"
is ApiPlanForwardChatItems -> "apiPlanForwardChatItems"
is ApiNewGroup -> "apiNewGroup"
is ApiAddMember -> "apiAddMember"
is ApiJoinGroup -> "apiJoinGroup"
@@ -4961,7 +4878,6 @@ sealed class CR {
@Serializable @SerialName("chatItemNotChanged") class ChatItemNotChanged(val user: UserRef, val chatItem: AChatItem): CR()
@Serializable @SerialName("chatItemReaction") class ChatItemReaction(val user: UserRef, val added: Boolean, val reaction: ACIReaction): CR()
@Serializable @SerialName("chatItemsDeleted") class ChatItemsDeleted(val user: UserRef, val chatItemDeletions: List<ChatItemDeletion>, val byUser: Boolean): CR()
@Serializable @SerialName("forwardPlan") class ForwardPlan(val user: UserRef, val itemsCount: Int, val chatItemIds: List<Long>, val forwardConfirmation: ForwardConfirmation? = null): CR()
// group events
@Serializable @SerialName("groupCreated") class GroupCreated(val user: UserRef, val groupInfo: GroupInfo): CR()
@Serializable @SerialName("sentGroupInvitation") class SentGroupInvitation(val user: UserRef, val groupInfo: GroupInfo, val contact: Contact, val member: GroupMember): CR()
@@ -5139,7 +5055,6 @@ sealed class CR {
is ChatItemNotChanged -> "chatItemNotChanged"
is ChatItemReaction -> "chatItemReaction"
is ChatItemsDeleted -> "chatItemsDeleted"
is ForwardPlan -> "forwardPlan"
is GroupCreated -> "groupCreated"
is SentGroupInvitation -> "sentGroupInvitation"
is UserAcceptedGroupSent -> "userAcceptedGroupSent"
@@ -5309,7 +5224,6 @@ sealed class CR {
is ChatItemNotChanged -> withUser(user, json.encodeToString(chatItem))
is ChatItemReaction -> withUser(user, "added: $added\n${json.encodeToString(reaction)}")
is ChatItemsDeleted -> withUser(user, "${chatItemDeletions.map { (deletedChatItem, toChatItem) -> "deletedChatItem: ${json.encodeToString(deletedChatItem)}\ntoChatItem: ${json.encodeToString(toChatItem)}" }} \nbyUser: $byUser")
is ForwardPlan -> withUser(user, "itemsCount: $itemsCount\nchatItemIds: ${json.encodeToString(chatItemIds)}\nforwardConfirmation: ${json.encodeToString(forwardConfirmation)}")
is GroupCreated -> withUser(user, json.encodeToString(groupInfo))
is SentGroupInvitation -> withUser(user, "groupInfo: $groupInfo\ncontact: $contact\nmember: $member")
is UserAcceptedGroupSent -> json.encodeToString(groupInfo)
@@ -49,7 +49,7 @@ class CallManager(val chatModel: ChatModel) {
contact = invitation.contact,
callUUID = invitation.callUUID,
callState = CallState.InvitationAccepted,
initialCallType = invitation.callType.media,
localMedia = invitation.callType.media,
sharedKey = invitation.sharedKey,
)
showCallView.value = true
@@ -2,7 +2,6 @@ package chat.simplex.common.views.call
import chat.simplex.common.views.helpers.generalGetString
import chat.simplex.common.model.*
import chat.simplex.common.platform.appPlatform
import chat.simplex.res.MR
import kotlinx.datetime.Instant
import kotlinx.serialization.SerialName
@@ -16,21 +15,18 @@ data class Call(
val contact: Contact,
val callUUID: String?,
val callState: CallState,
val initialCallType: CallMediaType,
val localMediaSources: CallMediaSources = CallMediaSources(mic = true, camera = initialCallType == CallMediaType.Video && appPlatform.isAndroid),
val localMedia: CallMediaType,
val localCapabilities: CallCapabilities? = null,
val peerMediaSources: CallMediaSources = CallMediaSources(),
val peerMedia: CallMediaType? = null,
val sharedKey: String? = null,
val audioEnabled: Boolean = true,
val videoEnabled: Boolean = localMedia == CallMediaType.Video,
var localCamera: VideoCamera = VideoCamera.User,
val connectionInfo: ConnectionInfo? = null,
var connectedAt: Instant? = null,
// When a user has audio call, and then he wants to enable camera but didn't grant permissions for using camera yet,
// we show permissions view without enabling camera before permissions are granted. After they are granted, enabling camera
val wantsToEnableCamera: Boolean = false
) {
val encrypted: Boolean get() = localEncrypted && sharedKey != null
private val localEncrypted: Boolean get() = localCapabilities?.encryption ?: false
val localEncrypted: Boolean get() = localCapabilities?.encryption ?: false
val encryptionStatus: String get() = when(callState) {
CallState.WaitCapabilities -> ""
@@ -39,8 +35,10 @@ data class Call(
else -> generalGetString(if (!localEncrypted) MR.strings.status_no_e2e_encryption else if (sharedKey == null) MR.strings.status_contact_has_no_e2e_encryption else MR.strings.status_e2e_encrypted)
}
val hasVideo: Boolean
get() = localMediaSources.hasVideo || peerMediaSources.hasVideo
val hasMedia: Boolean get() = callState == CallState.OfferSent || callState == CallState.Negotiated || callState == CallState.Connected
fun supportsVideo(): Boolean = peerMedia == CallMediaType.Video || localMedia == CallMediaType.Video
}
enum class CallState {
@@ -70,16 +68,6 @@ enum class CallState {
@Serializable data class WVAPICall(val corrId: Int? = null, val command: WCallCommand)
@Serializable data class WVAPIMessage(val corrId: Int? = null, val resp: WCallResponse, val command: WCallCommand? = null)
@Serializable data class CallMediaSources(
val mic: Boolean = false,
val camera: Boolean = false,
val screenAudio: Boolean = false,
val screenVideo: Boolean = false
) {
val hasVideo: Boolean
get() = camera || screenVideo
}
@Serializable
sealed class WCallCommand {
@Serializable @SerialName("capabilities") data class Capabilities(val media: CallMediaType): WCallCommand()
@@ -87,7 +75,7 @@ sealed class WCallCommand {
@Serializable @SerialName("offer") data class Offer(val offer: String, val iceCandidates: String, val media: CallMediaType, val aesKey: String? = null, val iceServers: List<RTCIceServer>? = null, val relay: Boolean? = null): WCallCommand()
@Serializable @SerialName("answer") data class Answer (val answer: String, val iceCandidates: String): WCallCommand()
@Serializable @SerialName("ice") data class Ice(val iceCandidates: String): WCallCommand()
@Serializable @SerialName("media") data class Media(val source: CallMediaSource, val enable: Boolean): WCallCommand()
@Serializable @SerialName("media") data class Media(val media: CallMediaType, val enable: Boolean): WCallCommand()
@Serializable @SerialName("camera") data class Camera(val camera: VideoCamera): WCallCommand()
@Serializable @SerialName("description") data class Description(val state: String, val description: String): WCallCommand()
@Serializable @SerialName("layout") data class Layout(val layout: LayoutType): WCallCommand()
@@ -102,7 +90,6 @@ sealed class WCallResponse {
@Serializable @SerialName("ice") data class Ice(val iceCandidates: String): WCallResponse()
@Serializable @SerialName("connection") data class Connection(val state: ConnectionState): WCallResponse()
@Serializable @SerialName("connected") data class Connected(val connectionInfo: ConnectionInfo): WCallResponse()
@Serializable @SerialName("peerMedia") data class PeerMedia(val source: CallMediaSource, val enabled: Boolean): WCallResponse()
@Serializable @SerialName("end") object End: WCallResponse()
@Serializable @SerialName("ended") object Ended: WCallResponse()
@Serializable @SerialName("ok") object Ok: WCallResponse()
@@ -178,14 +165,6 @@ enum class CallMediaType {
@SerialName("audio") Audio
}
@Serializable
enum class CallMediaSource {
@SerialName("mic") Mic,
@SerialName("camera") Camera,
@SerialName("screenAudio") ScreenAudio,
@SerialName("screenVideo") ScreenVideo
}
@Serializable
enum class VideoCamera {
@SerialName("user") User,
@@ -14,7 +14,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.*
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.graphics.*
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.platform.*
import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource
@@ -22,10 +21,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.text.*
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.*
import chat.simplex.common.model.*
import chat.simplex.common.model.CIDirection.GroupRcv
import chat.simplex.common.model.ChatController.appPrefs
import chat.simplex.common.model.ChatModel.controller
import chat.simplex.common.model.ChatModel.withChats
@@ -42,14 +39,11 @@ import chat.simplex.common.views.newchat.ContactConnectionInfoView
import chat.simplex.res.MR
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.datetime.*
import kotlinx.datetime.Clock
import java.io.File
import java.net.URI
import kotlin.math.abs
import kotlin.math.sign
data class ItemSeparation(val timestamp: Boolean, val largeGap: Boolean, val date: Instant?)
@Composable
// staleChatId means the id that was before chatModel.chatId becomes null. It's needed for Android only to make transition from chat
// to chat list smooth. Otherwise, chat view will become blank right before the transition starts
@@ -178,30 +172,7 @@ fun ChatView(staleChatId: State<String?>, onComposed: suspend (chatId: String) -
})
}
}
},
forwardItems = {
val itemIds = selectedChatItems.value
if (itemIds != null) {
withBGApi {
val chatItemIds = itemIds.toList()
val forwardPlan = controller.apiPlanForwardChatItems(
rh = chatRh,
fromChatType = chatInfo.chatType,
fromChatId = chatInfo.apiId,
chatItemIds = chatItemIds
)
if (forwardPlan != null) {
if (forwardPlan.chatItemIds.count() < chatItemIds.count() || forwardPlan.forwardConfirmation != null) {
handleForwardConfirmation(chatRh, forwardPlan, chatInfo)
} else {
forwardContent(forwardPlan.chatItemIds, chatInfo)
}
}
}
}
},
}
)
}
},
@@ -376,9 +347,9 @@ fun ChatView(staleChatId: State<String?>, onComposed: suspend (chatId: String) -
openDirectChat(chatRh, contactId, chatModel)
}
},
forwardItem = { cInfo, cItem ->
forwardItem = { cItem, cInfo ->
chatModel.chatId.value = null
chatModel.sharedContent.value = SharedContent.Forward(listOf(cItem), cInfo)
chatModel.sharedContent.value = SharedContent.Forward(cInfo, cItem)
},
updateContactStats = { contact ->
withBGApi {
@@ -580,7 +551,7 @@ fun startChatCall(remoteHostId: Long?, chatInfo: ChatInfo, media: CallMediaType)
if (chatInfo is ChatInfo.Direct) {
val contactInfo = chatModel.controller.apiContactInfo(remoteHostId, chatInfo.contact.contactId)
val profile = contactInfo?.second ?: chatModel.currentUser.value?.profile?.toProfile() ?: return@withBGApi
chatModel.activeCall.value = Call(remoteHostId = remoteHostId, contact = chatInfo.contact, callUUID = null, callState = CallState.WaitCapabilities, initialCallType = media, userProfile = profile)
chatModel.activeCall.value = Call(remoteHostId = remoteHostId, contact = chatInfo.contact, callUUID = null, callState = CallState.WaitCapabilities, localMedia = media, userProfile = profile)
chatModel.showCallView.value = true
chatModel.callCommand.add(WCallCommand.Capabilities(media))
}
@@ -1038,6 +1009,25 @@ fun BoxWithConstraintsScope.ChatItemsList(
// With default touchSlop when you scroll LazyColumn, you can unintentionally open reply view
LocalViewConfiguration provides LocalViewConfiguration.current.bigTouchSlop()
) {
val dismissState = rememberDismissState(initialValue = DismissValue.Default) {
if (it == DismissValue.DismissedToStart) {
scope.launch {
if ((cItem.content is CIContent.SndMsgContent || cItem.content is CIContent.RcvMsgContent) && chatInfo !is ChatInfo.Local) {
if (composeState.value.editing) {
composeState.value = ComposeState(contextItem = ComposeContextItem.QuotedItem(cItem), useLinkPreviews = useLinkPreviews)
} else if (cItem.id != ChatItem.TEMP_LIVE_CHAT_ITEM_ID) {
composeState.value = composeState.value.copy(contextItem = ComposeContextItem.QuotedItem(cItem))
}
}
}
}
false
}
val swipeableModifier = SwipeToDismissModifier(
state = dismissState,
directions = setOf(DismissDirection.EndToStart),
swipeDistance = with(LocalDensity.current) { 30.dp.toPx() },
)
val provider = {
providerForGallery(i, chatModel.chatItems.value, cItem.id) { indexInReversed ->
scope.launch {
@@ -1052,56 +1042,18 @@ fun BoxWithConstraintsScope.ChatItemsList(
val revealed = remember { mutableStateOf(false) }
@Composable
fun ChatItemViewShortHand(cItem: ChatItem, itemSeparation: ItemSeparation, range: IntRange?, fillMaxWidth: Boolean = true) {
fun ChatItemViewShortHand(cItem: ChatItem, range: IntRange?) {
tryOrShowError("${cItem.id}ChatItem", error = {
CIBrokenComposableView(if (cItem.chatDir.sent) Alignment.CenterEnd else Alignment.CenterStart)
}) {
ChatItemView(remoteHostId, chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, revealed = revealed, range = range, fillMaxWidth = fillMaxWidth, selectedChatItems = selectedChatItems, selectChatItem = { selectUnselectChatItem(true, cItem, revealed, selectedChatItems) }, deleteMessage = deleteMessage, deleteMessages = deleteMessages, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = joinGroup, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, forwardItem = forwardItem, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails, developerTools = developerTools, showViaProxy = showViaProxy, showTimestamp = itemSeparation.timestamp)
ChatItemView(remoteHostId, chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, revealed = revealed, range = range, selectedChatItems = selectedChatItems, selectChatItem = { selectUnselectChatItem(true, cItem, revealed, selectedChatItems) }, deleteMessage = deleteMessage, deleteMessages = deleteMessages, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = joinGroup, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, forwardItem = forwardItem, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails, developerTools = developerTools, showViaProxy = showViaProxy)
}
}
@Composable
fun ChatItemView(cItem: ChatItem, range: IntRange?, prevItem: ChatItem?, itemSeparation: ItemSeparation, previousItemSeparation: ItemSeparation?) {
val dismissState = rememberDismissState(initialValue = DismissValue.Default) {
if (it == DismissValue.DismissedToStart) {
scope.launch {
if ((cItem.content is CIContent.SndMsgContent || cItem.content is CIContent.RcvMsgContent) && chatInfo !is ChatInfo.Local) {
if (composeState.value.editing) {
composeState.value = ComposeState(contextItem = ComposeContextItem.QuotedItem(cItem), useLinkPreviews = useLinkPreviews)
} else if (cItem.id != ChatItem.TEMP_LIVE_CHAT_ITEM_ID) {
composeState.value = composeState.value.copy(contextItem = ComposeContextItem.QuotedItem(cItem))
}
}
}
}
false
}
val swipeableModifier = SwipeToDismissModifier(
state = dismissState,
directions = setOf(DismissDirection.EndToStart),
swipeDistance = with(LocalDensity.current) { 30.dp.toPx() },
)
fun ChatItemView(cItem: ChatItem, range: IntRange?, prevItem: ChatItem?) {
val sent = cItem.chatDir.sent
@Composable
fun ChatItemBox(modifier: Modifier = Modifier, content: @Composable () -> Unit = { }) {
Box(
modifier = modifier.padding(
bottom = if (itemSeparation.largeGap) {
if (i == 0) {
8.dp
} else {
4.dp
}
} else 1.dp, top = if (previousItemSeparation?.largeGap == true) 4.dp else 1.dp
),
contentAlignment = Alignment.CenterStart
) {
content()
}
}
Box {
Box(Modifier.padding(bottom = 4.dp)) {
val voiceWithTransparentBack = cItem.content.msgContent is MsgContent.MCVoice && cItem.content.text.isEmpty() && cItem.quotedItem == null && cItem.meta.itemForwarded == null
val selectionVisible = selectedChatItems.value != null && cItem.canBeDeletedForSelf
val selectionOffset by animateDpAsState(if (selectionVisible && !sent) 4.dp + 22.dp * fontSizeMultiplier else 0.dp)
@@ -1119,66 +1071,46 @@ fun BoxWithConstraintsScope.ChatItemsList(
Column(
Modifier
.padding(top = 8.dp)
.padding(start = 8.dp, end = if (voiceWithTransparentBack) 12.dp else 66.dp)
.fillMaxWidth()
.then(swipeableModifier),
.padding(start = 8.dp, end = if (voiceWithTransparentBack) 12.dp else 66.dp),
verticalArrangement = Arrangement.spacedBy(4.dp),
horizontalAlignment = Alignment.Start
) {
@Composable
fun MemberNameAndRole() {
Row(Modifier.padding(bottom = 2.dp).graphicsLayer { translationX = selectionOffset.toPx() }, horizontalArrangement = Arrangement.SpaceBetween) {
Text(
memberNames(member, prevMember, memCount),
Modifier
.padding(start = MEMBER_IMAGE_SIZE + DEFAULT_PADDING_HALF)
.weight(1f, false),
fontSize = 13.5.sp,
color = MaterialTheme.colors.secondary,
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
if (memCount == 1 && member.memberRole > GroupMemberRole.Member) {
Text(
member.memberRole.text,
Modifier.padding(start = DEFAULT_PADDING_HALF * 1.5f, end = DEFAULT_PADDING_HALF),
fontSize = 13.5.sp,
fontWeight = FontWeight.Medium,
color = MaterialTheme.colors.secondary,
maxLines = 1
)
}
}
}
@Composable
fun Item() {
ChatItemBox(Modifier.layoutId(CHAT_BUBBLE_LAYOUT_ID)) {
androidx.compose.animation.AnimatedVisibility(selectionVisible, enter = fadeIn(), exit = fadeOut()) {
SelectedChatItem(Modifier, cItem.id, selectedChatItems)
}
Row(Modifier.graphicsLayer { translationX = selectionOffset.toPx() },
horizontalArrangement = Arrangement.spacedBy(4.dp)) {
Box(Modifier.clickable { showMemberInfo(chatInfo.groupInfo, member) }) {
MemberImage(member)
}
Box(modifier = Modifier.padding(top = 2.dp)) {
ChatItemViewShortHand(cItem, itemSeparation, range, false)
}
}
}
}
if (cItem.content.showMemberName) {
DependentLayout(Modifier, CHAT_BUBBLE_LAYOUT_ID) {
MemberNameAndRole()
Item()
val memberNameStyle = SpanStyle(fontSize = 13.5.sp, color = CurrentColors.value.colors.secondary)
val memberNameString = if (memCount == 1 && member.memberRole > GroupMemberRole.Member) {
buildAnnotatedString {
withStyle(memberNameStyle.copy(fontWeight = FontWeight.Medium)) { append(member.memberRole.text) }
append(" ")
withStyle(memberNameStyle) { append(memberNames(member, prevMember, memCount)) }
}
} else {
buildAnnotatedString {
withStyle(memberNameStyle) { append(memberNames(member, prevMember, memCount)) }
}
}
Text(
memberNameString,
Modifier.padding(start = MEMBER_IMAGE_SIZE + 10.dp),
maxLines = 2
)
}
Box(contentAlignment = Alignment.CenterStart) {
androidx.compose.animation.AnimatedVisibility(selectionVisible, enter = fadeIn(), exit = fadeOut()) {
SelectedChatItem(Modifier, cItem.id, selectedChatItems)
}
Row(
swipeableOrSelectionModifier,
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
Box(Modifier.clickable { showMemberInfo(chatInfo.groupInfo, member) }) {
MemberImage(member)
}
ChatItemViewShortHand(cItem, range)
}
} else {
Item()
}
}
} else {
ChatItemBox {
Box(contentAlignment = Alignment.CenterStart) {
AnimatedVisibility (selectionVisible, enter = fadeIn(), exit = fadeOut()) {
SelectedChatItem(Modifier.padding(start = 8.dp), cItem.id, selectedChatItems)
}
@@ -1187,12 +1119,12 @@ fun BoxWithConstraintsScope.ChatItemsList(
.padding(start = 8.dp + MEMBER_IMAGE_SIZE + 4.dp, end = if (voiceWithTransparentBack) 12.dp else 66.dp)
.then(swipeableOrSelectionModifier)
) {
ChatItemViewShortHand(cItem, itemSeparation, range)
ChatItemViewShortHand(cItem, range)
}
}
}
} else {
ChatItemBox {
Box(contentAlignment = Alignment.CenterStart) {
AnimatedVisibility (selectionVisible, enter = fadeIn(), exit = fadeOut()) {
SelectedChatItem(Modifier.padding(start = 8.dp), cItem.id, selectedChatItems)
}
@@ -1201,12 +1133,12 @@ fun BoxWithConstraintsScope.ChatItemsList(
.padding(start = if (voiceWithTransparentBack) 12.dp else 104.dp, end = 12.dp)
.then(if (selectionVisible) Modifier else swipeableModifier)
) {
ChatItemViewShortHand(cItem, itemSeparation, range)
ChatItemViewShortHand(cItem, range)
}
}
}
} else { // direct message
ChatItemBox {
Box(contentAlignment = Alignment.CenterStart) {
AnimatedVisibility (selectionVisible, enter = fadeIn(), exit = fadeOut()) {
SelectedChatItem(Modifier.padding(start = 8.dp), cItem.id, selectedChatItems)
}
@@ -1216,7 +1148,7 @@ fun BoxWithConstraintsScope.ChatItemsList(
end = if (sent || voiceWithTransparentBack) 12.dp else 76.dp,
).then(if (!selectionVisible || !sent) swipeableOrSelectionModifier else Modifier)
) {
ChatItemViewShortHand(cItem, itemSeparation, range)
ChatItemViewShortHand(cItem, range)
}
}
}
@@ -1235,30 +1167,17 @@ fun BoxWithConstraintsScope.ChatItemsList(
// memberConnected events and deleted items are aggregated at the last chat item in a row, see ChatItemView
} else {
val (prevHidden, prevItem) = chatModel.getPrevShownChatItem(currIndex, ciCategory)
val itemSeparation = getItemSeparation(cItem, nextItem)
val previousItemSeparation = if (prevItem != null) getItemSeparation(prevItem, cItem) else null
if (itemSeparation.date != null) {
DateSeparator(itemSeparation.date)
}
val range = chatViewItemsRange(currIndex, prevHidden)
if (revealed.value && range != null) {
reversedChatItems.subList(range.first, range.last + 1).forEachIndexed { index, ci ->
val prev = if (index + range.first == prevHidden) prevItem else reversedChatItems[index + range.first + 1]
ChatItemView(ci, null, prev, itemSeparation, previousItemSeparation)
ChatItemView(ci, null, prev)
}
} else {
ChatItemView(cItem, range, prevItem, itemSeparation, previousItemSeparation)
}
if (i == reversedChatItems.lastIndex) {
DateSeparator(cItem.meta.itemTs)
ChatItemView(cItem, range, prevItem)
}
}
if (cItem.isRcvNew && chatInfo.id == ChatModel.chatId.value) {
LaunchedEffect(cItem.id) {
scope.launch {
@@ -1462,7 +1381,7 @@ private fun showMemberImage(member: GroupMember, prevItem: ChatItem?): Boolean =
else -> false
}
val MEMBER_IMAGE_SIZE: Dp = 37.dp
val MEMBER_IMAGE_SIZE: Dp = 38.dp
@Composable
fun MemberImage(member: GroupMember) {
@@ -1497,77 +1416,6 @@ private fun TopEndFloatingButton(
}
}
@Composable
private fun DownloadFilesButton(
forwardConfirmation: ForwardConfirmation.FilesNotAccepted,
rhId: Long?,
modifier: Modifier = Modifier,
contentPadding: PaddingValues = ButtonDefaults.TextButtonContentPadding
) {
val user = chatModel.currentUser.value
if (user != null) {
TextButton(
contentPadding = contentPadding,
modifier = modifier,
onClick = {
AlertManager.shared.hideAlert()
withBGApi {
controller.receiveFiles(
rhId = rhId,
fileIds = forwardConfirmation.fileIds,
user = user
)
}
}
) {
Text(stringResource(MR.strings.forward_files_not_accepted_receive_files), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
}
}
}
@Composable
private fun ForwardButton(
forwardPlan: CR.ForwardPlan,
chatInfo: ChatInfo,
modifier: Modifier = Modifier,
contentPadding: PaddingValues = ButtonDefaults.TextButtonContentPadding
) {
TextButton(
onClick = {
forwardContent(forwardPlan.chatItemIds, chatInfo)
AlertManager.shared.hideAlert()
},
modifier = modifier,
contentPadding = contentPadding
) {
Text(stringResource(MR.strings.forward_chat_item), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
}
}
@Composable
private fun ButtonRow(horizontalArrangement: Arrangement.Horizontal, content: @Composable() (RowScope.() -> Unit)) {
Row(
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING),
horizontalArrangement = horizontalArrangement
) {
content()
}
}
@Composable
private fun DateSeparator(date: Instant) {
Text(
text = getTimestampDateText(date),
Modifier.padding(DEFAULT_PADDING).fillMaxWidth(),
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
textAlign = TextAlign.Center,
color = MaterialTheme.colors.secondary
)
}
val chatViewScrollState = MutableStateFlow(false)
fun addGroupMembers(groupInfo: GroupInfo, rhId: Long?, view: Any? = null, close: (() -> Unit)? = null) {
@@ -1864,100 +1712,6 @@ private fun ViewConfiguration.bigTouchSlop(slop: Float = 50f) = object: ViewConf
override val touchSlop: Float get() = slop
}
private fun forwardContent(chatItemsIds: List<Long>, chatInfo: ChatInfo) {
chatModel.chatId.value = null
chatModel.sharedContent.value = SharedContent.Forward(
chatModel.chatItems.value.filter { chatItemsIds.contains(it.id) },
chatInfo
)
}
private fun forwardConfirmationAlertDescription(forwardConfirmation: ForwardConfirmation): String {
return when (forwardConfirmation) {
is ForwardConfirmation.FilesNotAccepted -> String.format(generalGetString(MR.strings.forward_files_not_accepted_desc), forwardConfirmation.fileIds.count())
is ForwardConfirmation.FilesInProgress -> String.format(generalGetString(MR.strings.forward_files_in_progress_desc), forwardConfirmation.filesCount)
is ForwardConfirmation.FilesFailed -> String.format(generalGetString(MR.strings.forward_files_failed_to_receive_desc), forwardConfirmation.filesCount)
is ForwardConfirmation.FilesMissing -> String.format(generalGetString(MR.strings.forward_files_missing_desc), forwardConfirmation.filesCount)
}
}
private fun handleForwardConfirmation(
rhId: Long?,
forwardPlan: CR.ForwardPlan,
chatInfo: ChatInfo
) {
var alertDescription = if (forwardPlan.forwardConfirmation != null) forwardConfirmationAlertDescription(forwardPlan.forwardConfirmation) else ""
if (forwardPlan.chatItemIds.isNotEmpty()) {
alertDescription += "\n${generalGetString(MR.strings.forward_alert_forward_messages_without_files)}"
}
AlertManager.shared.showAlertDialogButtonsColumn(
title = if (forwardPlan.chatItemIds.isNotEmpty())
String.format(generalGetString(MR.strings.forward_alert_title_messages_to_forward), forwardPlan.chatItemIds.count()) else
generalGetString(MR.strings.forward_alert_title_nothing_to_forward),
text = alertDescription,
buttons = {
if (forwardPlan.chatItemIds.isNotEmpty()) {
when (val confirmation = forwardPlan.forwardConfirmation) {
is ForwardConfirmation.FilesNotAccepted -> {
val fillMaxWidthModifier = Modifier.fillMaxWidth()
val contentPadding = PaddingValues(vertical = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL)
Column {
ForwardButton(forwardPlan, chatInfo, fillMaxWidthModifier, contentPadding)
DownloadFilesButton(confirmation, rhId, fillMaxWidthModifier, contentPadding)
TextButton(onClick = { AlertManager.shared.hideAlert() }, modifier = fillMaxWidthModifier, contentPadding = contentPadding) {
Text(stringResource(MR.strings.cancel_verb), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
}
}
}
else -> {
ButtonRow(Arrangement.SpaceBetween) {
TextButton(onClick = { AlertManager.shared.hideAlert() }) {
Text(stringResource(MR.strings.cancel_verb), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
}
ForwardButton(forwardPlan, chatInfo)
}
}
}
} else {
when (val confirmation = forwardPlan.forwardConfirmation) {
is ForwardConfirmation.FilesNotAccepted -> {
ButtonRow(Arrangement.SpaceBetween) {
TextButton(onClick = { AlertManager.shared.hideAlert() }) {
Text(stringResource(MR.strings.cancel_verb), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
}
DownloadFilesButton(confirmation, rhId)
}
}
else -> ButtonRow(Arrangement.Center) {
TextButton(onClick = { AlertManager.shared.hideAlert() }) {
Text(stringResource(MR.strings.ok), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
}
}
}
}
}
)
}
private fun getItemSeparation(chatItem: ChatItem, nextItem: ChatItem?): ItemSeparation {
if (nextItem == null) {
return ItemSeparation(timestamp = true, largeGap = true, date = null)
}
val sameMemberAndDirection = if (nextItem.chatDir is GroupRcv && chatItem.chatDir is GroupRcv) {
chatItem.chatDir.groupMember.groupMemberId == nextItem.chatDir.groupMember.groupMemberId
} else chatItem.chatDir.sent == nextItem.chatDir.sent
val largeGap = !sameMemberAndDirection || (abs(nextItem.meta.createdAt.epochSeconds - chatItem.meta.createdAt.epochSeconds) >= 60)
return ItemSeparation(
timestamp = largeGap || nextItem.meta.timestampText != chatItem.meta.timestampText,
largeGap = largeGap,
date = if (getTimestampDateText(chatItem.meta.itemTs) == getTimestampDateText(nextItem.meta.itemTs)) null else nextItem.meta.itemTs
)
}
@Preview/*(
uiMode = Configuration.UI_MODE_NIGHT_YES,
showBackground = true,
@@ -13,6 +13,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontStyle
import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource
@@ -48,7 +49,7 @@ sealed class ComposeContextItem {
@Serializable object NoContextItem: ComposeContextItem()
@Serializable class QuotedItem(val chatItem: ChatItem): ComposeContextItem()
@Serializable class EditingItem(val chatItem: ChatItem): ComposeContextItem()
@Serializable class ForwardingItems(val chatItems: List<ChatItem>, val fromChatInfo: ChatInfo): ComposeContextItem()
@Serializable class ForwardingItem(val chatItem: ChatItem, val fromChatInfo: ChatInfo): ComposeContextItem()
}
@Serializable
@@ -84,7 +85,7 @@ data class ComposeState(
}
val forwarding: Boolean
get() = when (contextItem) {
is ComposeContextItem.ForwardingItems -> true
is ComposeContextItem.ForwardingItem -> true
else -> false
}
val sendEnabled: () -> Boolean
@@ -406,41 +407,33 @@ fun ComposeView(
return null
}
suspend fun sendMessageAsync(text: String?, live: Boolean, ttl: Int?): List<ChatItem>? {
suspend fun sendMessageAsync(text: String?, live: Boolean, ttl: Int?): ChatItem? {
val cInfo = chat.chatInfo
val cs = composeState.value
var sent: List<ChatItem>?
var sent: ChatItem?
val msgText = text ?: cs.message
fun sending() {
composeState.value = composeState.value.copy(inProgress = true)
}
suspend fun forwardItem(rhId: Long?, forwardedItem: List<ChatItem>, fromChatInfo: ChatInfo, ttl: Int?): List<ChatItem>? {
suspend fun forwardItem(rhId: Long?, forwardedItem: ChatItem, fromChatInfo: ChatInfo, ttl: Int?): ChatItem? {
val chatItems = controller.apiForwardChatItems(
rh = rhId,
toChatType = chat.chatInfo.chatType,
toChatId = chat.chatInfo.apiId,
fromChatType = fromChatInfo.chatType,
fromChatId = fromChatInfo.apiId,
itemIds = forwardedItem.map { it.id },
itemIds = listOf(forwardedItem.id),
ttl = ttl
)
chatItems?.forEach { chatItem ->
withChats {
addChatItem(rhId, chat.chatInfo, chatItem)
}
}
if (chatItems != null && chatItems.count() < forwardedItem.count()) {
AlertManager.shared.showAlertMsg(
title = String.format(generalGetString(MR.strings.forward_files_messages_deleted_after_selection_title), forwardedItem.count() - chatItems.count()),
text = generalGetString(MR.strings.forward_files_messages_deleted_after_selection_desc)
)
}
return chatItems
// TODO batch send: forward multiple messages
return chatItems?.firstOrNull()
}
fun checkLinkPreview(): MsgContent {
@@ -513,25 +506,16 @@ fun ComposeView(
if (chat.nextSendGrpInv) {
sendMemberContactInvitation()
sent = null
} else if (cs.contextItem is ComposeContextItem.ForwardingItems) {
sent = forwardItem(chat.remoteHostId, cs.contextItem.chatItems, cs.contextItem.fromChatInfo, ttl = ttl)
} else if (cs.contextItem is ComposeContextItem.ForwardingItem) {
sent = forwardItem(chat.remoteHostId, cs.contextItem.chatItem, cs.contextItem.fromChatInfo, ttl = ttl)
if (cs.message.isNotEmpty()) {
sent?.mapIndexed { index, message ->
if (index == sent!!.lastIndex) {
send(chat, checkLinkPreview(), quoted = message.id, live = false, ttl = ttl)
} else {
message
}
}
sent = send(chat, checkLinkPreview(), quoted = sent?.id, live = false, ttl = ttl)
}
}
else if (cs.contextItem is ComposeContextItem.EditingItem) {
} else if (cs.contextItem is ComposeContextItem.EditingItem) {
val ei = cs.contextItem.chatItem
val updatedMessage = updateMessage(ei, chat, live)
sent = if (updatedMessage != null) listOf(updatedMessage) else null
sent = updateMessage(ei, chat, live)
} else if (liveMessage != null && liveMessage.sent) {
val updatedMessage = updateMessage(liveMessage.chatItem, chat, live)
sent = if (updatedMessage != null) listOf(updatedMessage) else null
sent = updateMessage(liveMessage.chatItem, chat, live)
} else {
val msgs: ArrayList<MsgContent> = ArrayList()
val files: ArrayList<CryptoFile> = ArrayList()
@@ -624,23 +608,21 @@ fun ComposeView(
localPath = file.filePath
)
}
val sendResult = send(chat, content, if (index == 0) quotedItemId else null, file,
sent = send(chat, content, if (index == 0) quotedItemId else null, file,
live = if (content !is MsgContent.MCVoice && index == msgs.lastIndex) live else false,
ttl = ttl
)
sent = if (sendResult != null) listOf(sendResult) else null
}
if (sent == null &&
(cs.preview is ComposePreview.MediaPreview ||
cs.preview is ComposePreview.FilePreview ||
cs.preview is ComposePreview.VoicePreview)
) {
val sendResult = send(chat, MsgContent.MCText(msgText), quotedItemId, null, live, ttl)
sent = if (sendResult != null) listOf(sendResult) else null
sent = send(chat, MsgContent.MCText(msgText), quotedItemId, null, live, ttl)
}
}
val wasForwarding = cs.forwarding
val forwardingFromChatId = (cs.contextItem as? ComposeContextItem.ForwardingItems)?.fromChatInfo?.id
val forwardingFromChatId = (cs.contextItem as? ComposeContextItem.ForwardingItem)?.fromChatInfo?.id
clearState(live)
val draft = chatModel.draft.value
if (wasForwarding && chatModel.draftChatId.value == chat.chatInfo.id && forwardingFromChatId != chat.chatInfo.id && draft != null) {
@@ -742,8 +724,8 @@ fun ComposeView(
val typedMsg = cs.message
if ((cs.sendEnabled() || cs.contextItem is ComposeContextItem.QuotedItem) && (cs.liveMessage == null || !cs.liveMessage.sent)) {
val ci = sendMessageAsync(typedMsg, live = true, ttl = null)
if (!ci.isNullOrEmpty()) {
composeState.value = composeState.value.copy(liveMessage = LiveMessage(ci.last(), typedMsg = typedMsg, sentMsg = typedMsg, sent = true))
if (ci != null) {
composeState.value = composeState.value.copy(liveMessage = LiveMessage(ci, typedMsg = typedMsg, sentMsg = typedMsg, sent = true))
}
} else if (cs.liveMessage == null) {
val cItem = chatModel.addLiveDummy(chat.chatInfo)
@@ -763,8 +745,8 @@ fun ComposeView(
val sentMsg = liveMessageToSend(liveMessage, typedMsg)
if (sentMsg != null) {
val ci = sendMessageAsync(sentMsg, live = true, ttl = null)
if (!ci.isNullOrEmpty()) {
composeState.value = composeState.value.copy(liveMessage = LiveMessage(ci.last(), typedMsg = typedMsg, sentMsg = sentMsg, sent = true))
if (ci != null) {
composeState.value = composeState.value.copy(liveMessage = LiveMessage(ci, typedMsg = typedMsg, sentMsg = sentMsg, sent = true))
}
} else if (liveMessage.typedMsg != typedMsg) {
composeState.value = composeState.value.copy(liveMessage = liveMessage.copy(typedMsg = typedMsg))
@@ -823,13 +805,13 @@ fun ComposeView(
fun contextItemView() {
when (val contextItem = composeState.value.contextItem) {
ComposeContextItem.NoContextItem -> {}
is ComposeContextItem.QuotedItem -> ContextItemView(listOf(contextItem.chatItem), painterResource(MR.images.ic_reply), chatType = chat.chatInfo.chatType) {
is ComposeContextItem.QuotedItem -> ContextItemView(contextItem.chatItem, painterResource(MR.images.ic_reply)) {
composeState.value = composeState.value.copy(contextItem = ComposeContextItem.NoContextItem)
}
is ComposeContextItem.EditingItem -> ContextItemView(listOf(contextItem.chatItem), painterResource(MR.images.ic_edit_filled), chatType = chat.chatInfo.chatType) {
is ComposeContextItem.EditingItem -> ContextItemView(contextItem.chatItem, painterResource(MR.images.ic_edit_filled)) {
clearState()
}
is ComposeContextItem.ForwardingItems -> ContextItemView(contextItem.chatItems, painterResource(MR.images.ic_forward), showSender = false, chatType = chat.chatInfo.chatType) {
is ComposeContextItem.ForwardingItem -> ContextItemView(contextItem.chatItem, painterResource(MR.images.ic_forward), showSender = false) {
composeState.value = composeState.value.copy(contextItem = ComposeContextItem.NoContextItem)
}
}
@@ -852,7 +834,7 @@ fun ComposeView(
is SharedContent.Media -> composeState.processPickedMedia(shared.uris, shared.text)
is SharedContent.File -> composeState.processPickedFile(shared.uri, shared.text)
is SharedContent.Forward -> composeState.value = composeState.value.copy(
contextItem = ComposeContextItem.ForwardingItems(shared.chatItems, shared.fromChatInfo),
contextItem = ComposeContextItem.ForwardingItem(shared.chatItem, shared.fromChatInfo),
preview = if (composeState.value.preview is ComposePreview.CLinkPreview) composeState.value.preview else ComposePreview.NoPreview
)
null -> {}
@@ -13,31 +13,28 @@ import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.foundation.text.appendInlineContent
import androidx.compose.runtime.*
import androidx.compose.ui.text.*
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import chat.simplex.common.ui.theme.*
import chat.simplex.common.views.chat.item.*
import chat.simplex.common.model.*
import chat.simplex.common.platform.getLoadedFilePath
import chat.simplex.common.views.helpers.*
import chat.simplex.res.MR
import dev.icerock.moko.resources.ImageResource
import kotlinx.datetime.Clock
@Composable
fun ContextItemView(
contextItems: List<ChatItem>,
contextItem: ChatItem,
contextIcon: Painter,
showSender: Boolean = true,
chatType: ChatType,
cancelContextItem: () -> Unit,
cancelContextItem: () -> Unit
) {
val sent = contextItem.chatDir.sent
val sentColor = MaterialTheme.appColors.sentMessage
val receivedColor = MaterialTheme.appColors.receivedMessage
@Composable
fun MessageText(contextItem: ChatItem, attachment: ImageResource?, lines: Int) {
fun MessageText(attachment: ImageResource?, lines: Int) {
val inlineContent: Pair<AnnotatedString.Builder.() -> Unit, Map<String, InlineTextContent>>? = if (attachment != null) {
remember(contextItem.id) {
val inlineContentBuilder: AnnotatedString.Builder.() -> Unit = {
@@ -65,24 +62,19 @@ fun ContextItemView(
)
}
fun attachment(contextItem: ChatItem): ImageResource? {
val fileIsLoaded = getLoadedFilePath(contextItem.file) != null
return when (contextItem.content.msgContent) {
is MsgContent.MCFile -> if (fileIsLoaded) MR.images.ic_draft_filled else null
fun attachment(): ImageResource? =
when (contextItem.content.msgContent) {
is MsgContent.MCFile -> MR.images.ic_draft_filled
is MsgContent.MCImage -> MR.images.ic_image
is MsgContent.MCVoice -> if (fileIsLoaded) MR.images.ic_play_arrow_filled else null
is MsgContent.MCVoice -> MR.images.ic_play_arrow_filled
else -> null
}
}
@Composable
fun ContextMsgPreview(contextItem: ChatItem, lines: Int) {
MessageText(contextItem, remember(contextItem.id) { attachment(contextItem) }, lines)
fun ContextMsgPreview(lines: Int) {
MessageText(remember(contextItem.id) { attachment() }, lines)
}
val sent = contextItems[0].chatDir.sent
Row(
Modifier
.padding(top = 8.dp)
@@ -105,27 +97,20 @@ fun ContextItemView(
contentDescription = stringResource(MR.strings.icon_descr_context),
tint = MaterialTheme.colors.secondary,
)
if (contextItems.count() == 1) {
val contextItem = contextItems[0]
val sender = contextItem.memberDisplayName
if (showSender && sender != null) {
Column(
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
Text(
sender,
style = TextStyle(fontSize = 13.5.sp, color = CurrentColors.value.colors.secondary)
)
ContextMsgPreview(contextItem, lines = 2)
}
} else {
ContextMsgPreview(contextItem, lines = 3)
val sender = contextItem.memberDisplayName
if (showSender && sender != null) {
Column(
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
Text(
sender,
style = TextStyle(fontSize = 13.5.sp, color = CurrentColors.value.colors.secondary)
)
ContextMsgPreview(lines = 2)
}
} else if (contextItems.isNotEmpty()) {
Text(String.format(generalGetString(if (chatType == ChatType.Local) MR.strings.compose_save_messages_n else MR.strings.compose_forward_messages_n), contextItems.count()), fontStyle = FontStyle.Italic)
} else {
ContextMsgPreview(lines = 3)
}
}
IconButton(onClick = cancelContextItem) {
@@ -144,9 +129,8 @@ fun ContextItemView(
fun PreviewContextItemView() {
SimpleXTheme {
ContextItemView(
contextItems = listOf(ChatItem.getSampleData(1, CIDirection.DirectRcv(), Clock.System.now(), "hello")),
contextIcon = painterResource(MR.images.ic_edit_filled),
chatType = ChatType.Direct
contextItem = ChatItem.getSampleData(1, CIDirection.DirectRcv(), Clock.System.now(), "hello"),
contextIcon = painterResource(MR.images.ic_edit_filled)
) {}
}
}
@@ -7,7 +7,6 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@@ -52,29 +51,17 @@ fun SelectedItemsBottomToolbar(
selectedChatItems: MutableState<Set<Long>?>,
deleteItems: (Boolean) -> Unit, // Boolean - delete for everyone is possible
moderateItems: () -> Unit,
forwardItems: () -> Unit,
// shareItems: () -> Unit,
) {
val deleteEnabled = remember { mutableStateOf(false) }
val deleteForEveryoneEnabled = remember { mutableStateOf(false) }
val canModerate = remember { mutableStateOf(false) }
val moderateEnabled = remember { mutableStateOf(false) }
val forwardEnabled = remember { mutableStateOf(false) }
val allButtonsDisabled = remember { mutableStateOf(false) }
Box {
// It's hard to measure exact height of ComposeView with different fontSizes. Better to depend on actual ComposeView, even empty
ComposeView(chatModel = chatModel, Chat.sampleData, remember { mutableStateOf(ComposeState(useLinkPreviews = false)) }, remember { mutableStateOf(null) }, {})
Row(
Modifier
.matchParentSize()
.background(MaterialTheme.colors.background)
.pointerInput(Unit) {
detectGesture {
true
}
},
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(Modifier.matchParentSize().background(MaterialTheme.colors.background), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
IconButton({ deleteItems(deleteForEveryoneEnabled.value) }, enabled = deleteEnabled.value && !allButtonsDisabled.value) {
Icon(
painterResource(MR.images.ic_delete),
@@ -93,18 +80,18 @@ fun SelectedItemsBottomToolbar(
)
}
IconButton({ forwardItems() }, enabled = forwardEnabled.value && !allButtonsDisabled.value) {
IconButton({ /*shareItems()*/ }, Modifier.alpha(0f), enabled = false/*!allButtonsDisabled.value*/) {
Icon(
painterResource(MR.images.ic_forward),
painterResource(MR.images.ic_share),
null,
Modifier.size(22.dp),
tint = if (!forwardEnabled.value || allButtonsDisabled.value) MaterialTheme.colors.secondary else MaterialTheme.colors.primary
tint = if (allButtonsDisabled.value) MaterialTheme.colors.secondary else MaterialTheme.colors.primary
)
}
}
}
LaunchedEffect(chatInfo, chatItems, selectedChatItems.value) {
recheckItems(chatInfo, chatItems, selectedChatItems, deleteEnabled, deleteForEveryoneEnabled, canModerate, moderateEnabled, forwardEnabled, allButtonsDisabled)
recheckItems(chatInfo, chatItems, selectedChatItems, deleteEnabled, deleteForEveryoneEnabled, canModerate, moderateEnabled, allButtonsDisabled)
}
}
@@ -115,7 +102,6 @@ private fun recheckItems(chatInfo: ChatInfo,
deleteForEveryoneEnabled: MutableState<Boolean>,
canModerate: MutableState<Boolean>,
moderateEnabled: MutableState<Boolean>,
forwardEnabled: MutableState<Boolean>,
allButtonsDisabled: MutableState<Boolean>
) {
val count = selectedChatItems.value?.size ?: 0
@@ -126,7 +112,6 @@ private fun recheckItems(chatInfo: ChatInfo,
var rDeleteForEveryoneEnabled = true
var rModerateEnabled = true
var rOnlyOwnGroupItems = true
var rForwardEnabled = true
val rSelectedChatItems = mutableSetOf<Long>()
for (ci in chatItems) {
if (selected.contains(ci.id)) {
@@ -134,7 +119,6 @@ private fun recheckItems(chatInfo: ChatInfo,
rDeleteForEveryoneEnabled = rDeleteForEveryoneEnabled && ci.meta.deletable && !ci.localNote
rOnlyOwnGroupItems = rOnlyOwnGroupItems && ci.chatDir is CIDirection.GroupSnd
rModerateEnabled = rModerateEnabled && ci.content.msgContent != null && ci.memberToModerate(chatInfo) != null
rForwardEnabled = rForwardEnabled && ci.content.msgContent != null && ci.meta.itemDeleted == null && !ci.isLiveDummy
rSelectedChatItems.add(ci.id) // we are collecting new selected items here to account for any changes in chat items list
}
}
@@ -142,7 +126,6 @@ private fun recheckItems(chatInfo: ChatInfo,
deleteEnabled.value = rDeleteEnabled
deleteForEveryoneEnabled.value = rDeleteForEveryoneEnabled
moderateEnabled.value = rModerateEnabled
forwardEnabled.value = rForwardEnabled
selectedChatItems.value = rSelectedChatItems
}
@@ -665,8 +665,9 @@ private fun updateMemberRoleDialog(
fun connectViaMemberAddressAlert(rhId: Long?, connReqUri: String) {
try {
val uri = URI(connReqUri)
withBGApi {
planAndConnect(rhId, connReqUri, incognito = null, close = { ModalManager.closeAllModalsEverywhere() })
planAndConnect(rhId, uri, incognito = null, close = { ModalManager.closeAllModalsEverywhere() })
}
} catch (e: RuntimeException) {
AlertManager.shared.showAlertMsg(
@@ -20,7 +20,6 @@ fun CICallItemView(
cItem: ChatItem,
status: CICallStatus,
duration: Int,
showTimestamp: Boolean,
acceptCall: (Contact) -> Unit,
timedMessagesTTL: Int?
) {
@@ -48,7 +47,7 @@ fun CICallItemView(
CICallStatus.Error -> {}
}
CIMetaView(cItem, timedMessagesTTL, showStatus = false, showEdited = false, showViaProxy = false, showTimestamp = showTimestamp)
CIMetaView(cItem, timedMessagesTTL, showStatus = false, showEdited = false, showViaProxy = false)
}
}
@@ -26,7 +26,6 @@ fun CIGroupInvitationView(
ci: ChatItem,
groupInvitation: CIGroupInvitation,
memberRole: GroupMemberRole,
showTimestamp: Boolean,
chatIncognito: Boolean = false,
joinGroup: (Long, () -> Unit) -> Unit,
timedMessagesTTL: Int?
@@ -119,7 +118,7 @@ fun CIGroupInvitationView(
Text(
buildAnnotatedString {
append(generalGetString(if (chatIncognito) MR.strings.group_invitation_tap_to_join_incognito else MR.strings.group_invitation_tap_to_join))
withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, timedMessagesTTL, encrypted = null, showStatus = false, showEdited = false, secondaryColor = secondaryColor, showTimestamp = showTimestamp)) }
withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, timedMessagesTTL, encrypted = null, showStatus = false, showEdited = false, secondaryColor = secondaryColor)) }
},
color = if (inProgress.value)
MaterialTheme.colors.secondary
@@ -130,7 +129,7 @@ fun CIGroupInvitationView(
Text(
buildAnnotatedString {
append(groupInvitationStr())
withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, timedMessagesTTL, encrypted = null, showStatus = false, showEdited = false, secondaryColor = secondaryColor, showTimestamp = showTimestamp)) }
withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, timedMessagesTTL, encrypted = null, showStatus = false, showEdited = false, secondaryColor = secondaryColor)) }
}
)
}
@@ -146,7 +145,7 @@ fun CIGroupInvitationView(
}
}
CIMetaView(ci, timedMessagesTTL, showStatus = false, showEdited = false, showViaProxy = false, showTimestamp = showTimestamp)
CIMetaView(ci, timedMessagesTTL, showStatus = false, showEdited = false, showViaProxy = false)
}
}
}
@@ -163,8 +162,7 @@ fun PendingCIGroupInvitationViewPreview() {
groupInvitation = CIGroupInvitation.getSample(),
memberRole = GroupMemberRole.Admin,
joinGroup = { _, _ -> },
timedMessagesTTL = null,
showTimestamp = true,
timedMessagesTTL = null
)
}
}
@@ -181,9 +179,8 @@ fun CIGroupInvitationViewAcceptedPreview() {
groupInvitation = CIGroupInvitation.getSample(status = CIGroupInvitationStatus.Accepted),
memberRole = GroupMemberRole.Admin,
joinGroup = { _, _ -> },
timedMessagesTTL = null,
showTimestamp = true,
)
timedMessagesTTL = null
)
}
}
@@ -199,8 +196,7 @@ fun CIGroupInvitationViewLongNamePreview() {
),
memberRole = GroupMemberRole.Admin,
joinGroup = { _, _ -> },
timedMessagesTTL = null,
showTimestamp = true,
)
timedMessagesTTL = null
)
}
}
@@ -35,8 +35,7 @@ fun CIMetaView(
},
showStatus: Boolean = true,
showEdited: Boolean = true,
showTimestamp: Boolean,
showViaProxy: Boolean,
showViaProxy: Boolean
) {
Row(Modifier.padding(start = 3.dp), verticalAlignment = Alignment.CenterVertically) {
if (chatItem.isDeletedContent) {
@@ -55,8 +54,7 @@ fun CIMetaView(
paleMetaColor,
showStatus = showStatus,
showEdited = showEdited,
showViaProxy = showViaProxy,
showTimestamp = showTimestamp
showViaProxy = showViaProxy
)
}
}
@@ -72,11 +70,11 @@ private fun CIMetaText(
paleColor: Color,
showStatus: Boolean = true,
showEdited: Boolean = true,
showTimestamp: Boolean,
showViaProxy: Boolean,
showViaProxy: Boolean
) {
if (showEdited && meta.itemEdited) {
StatusIconText(painterResource(MR.images.ic_edit), color)
Spacer(Modifier.width(3.dp))
}
if (meta.disappearing) {
StatusIconText(painterResource(MR.images.ic_timer), color)
@@ -84,13 +82,12 @@ private fun CIMetaText(
if (ttl != chatTTL) {
Text(shortTimeText(ttl), color = color, fontSize = 12.sp)
}
Spacer(Modifier.width(4.dp))
}
if (showViaProxy && meta.sentViaProxy == true) {
Spacer(Modifier.width(4.dp))
Icon(painterResource(MR.images.ic_arrow_forward), null, Modifier.height(17.dp), tint = MaterialTheme.colors.secondary)
}
if (showStatus) {
Spacer(Modifier.width(4.dp))
val statusIcon = meta.statusIcon(MaterialTheme.colors.primary, color, paleColor)
if (statusIcon != null) {
val (icon, statusColor) = statusIcon
@@ -99,19 +96,17 @@ private fun CIMetaText(
} else {
StatusIconText(painterResource(icon), statusColor)
}
Spacer(Modifier.width(4.dp))
} else if (!meta.disappearing) {
StatusIconText(painterResource(MR.images.ic_circle_filled), Color.Transparent)
Spacer(Modifier.width(4.dp))
}
}
if (encrypted != null) {
Spacer(Modifier.width(4.dp))
StatusIconText(painterResource(if (encrypted) MR.images.ic_lock else MR.images.ic_lock_open_right), color)
}
if (showTimestamp) {
Spacer(Modifier.width(4.dp))
Text(meta.timestampText, color = color, fontSize = 12.sp, maxLines = 1, overflow = TextOverflow.Ellipsis)
}
Text(meta.timestampText, color = color, fontSize = 12.sp, maxLines = 1, overflow = TextOverflow.Ellipsis)
}
// the conditions in this function should match CIMetaText
@@ -122,56 +117,28 @@ fun reserveSpaceForMeta(
secondaryColor: Color,
showStatus: Boolean = true,
showEdited: Boolean = true,
showViaProxy: Boolean = false,
showTimestamp: Boolean
showViaProxy: Boolean = false
): String {
val iconSpace = " "
val whiteSpace = " "
var res = iconSpace
var space: String? = null
fun appendSpace() {
if (space != null) {
res += space
space = null
}
}
if (showEdited && meta.itemEdited) {
res += iconSpace
}
var res = ""
if (showEdited && meta.itemEdited) res += iconSpace
if (meta.itemTimed != null) {
res += iconSpace
val ttl = meta.itemTimed.ttl
if (ttl != chatTTL) {
res += shortTimeText(ttl)
}
space = whiteSpace
}
if (showViaProxy && meta.sentViaProxy == true) {
appendSpace()
res += iconSpace
}
if (showStatus) {
appendSpace()
if (meta.statusIcon(secondaryColor) != null) {
res += iconSpace
} else if (!meta.disappearing) {
res += iconSpace
}
space = whiteSpace
if (showStatus && (meta.statusIcon(secondaryColor) != null || !meta.disappearing)) {
res += iconSpace
}
if (encrypted != null) {
appendSpace()
res += iconSpace
space = whiteSpace
}
if (showTimestamp) {
appendSpace()
res += meta.timestampText
}
return res
return res + meta.timestampText
}
@Composable
@@ -187,8 +154,7 @@ fun PreviewCIMetaView() {
1, CIDirection.DirectSnd(), Clock.System.now(), "hello"
),
null,
showViaProxy = false,
showTimestamp = true
showViaProxy = false
)
}
@@ -201,8 +167,7 @@ fun PreviewCIMetaViewUnread() {
status = CIStatus.RcvNew()
),
null,
showViaProxy = false,
showTimestamp = true
showViaProxy = false
)
}
@@ -215,8 +180,7 @@ fun PreviewCIMetaViewSendFailed() {
status = CIStatus.CISSndError(SndError.Other("CMD SYNTAX"))
),
null,
showViaProxy = false,
showTimestamp = true
showViaProxy = false
)
}
@@ -228,8 +192,7 @@ fun PreviewCIMetaViewSendNoAuth() {
1, CIDirection.DirectSnd(), Clock.System.now(), "hello", status = CIStatus.SndErrorAuth()
),
null,
showViaProxy = false,
showTimestamp = true
showViaProxy = false
)
}
@@ -241,8 +204,7 @@ fun PreviewCIMetaViewSendSent() {
1, CIDirection.DirectSnd(), Clock.System.now(), "hello", status = CIStatus.SndSent(SndCIStatusProgress.Complete)
),
null,
showViaProxy = false,
showTimestamp = true
showViaProxy = false
)
}
@@ -255,8 +217,7 @@ fun PreviewCIMetaViewEdited() {
itemEdited = true
),
null,
showViaProxy = false,
showTimestamp = true
showViaProxy = false
)
}
@@ -270,8 +231,7 @@ fun PreviewCIMetaViewEditedUnread() {
status= CIStatus.RcvNew()
),
null,
showViaProxy = false,
showTimestamp = true
showViaProxy = false
)
}
@@ -285,8 +245,7 @@ fun PreviewCIMetaViewEditedSent() {
status= CIStatus.SndSent(SndCIStatusProgress.Complete)
),
null,
showViaProxy = false,
showTimestamp = true
showViaProxy = false
)
}
@@ -296,7 +255,6 @@ fun PreviewCIMetaViewDeletedContent() {
CIMetaView(
chatItem = ChatItem.getDeletedContentSampleData(),
null,
showViaProxy = false,
showTimestamp = true
showViaProxy = false
)
}
@@ -169,14 +169,14 @@ fun DecryptionErrorItemFixButton(
Text(
buildAnnotatedString {
append(generalGetString(MR.strings.fix_connection))
withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, null, encrypted = null, secondaryColor = secondaryColor, showTimestamp = true)) }
withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, null, encrypted = null, secondaryColor = secondaryColor)) }
withStyle(reserveTimestampStyle) { append(" ") } // for icon
},
color = if (syncSupported) MaterialTheme.colors.primary else MaterialTheme.colors.secondary
)
}
}
CIMetaView(ci, timedMessagesTTL = null, showViaProxy = false, showTimestamp = true)
CIMetaView(ci, timedMessagesTTL = null, showViaProxy = false)
}
}
}
@@ -201,11 +201,11 @@ fun DecryptionErrorItem(
Text(
buildAnnotatedString {
withStyle(SpanStyle(fontStyle = FontStyle.Italic, color = Color.Red)) { append(ci.content.text) }
withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, null, encrypted = null, secondaryColor = secondaryColor, showTimestamp = true)) }
withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, null, encrypted = null, secondaryColor = secondaryColor)) }
},
style = MaterialTheme.typography.body1.copy(lineHeight = 22.sp)
)
CIMetaView(ci, timedMessagesTTL = null, showViaProxy = false, showTimestamp = true)
CIMetaView(ci, timedMessagesTTL = null, showViaProxy = false)
}
}
}
@@ -38,7 +38,6 @@ fun CIVoiceView(
ci: ChatItem,
timedMessagesTTL: Int?,
showViaProxy: Boolean,
showTimestamp: Boolean,
smallView: Boolean = false,
longClick: () -> Unit,
receiveFile: (Long) -> Unit,
@@ -87,7 +86,7 @@ fun CIVoiceView(
durationText(time / 1000)
}
}
VoiceLayout(file, ci, text, audioPlaying, progress, duration, brokenAudio, sent, hasText, timedMessagesTTL, showViaProxy, showTimestamp, sizeMultiplier, play, pause, longClick, receiveFile) {
VoiceLayout(file, ci, text, audioPlaying, progress, duration, brokenAudio, sent, hasText, timedMessagesTTL, showViaProxy, sizeMultiplier, play, pause, longClick, receiveFile) {
AudioPlayer.seekTo(it, progress, fileSource.value?.filePath)
}
if (smallView) {
@@ -121,7 +120,6 @@ private fun VoiceLayout(
hasText: Boolean,
timedMessagesTTL: Int?,
showViaProxy: Boolean,
showTimestamp: Boolean,
sizeMultiplier: Float,
play: () -> Unit,
pause: () -> Unit,
@@ -202,7 +200,7 @@ private fun VoiceLayout(
VoiceMsgIndicator(file, audioPlaying.value, sent, hasText, progress, duration, brokenAudio, 1f, play, pause, longClick, receiveFile)
}
Box(Modifier.padding(top = 6.sp.toDp() * sizeMultiplier, end = 6.sp.toDp() * sizeMultiplier)) {
CIMetaView(ci, timedMessagesTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMetaView(ci, timedMessagesTTL, showViaProxy = showViaProxy)
}
}
}
@@ -217,7 +215,7 @@ private fun VoiceLayout(
}
}
Box(Modifier.padding(top = 6.sp.toDp() * sizeMultiplier)) {
CIMetaView(ci, timedMessagesTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMetaView(ci, timedMessagesTTL, showViaProxy = showViaProxy)
}
}
}
@@ -51,7 +51,6 @@ fun ChatItemView(
revealed: MutableState<Boolean>,
range: IntRange?,
selectedChatItems: MutableState<Set<Long>?>,
fillMaxWidth: Boolean = true,
selectChatItem: () -> Unit,
deleteMessage: (Long, CIDeleteMode) -> Unit,
deleteMessages: (List<Long>) -> Unit,
@@ -73,7 +72,6 @@ fun ChatItemView(
showItemDetails: (ChatInfo, ChatItem) -> Unit,
developerTools: Boolean,
showViaProxy: Boolean,
showTimestamp: Boolean,
preview: Boolean = false,
) {
val uriHandler = LocalUriHandler.current
@@ -85,7 +83,7 @@ fun ChatItemView(
val live = composeState.value.liveMessage != null
Box(
modifier = if (fillMaxWidth) Modifier.fillMaxWidth() else Modifier,
modifier = Modifier.fillMaxWidth(),
contentAlignment = alignment,
) {
val info = cItem.meta.itemStatus.statusInto
@@ -133,7 +131,7 @@ fun ChatItemView(
) {
@Composable
fun framedItemView() {
FramedItemView(cInfo, cItem, uriHandler, imageProvider, linkMode = linkMode, showViaProxy = showViaProxy, showMenu, showTimestamp = showTimestamp, receiveFile, onLinkLongClick, scrollToItem)
FramedItemView(cInfo, cItem, uriHandler, imageProvider, linkMode = linkMode, showViaProxy = showViaProxy, showMenu, receiveFile, onLinkLongClick, scrollToItem)
}
fun deleteMessageQuestionText(): String {
@@ -356,14 +354,14 @@ fun ChatItemView(
fun ContentItem() {
val mc = cItem.content.msgContent
if (cItem.meta.itemDeleted != null && (!revealed.value || cItem.isDeletedContent)) {
MarkedDeletedItemView(cItem, cInfo.timedMessagesTTL, revealed, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
MarkedDeletedItemView(cItem, cInfo.timedMessagesTTL, revealed, showViaProxy = showViaProxy)
MarkedDeletedItemDropdownMenu()
} else {
if (cItem.quotedItem == null && cItem.meta.itemForwarded == null && cItem.meta.itemDeleted == null && !cItem.meta.isLive) {
if (mc is MsgContent.MCText && isShortEmoji(cItem.content.text)) {
EmojiItemView(cItem, cInfo.timedMessagesTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
EmojiItemView(cItem, cInfo.timedMessagesTTL, showViaProxy = showViaProxy)
} else if (mc is MsgContent.MCVoice && cItem.content.text.isEmpty()) {
CIVoiceView(mc.duration, cItem.file, cItem.meta.itemEdited, cItem.chatDir.sent, hasText = false, cItem, cInfo.timedMessagesTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp, longClick = { onLinkLongClick("") }, receiveFile = receiveFile)
CIVoiceView(mc.duration, cItem.file, cItem.meta.itemEdited, cItem.chatDir.sent, hasText = false, cItem, cInfo.timedMessagesTTL, showViaProxy = showViaProxy, longClick = { onLinkLongClick("") }, receiveFile = receiveFile)
} else {
framedItemView()
}
@@ -375,7 +373,7 @@ fun ChatItemView(
}
@Composable fun LegacyDeletedItem() {
DeletedItemView(cItem, cInfo.timedMessagesTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
DeletedItemView(cItem, cInfo.timedMessagesTTL, showViaProxy = showViaProxy)
DefaultDropdownMenu(showMenu) {
ItemInfoAction(cInfo, cItem, showItemDetails, showMenu)
DeleteItemAction(cItem, revealed, showMenu, questionText = deleteMessageQuestionText(), deleteMessage, deleteMessages)
@@ -387,7 +385,7 @@ fun ChatItemView(
}
@Composable fun CallItem(status: CICallStatus, duration: Int) {
CICallItemView(cInfo, cItem, status, duration, showTimestamp = showTimestamp, acceptCall, cInfo.timedMessagesTTL)
CICallItemView(cInfo, cItem, status, duration, acceptCall, cInfo.timedMessagesTTL)
DeleteItemMenu()
}
@@ -432,7 +430,7 @@ fun ChatItemView(
@Composable
fun DeletedItem() {
MarkedDeletedItemView(cItem, cInfo.timedMessagesTTL, revealed, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
MarkedDeletedItemView(cItem, cInfo.timedMessagesTTL, revealed, showViaProxy = showViaProxy)
DefaultDropdownMenu(showMenu) {
ItemInfoAction(cInfo, cItem, showItemDetails, showMenu)
DeleteItemAction(cItem, revealed, showMenu, questionText = generalGetString(MR.strings.delete_message_cannot_be_undone_warning), deleteMessage, deleteMessages)
@@ -475,7 +473,7 @@ fun ChatItemView(
is CIContent.SndCall -> CallItem(c.status, c.duration)
is CIContent.RcvCall -> CallItem(c.status, c.duration)
is CIContent.RcvIntegrityError -> if (developerTools) {
IntegrityErrorItemView(c.msgError, cItem, showTimestamp, cInfo.timedMessagesTTL)
IntegrityErrorItemView(c.msgError, cItem, cInfo.timedMessagesTTL)
DeleteItemMenu()
} else {
Box(Modifier.size(0.dp)) {}
@@ -485,11 +483,11 @@ fun ChatItemView(
DeleteItemMenu()
}
is CIContent.RcvGroupInvitation -> {
CIGroupInvitationView(cItem, c.groupInvitation, c.memberRole, joinGroup = joinGroup, chatIncognito = cInfo.incognito, showTimestamp = showTimestamp, timedMessagesTTL = cInfo.timedMessagesTTL)
CIGroupInvitationView(cItem, c.groupInvitation, c.memberRole, joinGroup = joinGroup, chatIncognito = cInfo.incognito, timedMessagesTTL = cInfo.timedMessagesTTL)
DeleteItemMenu()
}
is CIContent.SndGroupInvitation -> {
CIGroupInvitationView(cItem, c.groupInvitation, c.memberRole, joinGroup = joinGroup, chatIncognito = cInfo.incognito, showTimestamp = showTimestamp, timedMessagesTTL = cInfo.timedMessagesTTL)
CIGroupInvitationView(cItem, c.groupInvitation, c.memberRole, joinGroup = joinGroup, chatIncognito = cInfo.incognito, timedMessagesTTL = cInfo.timedMessagesTTL)
DeleteItemMenu()
}
is CIContent.RcvDirectEventContent -> {
@@ -929,7 +927,6 @@ fun PreviewChatItemView(
showItemDetails = { _, _ -> },
developerTools = false,
showViaProxy = false,
showTimestamp = true,
preview = true,
)
}
@@ -970,7 +967,6 @@ fun PreviewChatItemViewDeletedContent() {
developerTools = false,
showViaProxy = false,
preview = true,
showTimestamp = true
)
}
}
@@ -16,7 +16,7 @@ import chat.simplex.common.model.ChatItem
import chat.simplex.common.ui.theme.*
@Composable
fun DeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, showViaProxy: Boolean, showTimestamp: Boolean) {
fun DeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, showViaProxy: Boolean) {
val sent = ci.chatDir.sent
val sentColor = MaterialTheme.appColors.sentMessage
val receivedColor = MaterialTheme.appColors.receivedMessage
@@ -36,7 +36,7 @@ fun DeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, showViaProxy: Boolean,
style = MaterialTheme.typography.body1.copy(lineHeight = 22.sp),
modifier = Modifier.padding(end = 8.dp)
)
CIMetaView(ci, timedMessagesTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMetaView(ci, timedMessagesTTL, showViaProxy = showViaProxy)
}
}
}
@@ -51,8 +51,7 @@ fun PreviewDeletedItemView() {
DeletedItemView(
ChatItem.getDeletedContentSampleData(),
null,
showViaProxy = false,
showTimestamp = true
showViaProxy = false
)
}
}
@@ -12,19 +12,18 @@ import androidx.compose.ui.unit.sp
import chat.simplex.common.model.ChatItem
import chat.simplex.common.model.MREmojiChar
import chat.simplex.common.ui.theme.EmojiFont
import java.sql.Timestamp
val largeEmojiFont: TextStyle = TextStyle(fontSize = 48.sp, fontFamily = EmojiFont)
val mediumEmojiFont: TextStyle = TextStyle(fontSize = 36.sp, fontFamily = EmojiFont)
@Composable
fun EmojiItemView(chatItem: ChatItem, timedMessagesTTL: Int?, showViaProxy: Boolean, showTimestamp: Boolean) {
fun EmojiItemView(chatItem: ChatItem, timedMessagesTTL: Int?, showViaProxy: Boolean) {
Column(
Modifier.padding(vertical = 8.dp, horizontal = 12.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
EmojiText(chatItem.content.text)
CIMetaView(chatItem, timedMessagesTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMetaView(chatItem, timedMessagesTTL, showViaProxy = showViaProxy)
}
}
@@ -35,7 +35,6 @@ fun FramedItemView(
linkMode: SimplexLinkMode,
showViaProxy: Boolean,
showMenu: MutableState<Boolean>,
showTimestamp: Boolean,
receiveFile: (Long) -> Unit,
onLinkLongClick: (link: String) -> Unit = {},
scrollToItem: (Long) -> Unit = {},
@@ -48,7 +47,7 @@ fun FramedItemView(
}
@Composable
fun ciQuotedMsgTextView(qi: CIQuote, lines: Int, showTimestamp: Boolean) {
fun ciQuotedMsgTextView(qi: CIQuote, lines: Int) {
MarkdownText(
qi.text,
qi.formattedText,
@@ -57,8 +56,7 @@ fun FramedItemView(
overflow = TextOverflow.Ellipsis,
style = TextStyle(fontSize = 15.sp, color = MaterialTheme.colors.onSurface),
linkMode = linkMode,
uriHandler = if (appPlatform.isDesktop) uriHandler else null,
showTimestamp = showTimestamp
uriHandler = if (appPlatform.isDesktop) uriHandler else null
)
}
@@ -78,10 +76,10 @@ fun FramedItemView(
style = TextStyle(fontSize = 13.5.sp, color = CurrentColors.value.colors.secondary),
maxLines = 1
)
ciQuotedMsgTextView(qi, lines = 2, showTimestamp = showTimestamp)
ciQuotedMsgTextView(qi, lines = 2)
}
} else {
ciQuotedMsgTextView(qi, lines = 3, showTimestamp = showTimestamp)
ciQuotedMsgTextView(qi, lines = 3)
}
}
}
@@ -180,7 +178,7 @@ fun FramedItemView(
fun ciFileView(ci: ChatItem, text: String) {
CIFileView(ci.file, ci.meta.itemEdited, showMenu, false, receiveFile)
if (text != "" || ci.meta.isLive) {
CIMarkdownText(ci, chatTTL, linkMode = linkMode, uriHandler, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMarkdownText(ci, chatTTL, linkMode = linkMode, uriHandler, showViaProxy = showViaProxy)
}
}
@@ -244,7 +242,7 @@ fun FramedItemView(
if (mc.text == "" && !ci.meta.isLive) {
metaColor = Color.White
} else {
CIMarkdownText(ci, chatTTL, linkMode, uriHandler, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMarkdownText(ci, chatTTL, linkMode, uriHandler, showViaProxy = showViaProxy)
}
}
is MsgContent.MCVideo -> {
@@ -252,35 +250,35 @@ fun FramedItemView(
if (mc.text == "" && !ci.meta.isLive) {
metaColor = Color.White
} else {
CIMarkdownText(ci, chatTTL, linkMode, uriHandler, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMarkdownText(ci, chatTTL, linkMode, uriHandler, showViaProxy = showViaProxy)
}
}
is MsgContent.MCVoice -> {
CIVoiceView(mc.duration, ci.file, ci.meta.itemEdited, ci.chatDir.sent, hasText = true, ci, timedMessagesTTL = chatTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp, longClick = { onLinkLongClick("") }, receiveFile = receiveFile)
CIVoiceView(mc.duration, ci.file, ci.meta.itemEdited, ci.chatDir.sent, hasText = true, ci, timedMessagesTTL = chatTTL, showViaProxy = showViaProxy, longClick = { onLinkLongClick("") }, receiveFile = receiveFile)
if (mc.text != "") {
CIMarkdownText(ci, chatTTL, linkMode, uriHandler, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMarkdownText(ci, chatTTL, linkMode, uriHandler, showViaProxy = showViaProxy)
}
}
is MsgContent.MCFile -> ciFileView(ci, mc.text)
is MsgContent.MCUnknown ->
if (ci.file == null) {
CIMarkdownText(ci, chatTTL, linkMode, uriHandler, onLinkLongClick, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMarkdownText(ci, chatTTL, linkMode, uriHandler, onLinkLongClick, showViaProxy = showViaProxy)
} else {
ciFileView(ci, mc.text)
}
is MsgContent.MCLink -> {
ChatItemLinkView(mc.preview, showMenu, onLongClick = { showMenu.value = true })
Box(Modifier.widthIn(max = DEFAULT_MAX_IMAGE_WIDTH)) {
CIMarkdownText(ci, chatTTL, linkMode, uriHandler, onLinkLongClick, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMarkdownText(ci, chatTTL, linkMode, uriHandler, onLinkLongClick, showViaProxy = showViaProxy)
}
}
else -> CIMarkdownText(ci, chatTTL, linkMode, uriHandler, onLinkLongClick, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
else -> CIMarkdownText(ci, chatTTL, linkMode, uriHandler, onLinkLongClick, showViaProxy = showViaProxy)
}
}
}
}
Box(Modifier.padding(bottom = 6.dp, end = 12.dp)) {
CIMetaView(ci, chatTTL, metaColor, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMetaView(ci, chatTTL, metaColor, showViaProxy = showViaProxy)
}
}
}
@@ -293,21 +291,19 @@ fun CIMarkdownText(
linkMode: SimplexLinkMode,
uriHandler: UriHandler?,
onLinkLongClick: (link: String) -> Unit = {},
showViaProxy: Boolean,
showTimestamp: Boolean,
showViaProxy: Boolean
) {
Box(Modifier.padding(vertical = 7.dp, horizontal = 12.dp)) {
Box(Modifier.padding(vertical = 6.dp, horizontal = 12.dp)) {
val text = if (ci.meta.isLive) ci.content.msgContent?.text ?: ci.text else ci.text
MarkdownText(
text, if (text.isEmpty()) emptyList() else ci.formattedText, toggleSecrets = true,
meta = ci.meta, chatTTL = chatTTL, linkMode = linkMode,
uriHandler = uriHandler, senderBold = true, onLinkLongClick = onLinkLongClick, showViaProxy = showViaProxy, showTimestamp = showTimestamp
uriHandler = uriHandler, senderBold = true, onLinkLongClick = onLinkLongClick, showViaProxy = showViaProxy
)
}
}
const val CHAT_IMAGE_LAYOUT_ID = "chatImage"
const val CHAT_BUBBLE_LAYOUT_ID = "chatBubble"
/**
* Equal to [androidx.compose.ui.unit.Constraints.MaxFocusMask], which is 0x3FFFF - 1
* Other values make a crash `java.lang.IllegalArgumentException: Can't represent a width of 123456 and height of 9909 in Constraints`
@@ -315,23 +311,23 @@ const val CHAT_BUBBLE_LAYOUT_ID = "chatBubble"
* */
const val MAX_SAFE_WIDTH = 0x3FFFF - 1
/**
* Limiting max value for height + width in order to not crash the app, see [androidx.compose.ui.unit.Constraints.createConstraints]
* */
private fun maxSafeHeight(width: Int) = when { // width bits + height bits should be <= 31
width < 0x1FFF /*MaxNonFocusMask*/ -> 0x3FFFF - 1 /* MaxFocusMask */ // 13 bits width + 18 bits height
width < 0x7FFF /*MinNonFocusMask*/ -> 0xFFFF - 1 /* MinFocusMask */ // 15 bits width + 16 bits height
width < 0xFFFF /*MinFocusMask*/ -> 0x7FFF - 1 /* MinFocusMask */ // 16 bits width + 15 bits height
width < 0x3FFFF /*MaxFocusMask*/ -> 0x1FFF - 1 /* MaxNonFocusMask */ // 18 bits width + 13 bits height
else -> 0x1FFF // shouldn't happen since width is limited already
}
@Composable
fun PriorityLayout(
modifier: Modifier = Modifier,
priorityLayoutId: String,
content: @Composable () -> Unit
) {
/**
* Limiting max value for height + width in order to not crash the app, see [androidx.compose.ui.unit.Constraints.createConstraints]
* */
fun maxSafeHeight(width: Int) = when { // width bits + height bits should be <= 31
width < 0x1FFF /*MaxNonFocusMask*/ -> 0x3FFFF - 1 /* MaxFocusMask */ // 13 bits width + 18 bits height
width < 0x7FFF /*MinNonFocusMask*/ -> 0xFFFF - 1 /* MinFocusMask */ // 15 bits width + 16 bits height
width < 0xFFFF /*MinFocusMask*/ -> 0x7FFF - 1 /* MinFocusMask */ // 16 bits width + 15 bits height
width < 0x3FFFF /*MaxFocusMask*/ -> 0x1FFF - 1 /* MaxNonFocusMask */ // 18 bits width + 13 bits height
else -> 0x1FFF // shouldn't happen since width is limited already
}
Layout(
content = content,
modifier = modifier
@@ -356,36 +352,6 @@ fun PriorityLayout(
}
}
}
@Composable
fun DependentLayout(
modifier: Modifier = Modifier,
mainLayoutId: String,
content: @Composable () -> Unit
) {
Layout(
content = content,
modifier = modifier
) { measureable, constraints ->
// Find important element which should tell what min width it needs to draw itself.
// Expecting only one such element. Can be less than one but not more
val mainPlaceable = measureable.firstOrNull { it.layoutId == mainLayoutId }?.measure(constraints)
val placeables: List<Placeable> = measureable.map {
if (it.layoutId == mainLayoutId)
mainPlaceable!!
else
it.measure(constraints.copy(minWidth = mainPlaceable?.width ?: 0, maxWidth = min(MAX_SAFE_WIDTH, constraints.maxWidth))) }
val width = mainPlaceable?.measuredWidth ?: min(MAX_SAFE_WIDTH, placeables.maxOf { it.width })
val height = minOf(maxSafeHeight(width), placeables.sumOf { it.height })
layout(width, height) {
var y = 0
placeables.forEach {
it.place(0, y)
y += it.measuredHeight
}
}
}
}
/*
class EditedProvider: PreviewParameterProvider<Boolean> {
@@ -23,8 +23,8 @@ import chat.simplex.common.views.helpers.generalGetString
import chat.simplex.res.MR
@Composable
fun IntegrityErrorItemView(msgError: MsgErrorType, ci: ChatItem, showTimestamp: Boolean, timedMessagesTTL: Int?) {
CIMsgError(ci, showTimestamp, timedMessagesTTL) {
fun IntegrityErrorItemView(msgError: MsgErrorType, ci: ChatItem, timedMessagesTTL: Int?) {
CIMsgError(ci, timedMessagesTTL) {
when (msgError) {
is MsgErrorType.MsgSkipped ->
AlertManager.shared.showAlertMsg(
@@ -49,7 +49,7 @@ fun IntegrityErrorItemView(msgError: MsgErrorType, ci: ChatItem, showTimestamp:
}
@Composable
fun CIMsgError(ci: ChatItem, showTimestamp: Boolean, timedMessagesTTL: Int?, onClick: () -> Unit) {
fun CIMsgError(ci: ChatItem, timedMessagesTTL: Int?, onClick: () -> Unit) {
val receivedColor = MaterialTheme.appColors.receivedMessage
Surface(
Modifier.clickable(onClick = onClick),
@@ -68,7 +68,7 @@ fun CIMsgError(ci: ChatItem, showTimestamp: Boolean, timedMessagesTTL: Int?, onC
style = MaterialTheme.typography.body1.copy(lineHeight = 22.sp),
modifier = Modifier.padding(end = 8.dp)
)
CIMetaView(ci, timedMessagesTTL, showViaProxy = false, showTimestamp = showTimestamp)
CIMetaView(ci, timedMessagesTTL, showViaProxy = false)
}
}
}
@@ -83,8 +83,7 @@ fun IntegrityErrorItemViewPreview() {
IntegrityErrorItemView(
MsgErrorType.MsgBadHash(),
ChatItem.getDeletedContentSampleData(),
showTimestamp = true,
null,
null
)
}
}
@@ -20,7 +20,7 @@ import dev.icerock.moko.resources.compose.stringResource
import kotlinx.datetime.Clock
@Composable
fun MarkedDeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, revealed: MutableState<Boolean>, showViaProxy: Boolean, showTimestamp: Boolean) {
fun MarkedDeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, revealed: MutableState<Boolean>, showViaProxy: Boolean) {
val sentColor = MaterialTheme.appColors.sentMessage
val receivedColor = MaterialTheme.appColors.receivedMessage
Surface(
@@ -35,7 +35,7 @@ fun MarkedDeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, revealed: Mutabl
Box(Modifier.weight(1f, false)) {
MergedMarkedDeletedText(ci, revealed)
}
CIMetaView(ci, timedMessagesTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
CIMetaView(ci, timedMessagesTTL, showViaProxy = showViaProxy)
}
}
}
@@ -113,8 +113,7 @@ fun PreviewMarkedDeletedItemView() {
DeletedItemView(
ChatItem.getSampleData(itemDeleted = CIDeleted.Deleted(Clock.System.now())),
null,
showViaProxy = false,
showTimestamp = true
showViaProxy = false
)
}
}
@@ -70,8 +70,7 @@ fun MarkdownText (
linkMode: SimplexLinkMode,
inlineContent: Pair<AnnotatedString.Builder.() -> Unit, Map<String, InlineTextContent>>? = null,
onLinkLongClick: (link: String) -> Unit = {},
showViaProxy: Boolean = false,
showTimestamp: Boolean = true
showViaProxy: Boolean = false
) {
val textLayoutDirection = remember (text) {
if (isRtl(text.subSequence(0, kotlin.math.min(50, text.length)))) LayoutDirection.Rtl else LayoutDirection.Ltr
@@ -79,7 +78,7 @@ fun MarkdownText (
val reserve = if (textLayoutDirection != LocalLayoutDirection.current && meta != null) {
"\n"
} else if (meta != null) {
reserveSpaceForMeta(meta, chatTTL, null, secondaryColor = MaterialTheme.colors.secondary, showViaProxy = showViaProxy, showTimestamp = showTimestamp)
reserveSpaceForMeta(meta, chatTTL, null, secondaryColor = MaterialTheme.colors.secondary, showViaProxy = showViaProxy)
} else {
" "
}
@@ -478,7 +478,7 @@ private fun ToggleFilterEnabledButton() {
@Composable
expect fun ActiveCallInteractiveArea(call: Call)
fun connectIfOpenedViaUri(rhId: Long?, uri: String, chatModel: ChatModel) {
fun connectIfOpenedViaUri(rhId: Long?, uri: URI, chatModel: ChatModel) {
Log.d(TAG, "connectIfOpenedViaUri: opened via link")
if (chatModel.currentUser.value == null) {
chatModel.appOpenUrl.value = rhId to uri
@@ -566,7 +566,7 @@ private fun connect(link: String, searchChatFilteredBySimplexLink: MutableState<
withBGApi {
planAndConnect(
chatModel.remoteHostId(),
link,
URI.create(link),
incognito = null,
filterKnownContact = { searchChatFilteredBySimplexLink.value = it.id },
filterKnownGroup = { searchChatFilteredBySimplexLink.value = it.id },
@@ -256,7 +256,7 @@ fun ChatPreviewView(
}
}
is MsgContent.MCVoice -> SmallContentPreviewVoice() {
CIVoiceView(mc.duration, ci.file, ci.meta.itemEdited, ci.chatDir.sent, hasText = false, ci, cInfo.timedMessagesTTL, showViaProxy = false, showTimestamp = true, smallView = true, longClick = {}) {
CIVoiceView(mc.duration, ci.file, ci.meta.itemEdited, ci.chatDir.sent, hasText = false, ci, cInfo.timedMessagesTTL, showViaProxy = false, smallView = true, longClick = {}) {
val user = chatModel.currentUser.value ?: return@CIVoiceView
withBGApi { chatModel.controller.receiveFile(chat.remoteHostId, user, it) }
}
@@ -332,7 +332,7 @@ fun ChatPreviewView(
chatPreviewTitle()
}
Spacer(Modifier.width(8.sp.toDp()))
val ts = getTimestampText(chat.chatItems.lastOrNull()?.meta?.itemTs ?: chat.chatInfo.chatTs)
val ts = chat.chatItems.lastOrNull()?.timestampText ?: getTimestampText(chat.chatInfo.chatTs)
ChatListTimestampView(ts)
}
Row(Modifier.heightIn(min = 46.sp.toDp()).fillMaxWidth()) {
@@ -58,13 +58,11 @@ fun ShareListView(chatModel: ChatModel, stopped: Boolean) {
hasSimplexLink = hasSimplexLink(sharedContent.text)
}
is SharedContent.Forward -> {
sharedContent.chatItems.forEach { ci ->
val mc = ci.content.msgContent
if (mc != null) {
isMediaOrFileAttachment = isMediaOrFileAttachment || mc.isMediaOrFileAttachment
isVoice = isVoice || mc.isVoice
hasSimplexLink = hasSimplexLink || hasSimplexLink(mc.text)
}
val mc = sharedContent.chatItem.content.msgContent
if (mc != null) {
isMediaOrFileAttachment = mc.isMediaOrFileAttachment
isVoice = mc.isVoice
hasSimplexLink = hasSimplexLink(mc.text)
}
}
null -> {}
@@ -177,11 +175,11 @@ private fun ShareListToolbar(chatModel: ChatModel, stopped: Boolean, onSearchVal
title = {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
when (val v = chatModel.sharedContent.value) {
when (chatModel.sharedContent.value) {
is SharedContent.Text -> stringResource(MR.strings.share_message)
is SharedContent.Media -> stringResource(MR.strings.share_image)
is SharedContent.File -> stringResource(MR.strings.share_file)
is SharedContent.Forward -> if (v.chatItems.size > 1) stringResource(MR.strings.forward_multiple) else stringResource(MR.strings.forward_message)
is SharedContent.Forward -> stringResource(MR.strings.forward_message)
null -> stringResource(MR.strings.share_message)
},
color = MaterialTheme.colors.onBackground,
@@ -1,11 +1,13 @@
package chat.simplex.common.views.chatlist
import SectionItemView
import SectionView
import TextIconSpaced
import androidx.compose.foundation.*
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsHoveredAsState
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.*
import androidx.compose.material.*
import androidx.compose.runtime.*
@@ -20,7 +22,6 @@ import androidx.compose.ui.text.capitalize
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.*
import chat.simplex.common.model.*
import chat.simplex.common.model.ChatController.stopRemoteHostAndReloadHosts
@@ -30,6 +31,7 @@ import chat.simplex.common.views.helpers.*
import chat.simplex.common.platform.*
import chat.simplex.common.views.CreateProfile
import chat.simplex.common.views.localauth.VerticalDivider
import chat.simplex.common.views.newchat.*
import chat.simplex.common.views.remote.*
import chat.simplex.common.views.usersettings.*
import chat.simplex.common.views.usersettings.AppearanceScope.ColorModeSwitcher
@@ -38,8 +40,6 @@ import dev.icerock.moko.resources.compose.stringResource
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
private val USER_PICKER_SECTION_SPACING = 32.dp
@Composable
fun UserPicker(
chatModel: ChatModel,
@@ -56,7 +56,7 @@ fun UserPicker(
derivedStateOf {
chatModel.users
.filter { u -> u.user.activeUser || !u.user.hidden }
.sortedByDescending { it.user.activeOrder }
.sortedByDescending { it.user.activeUser }
}
}
val remoteHosts by remember {
@@ -142,33 +142,10 @@ fun UserPicker(
.height(IntrinsicSize.Min)
.fillMaxWidth()
.then(if (newChat.isVisible()) Modifier.shadow(8.dp, clip = true) else Modifier)
.background(if (appPlatform.isAndroid) MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, alpha = 1 - userPickerAlpha()) else MaterialTheme.colors.surface)
.padding(bottom = USER_PICKER_SECTION_SPACING - DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL),
.background(MaterialTheme.colors.surface)
.padding(vertical = DEFAULT_PADDING),
pickerState = userPickerState
) {
val showCustomModal: (@Composable() (ModalData.(ChatModel, () -> Unit) -> Unit)) -> () -> Unit = { modalView ->
{
ModalManager.start.showCustomModal { close -> modalView(chatModel, close) }
}
}
val stopped = remember { chatModel.chatRunning }.value == false
val onUserClicked: (user: User) -> Unit = { user ->
if (!user.activeUser) {
userPickerState.value = AnimatedViewState.HIDING
withBGApi {
controller.showProgressIfNeeded {
ModalManager.closeAllModalsEverywhere()
chatModel.controller.changeActiveUser(user.remoteHostId, user.userId, null)
}
}
} else {
showCustomModal { chatModel, close -> UserProfileView(chatModel, close) }()
withBGApi {
closePicker(userPickerState)
}
}
}
@Composable
fun FirstSection() {
if (remoteHosts.isNotEmpty()) {
@@ -192,24 +169,87 @@ fun UserPicker(
}
)
}
val currentUser = remember { chatModel.currentUser }.value
if (appPlatform.isAndroid) {
Column(modifier = Modifier.padding(top = USER_PICKER_SECTION_SPACING, bottom = USER_PICKER_SECTION_SPACING - DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL - 3.dp)) {
UserPickerUsersSection(
users = users,
onUserClicked = onUserClicked,
stopped = stopped
)
}
} else if (currentUser != null) {
SectionItemView({ onUserClicked(currentUser) }, 80.dp, padding = PaddingValues(start = 16.dp, end = DEFAULT_PADDING), disabled = stopped) {
ProfilePreview(currentUser.profile, stopped = stopped)
}
}
ActiveUserSection(
chatModel = chatModel,
userPickerState = userPickerState,
)
}
@Composable
fun SecondSection() {
GlobalSettingsSection(
chatModel = chatModel,
userPickerState = userPickerState,
setPerformLA = setPerformLA,
onUserClicked = { user ->
userPickerState.value = AnimatedViewState.HIDING
if (!user.activeUser) {
withBGApi {
controller.showProgressIfNeeded {
ModalManager.closeAllModalsEverywhere()
chatModel.controller.changeActiveUser(user.remoteHostId, user.userId, null)
}
}
}
},
onShowAllProfilesClicked = {
doWithAuth(
generalGetString(MR.strings.auth_open_chat_profiles),
generalGetString(MR.strings.auth_log_in_using_credential)
) {
ModalManager.start.showCustomModal { close ->
val search = rememberSaveable { mutableStateOf("") }
val profileHidden = rememberSaveable { mutableStateOf(false) }
ModalView(
{ close() },
endButtons = {
SearchTextField(Modifier.fillMaxWidth(), placeholder = stringResource(MR.strings.search_verb), alwaysVisible = true) { search.value = it }
},
content = { UserProfilesView(chatModel, search, profileHidden) })
}
}
}
)
}
if (appPlatform.isDesktop || windowOrientation() == WindowOrientation.PORTRAIT) {
Column {
FirstSection()
Divider(Modifier.padding(DEFAULT_PADDING))
SecondSection()
}
} else {
Row {
Box(Modifier.weight(1f)) {
FirstSection()
}
VerticalDivider()
Box(Modifier.weight(1f)) {
SecondSection()
}
}
}
}
}
@Composable
private fun ActiveUserSection(
chatModel: ChatModel,
userPickerState: MutableStateFlow<AnimatedViewState>,
) {
val showCustomModal: (@Composable() (ModalData.(ChatModel, () -> Unit) -> Unit)) -> () -> Unit = { modalView ->
{
ModalManager.start.showCustomModal { close -> modalView(chatModel, close) }
}
}
val currentUser = remember { chatModel.currentUser }.value
val stopped = chatModel.chatRunning.value == false
if (currentUser != null) {
SectionView {
SectionItemView(showCustomModal { chatModel, close -> UserProfileView(chatModel, close) }, 80.dp, padding = PaddingValues(start = 16.dp, end = DEFAULT_PADDING), disabled = stopped) {
ProfilePreview(currentUser.profile, stopped = stopped)
}
UserPickerOptionRow(
painterResource(MR.images.ic_qr_code),
if (chatModel.userAddress.value != null) generalGetString(MR.strings.your_simplex_contact_address) else generalGetString(MR.strings.create_simplex_address),
@@ -225,22 +265,9 @@ fun UserPicker(
}),
disabled = stopped
)
if (appPlatform.isDesktop) {
Divider(Modifier.padding(DEFAULT_PADDING))
val inactiveUsers = users.filter { !it.user.activeUser }
if (inactiveUsers.isNotEmpty()) {
Column(modifier = Modifier.padding(vertical = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL)) {
UserPickerUsersSection(
users = inactiveUsers,
onUserClicked = onUserClicked,
stopped = stopped
)
}
}
}
}
} else {
SectionView {
if (chatModel.desktopNoUserNoRemote) {
UserPickerOptionRow(
painterResource(MR.images.ic_manage_accounts),
@@ -256,121 +283,76 @@ fun UserPicker(
}
}
)
} else {
UserPickerOptionRow(
painterResource(MR.images.ic_manage_accounts),
stringResource(MR.strings.your_chat_profiles),
{
doWithAuth(
generalGetString(MR.strings.auth_open_chat_profiles),
generalGetString(MR.strings.auth_log_in_using_credential)
) {
ModalManager.start.showCustomModal { close ->
val search = rememberSaveable { mutableStateOf("") }
val profileHidden = rememberSaveable { mutableStateOf(false) }
ModalView(
{ close() },
endButtons = {
SearchTextField(Modifier.fillMaxWidth(), placeholder = stringResource(MR.strings.search_verb), alwaysVisible = true) { search.value = it }
},
content = { UserProfilesView(chatModel, search, profileHidden) })
}
}
},
disabled = stopped
)
}
}
if (appPlatform.isDesktop || windowOrientation() == WindowOrientation.PORTRAIT) {
Column {
FirstSection()
SecondSection()
GlobalSettingsSection(
userPickerState = userPickerState,
setPerformLA = setPerformLA,
)
}
} else {
Column {
FirstSection()
Row {
Box(Modifier.weight(1f)) {
Column {
SecondSection()
}
}
VerticalDivider()
Box(Modifier.weight(1f)) {
Column {
GlobalSettingsSection(
userPickerState = userPickerState,
setPerformLA = setPerformLA,
)
}
}
}
}
}
}
}
fun userPickerAlpha(): Float {
return when (CurrentColors.value.base) {
DefaultTheme.LIGHT -> 0.05f
DefaultTheme.DARK -> 0.05f
DefaultTheme.BLACK -> 0.075f
DefaultTheme.SIMPLEX -> 0.035f
}
}
@Composable
private fun GlobalSettingsSection(
chatModel: ChatModel,
userPickerState: MutableStateFlow<AnimatedViewState>,
setPerformLA: (Boolean) -> Unit,
onUserClicked: (user: User) -> Unit,
onShowAllProfilesClicked: () -> Unit
) {
val stopped = remember { chatModel.chatRunning }.value == false
if (appPlatform.isAndroid) {
val text = generalGetString(MR.strings.settings_section_title_use_from_desktop).lowercase().capitalize(Locale.current)
UserPickerOptionRow(
painterResource(MR.images.ic_desktop),
text,
click = {
ModalManager.start.showCustomModal { close ->
ConnectDesktopView(close)
}
}
)
} else {
UserPickerOptionRow(
icon = painterResource(MR.images.ic_smartphone_300),
text = stringResource(if (remember { chat.simplex.common.platform.chatModel.remoteHosts }.isEmpty()) MR.strings.link_a_mobile else MR.strings.linked_mobiles),
click = {
userPickerState.value = AnimatedViewState.HIDING
ModalManager.start.showModal {
ConnectMobileView()
}
},
disabled = stopped
)
val stopped = chatModel.chatRunning.value == false
val users by remember {
derivedStateOf {
chatModel.users
.filter { u -> !u.user.hidden && !u.user.activeUser }
}
}
SectionItemView(
click = {
ModalManager.start.showModalCloseable { close ->
SettingsView(chatModel, setPerformLA, close)
}
},
padding = if (appPlatform.isDesktop) PaddingValues(start = DEFAULT_PADDING * 1.7f, end = DEFAULT_PADDING + 2.dp) else PaddingValues(start = DEFAULT_PADDING, end = DEFAULT_PADDING_HALF)
) {
val text = generalGetString(MR.strings.settings_section_title_settings).lowercase().capitalize(Locale.current)
Icon(painterResource(MR.images.ic_settings), text, tint = MaterialTheme.colors.secondary)
TextIconSpaced()
Text(text, color = Color.Unspecified)
Spacer(Modifier.weight(1f))
ColorModeSwitcher()
SectionView(headerBottomPadding = if (appPlatform.isDesktop || windowOrientation() == WindowOrientation.PORTRAIT) DEFAULT_PADDING else 0.dp) {
UserPickerInactiveUsersSection(
users = users,
onShowAllProfilesClicked = onShowAllProfilesClicked,
onUserClicked = onUserClicked,
stopped = stopped
)
if (appPlatform.isAndroid) {
val text = generalGetString(MR.strings.settings_section_title_use_from_desktop).lowercase().capitalize(Locale.current)
UserPickerOptionRow(
painterResource(MR.images.ic_desktop),
text,
click = {
ModalManager.start.showCustomModal { close ->
ConnectDesktopView(close)
}
}
)
} else {
UserPickerOptionRow(
icon = painterResource(MR.images.ic_smartphone_300),
text = stringResource(if (remember { chat.simplex.common.platform.chatModel.remoteHosts }.isEmpty()) MR.strings.link_a_mobile else MR.strings.linked_mobiles),
click = {
userPickerState.value = AnimatedViewState.HIDING
ModalManager.start.showModal {
ConnectMobileView()
}
},
disabled = stopped
)
}
SectionItemView(
click = {
ModalManager.start.showModalCloseable { close ->
SettingsView(chatModel, setPerformLA, close)
}
},
padding = PaddingValues(start = DEFAULT_PADDING * 1.7f, end = DEFAULT_PADDING + 2.dp)
) {
val text = generalGetString(MR.strings.settings_section_title_settings).lowercase().capitalize(Locale.current)
Icon(painterResource(MR.images.ic_settings), text, tint = MaterialTheme.colors.secondary)
TextIconSpaced()
Text(text, color = Color.Unspecified)
Spacer(Modifier.weight(1f))
ColorModeSwitcher()
}
}
}
@@ -378,7 +360,7 @@ private fun GlobalSettingsSection(
fun UserProfilePickerItem(
u: User,
unreadCount: Int = 0,
enabled: Boolean = remember { chatModel.chatRunning }.value == true || chatModel.connectedToRemote,
enabled: Boolean = chatModel.chatRunning.value == true || chatModel.connectedToRemote,
onLongClick: () -> Unit = {},
openSettings: () -> Unit = {},
onClick: () -> Unit
@@ -427,7 +409,7 @@ fun UserProfilePickerItem(
}
@Composable
fun UserProfileRow(u: User, enabled: Boolean = remember { chatModel.chatRunning }.value == true || chatModel.connectedToRemote) {
fun UserProfileRow(u: User, enabled: Boolean = chatModel.chatRunning.value == true || chatModel.connectedToRemote) {
Row(
Modifier
.widthIn(max = windowWidth() * 0.7f)
@@ -450,14 +432,31 @@ fun UserProfileRow(u: User, enabled: Boolean = remember { chatModel.chatRunning
@Composable
fun UserPickerOptionRow(icon: Painter, text: String, click: (() -> Unit)? = null, disabled: Boolean = false) {
SectionItemView(click, disabled = disabled, extraPadding = appPlatform.isDesktop) {
SectionItemView(click, disabled = disabled, extraPadding = true) {
Icon(icon, text, tint = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.secondary)
TextIconSpaced()
Text(text = text, color = if (disabled) MaterialTheme.colors.secondary else Color.Unspecified)
}
}
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun UserPickerInactiveUserBadge(userInfo: UserInfo, stopped: Boolean, size: Dp = 60.dp, onClick: (user: User) -> Unit) {
Box {
IconButton(
onClick = { onClick(userInfo.user) },
enabled = !stopped
) {
Box {
ProfileImage(size = size, image = userInfo.user.profile.image, color = MaterialTheme.colors.secondaryVariant)
if (userInfo.unreadCount > 0) {
unreadBadge(userInfo.unreadCount, userInfo.user.showNtfs)
}
}
}
}
}
@Composable
private fun DevicePickerRow(
localDeviceActive: Boolean,
@@ -466,13 +465,13 @@ private fun DevicePickerRow(
onRemoteHostClick: (rh: RemoteHostInfo, connecting: MutableState<Boolean>) -> Unit,
onRemoteHostActionButtonClick: (rh: RemoteHostInfo) -> Unit,
) {
FlowRow(
Row(
Modifier
.fillMaxWidth()
.sizeIn(minHeight = DEFAULT_MIN_SECTION_ITEM_HEIGHT)
.padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, bottom = DEFAULT_PADDING, top = DEFAULT_PADDING + DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL),
.padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, bottom = DEFAULT_PADDING, top = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL),
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
verticalAlignment = Alignment.CenterVertically
) {
val activeHost = remoteHosts.firstOrNull { h -> h.activeHost }
@@ -516,9 +515,10 @@ private fun DevicePickerRow(
}
@Composable
expect fun UserPickerUsersSection(
expect fun UserPickerInactiveUsersSection(
users: List<UserInfo>,
stopped: Boolean,
onShowAllProfilesClicked: () -> Unit,
onUserClicked: (user: User) -> Unit,
)
@@ -554,8 +554,7 @@ fun DevicePill(
verticalAlignment = Alignment.CenterVertically
) {
Row(
Modifier.padding(horizontal = 6.dp, vertical = 4.dp),
verticalAlignment = Alignment.CenterVertically
Modifier.padding(horizontal = 6.dp, vertical = 4.dp)
) {
Icon(
icon,
@@ -568,9 +567,6 @@ fun DevicePill(
text,
color = MaterialTheme.colors.onSurface,
fontSize = 12.sp,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
modifier = if (onActionButtonClick != null && actionButtonVisible) Modifier.widthIn(max = 300.dp * fontSizeSqrtMultiplier) else Modifier
)
if (onActionButtonClick != null && actionButtonVisible) {
val interactionSource = remember { MutableInteractionSource() }
@@ -604,14 +600,14 @@ fun HostDisconnectButton(onClick: (() -> Unit)?) {
}
@Composable
fun BoxScope.unreadBadge(unreadCount: Int, userMuted: Boolean, hasPadding: Boolean) {
private fun BoxScope.unreadBadge(unreadCount: Int, userMuted: Boolean) {
Text(
if (unreadCount > 0) unreadCountStr(unreadCount) else "",
color = Color.White,
fontSize = 10.sp,
style = TextStyle(textAlign = TextAlign.Center),
modifier = Modifier
.offset(y = if (hasPadding) 3.sp.toDp() else -4.sp.toDp(), x = if (hasPadding) 0.dp else 4.sp.toDp())
.offset(y = 3.sp.toDp())
.background(if (userMuted) MaterialTheme.colors.primaryVariant else MaterialTheme.colors.secondary, shape = CircleShape)
.badgeLayout()
.padding(horizontal = 2.sp.toDp())
@@ -620,6 +616,7 @@ fun BoxScope.unreadBadge(unreadCount: Int, userMuted: Boolean, hasPadding: Boole
)
}
private suspend fun closePicker(userPickerState: MutableStateFlow<AnimatedViewState>) {
delay(500)
userPickerState.value = AnimatedViewState.HIDING
@@ -137,10 +137,9 @@ fun ProfileImageForActiveCall(
size: Dp,
image: String? = null,
color: Color = MaterialTheme.colors.secondaryVariant,
backgroundColor: Color? = null,
) {
) {
if (image == null) {
Box(Modifier.requiredSize(size).clip(CircleShape).then(if (backgroundColor != null) Modifier.background(backgroundColor) else Modifier)) {
Box(Modifier.requiredSize(size).clip(CircleShape)) {
Icon(
AccountCircleFilled,
contentDescription = stringResource(MR.strings.icon_descr_profile_image_placeholder),
@@ -2,7 +2,8 @@
package chat.simplex.common.views.helpers
import androidx.compose.runtime.saveable.Saver
import chat.simplex.common.model.*
import chat.simplex.common.model.ChatInfo
import chat.simplex.common.model.ChatItem
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
@@ -14,7 +15,7 @@ sealed class SharedContent {
data class Text(val text: String): SharedContent()
data class Media(val text: String, val uris: List<URI>): SharedContent()
data class File(val text: String, val uri: URI): SharedContent()
data class Forward(val chatItems: List<ChatItem>, val fromChatInfo: ChatInfo): SharedContent()
data class Forward(val chatItem: ChatItem, val fromChatInfo: ChatInfo): SharedContent()
}
enum class AnimatedViewState {
@@ -1,12 +1,7 @@
package chat.simplex.common.views.helpers
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.material.ripple.rememberRipple
import dev.icerock.moko.resources.compose.painterResource
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
@@ -14,7 +9,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.*
import chat.simplex.res.MR
@@ -91,12 +85,10 @@ fun <T> ExposedDropDownSettingWithIcon(
values: List<Triple<T, ImageResource, String>>,
selection: State<T>,
fontSize: TextUnit = 16.sp,
iconPaddingPercent: Float = 0.2f,
iconSize: Dp = 40.dp,
listIconSize: Dp = 30.dp,
boxSize: Dp = 60.dp,
iconColor: Color = MenuTextColor,
enabled: State<Boolean> = mutableStateOf(true),
background: Color,
minWidth: Dp = 200.dp,
onSelected: (T) -> Unit
) {
@@ -107,21 +99,13 @@ fun <T> ExposedDropDownSettingWithIcon(
expanded.value = !expanded.value && enabled.value
}
) {
Box(
Modifier
.background(background, CircleShape)
.size(boxSize)
.clickable(
onClick = {},
role = Role.Button,
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = false, radius = boxSize / 2, color = background.lighter(0.1f)),
enabled = enabled.value
),
contentAlignment = Alignment.Center
Row(
Modifier.padding(start = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End
) {
val choice = values.first { it.first == selection.value }
Icon(painterResource(choice.second), choice.third, Modifier.padding(boxSize * iconPaddingPercent).fillMaxSize(), tint = iconColor)
Icon(painterResource(choice.second), choice.third, Modifier.size(iconSize), tint = iconColor)
}
DefaultExposedDropdownMenu(
modifier = Modifier.widthIn(min = minWidth),
@@ -480,11 +480,12 @@ inline fun <reified T> serializableSaver(): Saver<T, *> = Saver(
)
fun UriHandler.openVerifiedSimplexUri(uri: String) {
connectIfOpenedViaUri(chatModel.remoteHostId(), uri, ChatModel)
val URI = try { URI.create(uri) } catch (e: Exception) { null }
if (URI != null) {
connectIfOpenedViaUri(chatModel.remoteHostId(), URI, ChatModel)
}
}
fun uriCreateOrNull(uri: String) = try { URI.create(uri) } catch (e: Exception) { null }
fun UriHandler.openUriCatching(uri: String) {
try {
openUri(uri)
@@ -20,7 +20,7 @@ enum class ConnectionLinkType {
suspend fun planAndConnect(
rhId: Long?,
uri: String,
uri: URI,
incognito: Boolean?,
close: (() -> Unit)?,
cleanup: (() -> Unit)? = null,
@@ -29,7 +29,7 @@ suspend fun planAndConnect(
) {
val connectionPlan = chatModel.controller.apiConnectPlan(rhId, uri.toString())
if (connectionPlan != null) {
val link = strHasSingleSimplexLink(uri.trim())
val link = strHasSingleSimplexLink(uri.toString().trim())
val linkText = if (link?.format is Format.SimplexLink)
"<br><br><u>${link.simplexLinkText(link.format.linkType, link.format.smpHosts)}</u>"
else
@@ -323,13 +323,13 @@ suspend fun planAndConnect(
suspend fun connectViaUri(
chatModel: ChatModel,
rhId: Long?,
uri: String,
uri: URI,
incognito: Boolean,
connectionPlan: ConnectionPlan?,
close: (() -> Unit)?,
cleanup: (() -> Unit)?,
) {
val pcc = chatModel.controller.apiConnect(rhId, incognito, uri)
val pcc = chatModel.controller.apiConnect(rhId, incognito, uri.toString())
val connLinkType = if (connectionPlan != null) planToConnectionLinkType(connectionPlan) else ConnectionLinkType.INVITATION
if (pcc != null) {
withChats {
@@ -361,7 +361,7 @@ fun planToConnectionLinkType(connectionPlan: ConnectionPlan): ConnectionLinkType
fun askCurrentOrIncognitoProfileAlert(
chatModel: ChatModel,
rhId: Long?,
uri: String,
uri: URI,
connectionPlan: ConnectionPlan?,
close: (() -> Unit)?,
title: String,
@@ -417,7 +417,7 @@ fun openKnownContact(chatModel: ChatModel, rhId: Long?, close: (() -> Unit)?, co
fun ownGroupLinkConfirmConnect(
chatModel: ChatModel,
rhId: Long?,
uri: String,
uri: URI,
linkText: String,
incognito: Boolean?,
connectionPlan: ConnectionPlan?,
@@ -482,7 +482,7 @@ private fun connect(link: String, searchChatFilteredBySimplexLink: MutableState<
withBGApi {
planAndConnect(
chatModel.remoteHostId(),
link,
URI.create(link),
incognito = null,
filterKnownContact = { searchChatFilteredBySimplexLink.value = it.id },
close = close,
@@ -655,7 +655,7 @@ private suspend fun verify(rhId: Long?, text: String?, close: () -> Unit): Boole
private suspend fun connect(rhId: Long?, link: String, close: () -> Unit, cleanup: (() -> Unit)? = null) {
planAndConnect(
rhId,
link,
URI.create(link),
close = close,
cleanup = cleanup,
incognito = null
@@ -31,7 +31,7 @@
<string name="smp_servers_preset_add">أضِف خوادم محدّدة مسبقًا</string>
<string name="smp_servers_add_to_another_device">أضِف إلى جهاز آخر</string>
<string name="users_delete_all_chats_deleted">سيتم حذف جميع الدردشات والرسائل - لا يمكن التراجع عن هذا!</string>
<string name="network_enable_socks_info">الوصول إلى الخوادم عبر وكيل SOCKS على المنفذ %d؟ يجب بدء تشغيل الوكيل قبل تمكين هذا الخيار.</string>
<string name="network_enable_socks_info">الوصول إلى الخوادم عبر بروكسي SOCKS على المنفذ %d؟ يجب بدء تشغيل الوكيل قبل تمكين هذا الخيار.</string>
<string name="smp_servers_add">أضِف خادم</string>
<string name="network_settings">إعدادات الشبكة المتقدمة</string>
<string name="all_group_members_will_remain_connected">سيبقى جميع أعضاء المجموعة على اتصال.</string>
@@ -50,7 +50,7 @@
<string name="allow_calls_only_if">السماح بالمكالمات فقط إذا سمحت جهة اتصالك بذلك.</string>
<string name="allow_message_reactions_only_if">اسمح بردود الفعل على الرسائل فقط إذا سمحت جهة اتصالك بذلك.</string>
<string name="keychain_is_storing_securely">يتم استخدام Android Keystore لتخزين عبارة المرور بشكل آمن - فهو يسمح لخدمة الإشعارات بالعمل.</string>
<string name="empty_chat_profile_is_created">يتم إنشاء ملف تعريف دردشة فارغ بالاسم المقدم، ويفتح التطبيق كالمعتاد.</string>
<string name="empty_chat_profile_is_created">يتم إنشاء ملف تعريف دردشة فارغ بالاسم المقدم ، ويفتح التطبيق كالمعتاد.</string>
<string name="answer_call">أجب الاتصال</string>
<string name="chat_preferences_always">دائِماً</string>
<string name="allow_to_send_disappearing">السماح بإرسال رسائل تختفي.</string>
@@ -141,7 +141,7 @@
<string name="database_initialization_error_title">لا يمكن تهيئة قاعدة البيانات</string>
<string name="attach">إرفاق</string>
<string name="icon_descr_asked_to_receive">طلب لاستلام الصورة</string>
<string name="app_version_name">إصدار التطبيق: v%s</string>
<string name="app_version_name">نسخة التطبيق: v%s</string>
<string name="auto_accept_contact">قبول تلقائي</string>
<string name="settings_section_title_calls">المكالمات</string>
<string name="alert_title_cant_invite_contacts">لا يمكن دعوة جهات الاتصال!</string>
@@ -1768,9 +1768,9 @@
<string name="snd_error_quota">تم تجاوز السعة - لم يتلق المُستلم الرسائل المُرسلة مسبقًا.</string>
<string name="snd_error_relay">خطأ في خادم الوجهة: %1$s</string>
<string name="ci_status_other_error">خطأ: %1$s</string>
<string name="snd_error_proxy_relay">خادم التحويل: %1$s
<string name="snd_error_proxy_relay">خادم إعادة التوجيه: %1$s
\nخطأ في الخادم الوجهة: %2$s</string>
<string name="snd_error_proxy">خادم التحويل: %1$s
<string name="snd_error_proxy">خادم إعادة التوجيه: %1$s
\nخطأ: %2$s</string>
<string name="message_delivery_warning_title">تحذير تسليم الرسالة</string>
<string name="snd_error_expired">مشكلات الشبكة - انتهت صلاحية الرسالة بعد عِدة محاولات لإرسالها.</string>
@@ -2067,27 +2067,4 @@
<string name="reset_all_hints">صفّر كافة التلميحات</string>
<string name="error_parsing_uri_desc">يُرجى التأكد من أن رابط SimpleX صحيح.</string>
<string name="error_parsing_uri_title">الرابط غير صالح</string>
<string name="n_file_errors">%1$d خطأ في الملف:
\n%2$s</string>
<string name="forward_files_failed_to_receive_desc">فشل تنزيل %1$d ملف/ات.</string>
<string name="forward_files_not_accepted_desc">لم يتم تنزيل %1$d ملف/ات.</string>
<string name="forward_files_not_accepted_receive_files">نزّل</string>
<string name="new_chat_share_profile">شارك ملف التعريف</string>
<string name="network_proxy_auth_mode_isolate_by_auth_entity">استخدم بيانات اعتماد الوكيل المختلفة لكل اتصال.</string>
<string name="network_proxy_username">اسم المستخدم</string>
<string name="network_proxy_auth_mode_username_password">قد يتم إرسال بيانات الاعتماد الخاصة بك غير مُعمَّاة.</string>
<string name="network_proxy_incorrect_config_title">خطأ في حفظ الوكيل</string>
<string name="migrate_from_device_remove_archive_question">إزالة الأرشيف؟</string>
<string name="system_mode_toast">وضع النظام</string>
<string name="migrate_from_device_uploaded_archive_will_be_removed">سيتم إزالة أرشيف قاعدة البيانات المرفوعة نهائيًا من الخوادم.</string>
<string name="network_proxy_auth_mode_isolate_by_auth_user">استخدم بيانات اعتماد الوكيل المختلفة لكل ملف تعريف.</string>
<string name="network_proxy_random_credentials">استخدم بيانات اعتماد عشوائية</string>
<string name="settings_section_title_chat_database">قاعدة بيانات الدردشة</string>
<string name="forward_files_missing_desc">حُذف %1$d ملف/ات.</string>
<string name="forward_files_in_progress_desc">لا يزال يتم تنزيل %1$d ملفًا.</string>
<string name="network_proxy_auth_mode_no_auth">لا تستخدم بيانات الاعتماد مع الوكيل.</string>
<string name="error_forwarding_messages">خطأ في تحويل الرسائل</string>
<string name="switching_profile_error_title">خطأ في تبديل الملف الشخصي</string>
<string name="select_chat_profile">حدد ملف تعريف الدردشة</string>
<string name="switching_profile_error_message">لقد تم نقل اتصالك إلى %s ولكن حدث خطأ غير متوقع أثناء إعادة توجيهك إلى الملف الشخصي.</string>
</resources>
@@ -125,7 +125,6 @@
<string name="proxy_destination_error_broker_version">Destination server version of %1$s is incompatible with forwarding server %2$s.</string>
<string name="please_try_later">Please try later.</string>
<string name="error_sending_message">Error sending message</string>
<string name="error_forwarding_messages">Error forwarding messages</string>
<string name="error_creating_message">Error creating message</string>
<string name="error_loading_details">Error loading details</string>
<string name="error_adding_members">Error adding member(s)</string>
@@ -134,9 +133,7 @@
<string name="sender_cancelled_file_transfer">Sender cancelled file transfer.</string>
<string name="file_not_approved_title">Unknown servers!</string>
<string name="file_not_approved_descr">Without Tor or VPN, your IP address will be visible to these XFTP relays:\n%1$s.</string>
<string name="n_other_file_errors">%1$d other file error(s).</string>
<string name="error_receiving_file">Error receiving file</string>
<string name="n_file_errors">%1$d file error(s):\n%2$s</string>
<string name="error_creating_address">Error creating address</string>
<string name="contact_already_exists">Contact already exists</string>
<string name="you_are_already_connected_to_vName_via_this_link">You are already connected to %1$s.</string>
@@ -381,23 +378,12 @@
<string name="no_selected_chat">No selected chat</string>
<string name="selected_chat_items_nothing_selected">Nothing selected</string>
<string name="selected_chat_items_selected_n">Selected %d</string>
<string name="forward_alert_title_messages_to_forward">Forward %1$s message(s)?</string>
<string name="forward_alert_title_nothing_to_forward">Nothing to forward!</string>
<string name="forward_alert_forward_messages_without_files">Forward messages without files?</string>
<string name="forward_files_messages_deleted_after_selection_desc">Messages were deleted after you selected them.</string>
<string name="forward_files_not_accepted_desc">%1$d file(s) were not downloaded.</string>
<string name="forward_files_in_progress_desc">%1$d file(s) are still being downloaded.</string>
<string name="forward_files_failed_to_receive_desc">%1$d file(s) failed to download.</string>
<string name="forward_files_missing_desc">%1$d file(s) were deleted.</string>
<string name="forward_files_not_accepted_receive_files">Download</string>
<string name="forward_files_messages_deleted_after_selection_title">%1$s messages not forwarded</string>
<!-- ShareListView.kt -->
<string name="share_message">Share message…</string>
<string name="share_image">Share media…</string>
<string name="share_file">Share file…</string>
<string name="forward_message">Forward message…</string>
<string name="forward_multiple">Forward messages…</string>
<string name="cannot_share_message_alert_title">Cannot send message</string>
<string name="cannot_share_message_alert_text">Selected chat preferences prohibit this message.</string>
@@ -419,8 +405,6 @@
<string name="files_and_media_prohibited">Files and media prohibited!</string>
<string name="only_owners_can_enable_files_and_media">Only group owners can enable files and media.</string>
<string name="compose_send_direct_message_to_connect">Send direct message to connect</string>
<string name="compose_forward_messages_n">Forwarding %1$s messages</string>
<string name="compose_save_messages_n">Saving %1$s messages</string>
<string name="simplex_links_not_allowed">SimpleX links not allowed</string>
<string name="files_and_media_not_allowed">Files and media not allowed</string>
<string name="voice_messages_not_allowed">Voice messages not allowed</string>
@@ -1075,7 +1059,6 @@
<string name="icon_descr_audio_on">Audio on</string>
<string name="icon_descr_speaker_off">Speaker off</string>
<string name="icon_descr_speaker_on">Speaker on</string>
<string name="icon_descr_sound_muted">Sound muted</string>
<string name="icon_descr_flip_camera">Flip camera</string>
<!-- Call items -->
@@ -1061,7 +1061,7 @@
<string name="v4_6_audio_video_calls_descr">Bluetooth-Unterstützung und weitere Verbesserungen.</string>
<string name="v4_6_group_moderation_descr">Administratoren können nun
\n- Nachrichten von Gruppenmitgliedern löschen
\n- Gruppenmitglieder deaktivieren (Beobachter-Rolle)</string>
\n- Gruppenmitglieder deaktivieren (Beobachter-Rolle)</string>
<string name="v4_6_group_welcome_message">Gruppen-Begrüßungsmeldung</string>
<string name="v4_6_reduced_battery_usage">Weiter reduzierter Batterieverbrauch</string>
<string name="v4_6_reduced_battery_usage_descr">Weitere Verbesserungen sind bald verfügbar!</string>
@@ -2151,23 +2151,4 @@
<string name="new_message">Neue Nachricht</string>
<string name="error_parsing_uri_desc">Bitte überprüfen Sie, ob der SimpleX-Link korrekt ist.</string>
<string name="error_parsing_uri_title">Ungültiger Link</string>
<string name="settings_section_title_chat_database">CHAT-DATENBANK</string>
<string name="switching_profile_error_title">Fehler beim Wechseln des Profils</string>
<string name="delete_messages_cannot_be_undone_warning">Die Nachrichten werden gelöscht. Dies kann nicht rückgängig gemacht werden!</string>
<string name="new_chat_share_profile">Profil teilen</string>
<string name="system_mode_toast">System-Modus</string>
<string name="migrate_from_device_uploaded_archive_will_be_removed">Das hochgeladene Datenbank-Archiv wird dauerhaft von den Servern entfernt.</string>
<string name="select_chat_profile">Chat-Profil auswählen</string>
<string name="migrate_from_device_remove_archive_question">Archiv entfernen?</string>
<string name="network_proxy_auth_mode_username_password">Ihre Anmeldeinformationen können unverschlüsselt versendet werden.</string>
<string name="network_proxy_auth_mode_no_auth">Verwenden Sie keine Anmeldeinformationen mit einem Proxy.</string>
<string name="switching_profile_error_message">Ihre Verbindung wurde auf %s verschoben, aber während der Weiterleitung auf das Profil trat ein unerwarteter Fehler auf.</string>
<string name="network_proxy_incorrect_config_desc">Stellen Sie sicher, dass die Proxy-Konfiguration richtig ist.</string>
<string name="network_proxy_incorrect_config_title">Fehler beim Speichern des Proxys</string>
<string name="network_proxy_password">Passwort</string>
<string name="network_proxy_auth">Proxy-Authentifizierung</string>
<string name="network_proxy_auth_mode_isolate_by_auth_entity">Verwenden Sie für jede Verbindung unterschiedliche Proxy-Anmeldeinformationen.</string>
<string name="network_proxy_auth_mode_isolate_by_auth_user">Verwenden Sie für jedes Profil unterschiedliche Proxy-Anmeldeinformationen.</string>
<string name="network_proxy_random_credentials">Verwenden Sie zufällige Anmeldeinformationen</string>
<string name="network_proxy_username">Benutzername</string>
</resources>
File diff suppressed because it is too large Load Diff
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="22" viewBox="0 -960 960 960" width="22"><path d="m809.5-61.5-133-133q-27 19-58.25 33.25T553.5-139.5V-199q21.5-6.5 42.5-14.5t39.5-22L476-396v229L280-363H122.5v-234H274L54.5-816.5 96-858l755 754-41.5 42.5ZM770-291l-41.5-41.5q20-33 29.75-70.67Q768-440.85 768-481q0-100.82-58.75-180.41T553.5-763v-59.5q120 28 196 123.25t76 218.25q0 50.5-14 98.75T770-291ZM642.5-418.5l-89-89v-132q46.5 21.5 73.75 64.75T654.5-480q0 16-3 31.5t-9 30ZM476-585 372-689l104-104v208Zm-57.5 278v-145.5l-87-87H180v119h124.5l114 113.5ZM375-496Z"/></svg>

Before

Width:  |  Height:  |  Size: 569 B

@@ -2069,40 +2069,4 @@
<string name="new_message">Nuovo messaggio</string>
<string name="error_parsing_uri_title">Link non valido</string>
<string name="error_parsing_uri_desc">Controlla che il link SimpleX sia corretto.</string>
<string name="switching_profile_error_title">Errore nel cambio di profilo</string>
<string name="select_chat_profile">Seleziona il profilo di chat</string>
<string name="new_chat_share_profile">Condividi il profilo</string>
<string name="settings_section_title_chat_database">DATABASE DELLA CHAT</string>
<string name="system_mode_toast">Modalità di sistema</string>
<string name="migrate_from_device_remove_archive_question">Rimuovere l\'archivio?</string>
<string name="delete_messages_cannot_be_undone_warning">I messaggi verranno eliminati. Non è reversibile!</string>
<string name="migrate_from_device_uploaded_archive_will_be_removed">L\'archivio del database caricato verrà rimosso definitivamente dai server.</string>
<string name="switching_profile_error_message">La tua connessione è stata spostata a %s, ma si è verificato un errore imprevisto durante il reindirizzamento al profilo.</string>
<string name="network_proxy_auth_mode_no_auth">Non usare credenziali con proxy.</string>
<string name="network_proxy_incorrect_config_desc">Assicurati che la configurazione del proxy sia corretta.</string>
<string name="network_proxy_auth">Autenticazione del proxy</string>
<string name="network_proxy_auth_mode_isolate_by_auth_entity">Usa diverse credenziali del proxy per ogni connessione.</string>
<string name="network_proxy_auth_mode_isolate_by_auth_user">Usa diverse credenziali del proxy per ogni profilo.</string>
<string name="network_proxy_random_credentials">Usa credenziali casuali</string>
<string name="network_proxy_auth_mode_username_password">Le credenziali potrebbero essere inviate in chiaro.</string>
<string name="network_proxy_incorrect_config_title">Errore di salvataggio del proxy</string>
<string name="network_proxy_password">Password</string>
<string name="network_proxy_username">Nome utente</string>
<string name="forward_files_in_progress_desc">%1$d file è/sono ancora in scaricamento.</string>
<string name="forward_files_messages_deleted_after_selection_title">%1$s messaggi non inoltrati</string>
<string name="n_other_file_errors">%1$d altro/i errore/i di file.</string>
<string name="error_forwarding_messages">Errore nell\'inoltro dei messaggi</string>
<string name="n_file_errors">%1$d errore/i di file:
\n%2$s</string>
<string name="forward_alert_title_messages_to_forward">Inoltrare %1$s messaggio/i?</string>
<string name="forward_alert_forward_messages_without_files">Inoltrare i messaggi senza file?</string>
<string name="forward_files_messages_deleted_after_selection_desc">I messaggi sono stati eliminati dopo che li hai selezionati.</string>
<string name="forward_alert_title_nothing_to_forward">Niente da inoltrare!</string>
<string name="forward_files_failed_to_receive_desc">%1$d file ha/hanno fallito lo scaricamento.</string>
<string name="forward_files_missing_desc">%1$d file è/sono stato/i eliminato/i.</string>
<string name="forward_files_not_accepted_desc">%1$d file non è/sono stato/i scaricato/i.</string>
<string name="forward_files_not_accepted_receive_files">Scarica</string>
<string name="compose_forward_messages_n">Inoltro di %1$s messaggi</string>
<string name="forward_multiple">Inoltra messaggi…</string>
<string name="compose_save_messages_n">Salvataggio di %1$s messaggi</string>
</resources>
@@ -312,7 +312,7 @@
<string name="how_to_use_your_servers">自分のサーバの使い方</string>
<string name="enter_one_ICE_server_per_line">ICEサーバ (1行に1サーバ)</string>
<string name="network_and_servers">ネットワークとサーバ</string>
<string name="network_settings_title">高度な設定</string>
<string name="network_settings_title">ネットワーク設定</string>
<string name="delete_address">アドレスを削除</string>
<string name="exit_without_saving">保存せずに閉じる</string>
<string name="display_name_cannot_contain_whitespace">表示の名前には空白が使用できません。</string>
@@ -535,7 +535,7 @@
<string name="colored_text">色付き</string>
<string name="callstate_received_answer">応答</string>
<string name="decentralized">分散型</string>
<string name="immune_to_spam_and_abuse">スパム耐性</string>
<string name="immune_to_spam_and_abuse">スパムや悪質送信を完全防止</string>
<string name="onboarding_notifications_mode_service">即時</string>
<string name="onboarding_notifications_mode_periodic">定期的</string>
<string name="call_already_ended">通話は既に終了してます!</string>
@@ -1837,53 +1837,4 @@
<string name="smp_servers_configured">SMPサーバーの構成</string>
<string name="servers_info_sessions_connected">接続中</string>
<string name="xftp_servers_configured">XFTPサーバーの構成</string>
<string name="one_hand_ui_card_title">チャトリスト切り替え</string>
<string name="contact_list_header_title">連絡先</string>
<string name="message_servers">メッセージサーバ</string>
<string name="media_and_file_servers">メディア&amp;ファイルサーバ</string>
<string name="one_hand_ui">チャットツールバーを近づける</string>
<string name="invite_friends_short">招待</string>
<string name="create_address_button">作成</string>
<string name="compose_message_placeholder">メッセージ</string>
<string name="v6_0_reachable_chat_toolbar">チャットツールバーを近づける</string>
<string name="scan_paste_link">QRスキャン / リンクの貼り付け</string>
<string name="v6_0_reachable_chat_toolbar_descr">片手でアプリを利用できます</string>
<string name="action_button_add_members">招待</string>
<string name="paste_link">リンクの貼り付け</string>
<string name="app_check_for_updates_notice_disable">無効</string>
<string name="current_user">現在のプロフィール</string>
<string name="all_users">全てのプロフィール</string>
<string name="info_view_call_button">通話</string>
<string name="confirm_delete_contact_question">連絡先の削除を確認しますか?</string>
<string name="info_view_connect_button">接続</string>
<string name="delete_contact_cannot_undo_warning">連絡先が削除されます - この操作は取り消せません!</string>
<string name="switching_profile_error_title">プロフィールの切り替えエラー</string>
<string name="privacy_media_blur_radius">メディアのぼかし</string>
<string name="settings_section_title_chat_database">チャットデータベース</string>
<string name="chat_database_exported_continue">続ける</string>
<string name="contact_deleted">連絡先の削除完了!</string>
<string name="servers_info_details">詳細</string>
<string name="member_info_member_inactive">非アクティブ</string>
<string name="app_check_for_updates_disabled">無効</string>
<string name="network_proxy_incorrect_config_title">プロキシの保存エラー</string>
<string name="allow_calls_question">通話を許可しますか?</string>
<string name="cant_call_contact_deleted_alert_text">連絡先が削除されました。</string>
<string name="member_info_member_disabled">無効</string>
<string name="v6_0_delete_many_messages_descr">一度に最大20件のメッセージを削除できます。</string>
<string name="servers_info_connected_servers_section_header">サーバに接続中</string>
<string name="servers_info_modal_error_title">エラー</string>
<string name="servers_info_reconnect_server_error">サーバーへの再接続エラー</string>
<string name="servers_info_sessions_errors">エラー</string>
<string name="servers_info_files_tab">ファイル</string>
<string name="decryption_errors">復号化エラー</string>
<string name="deletion_errors">削除エラー</string>
<string name="duplicates_label">重複</string>
<string name="expired_label">期限切れ</string>
<string name="servers_info_detailed_statistics">統計の詳細</string>
<string name="network_proxy_auth_mode_no_auth">プロキシで認証情報を使用しないでください。</string>
<string name="servers_info_reconnect_servers_error">サーバーへの再接続エラー</string>
<string name="servers_info_reset_stats_alert_error_title">統計のリセットエラー</string>
<string name="cannot_share_message_alert_title">メッセージを送信することができません</string>
<string name="cant_call_contact_alert_title">連絡先と通話することができません</string>
<string name="servers_info_sessions_connecting">接続待ち</string>
</resources>
@@ -72,7 +72,7 @@
<string name="about_simplex">Over SimpleX</string>
<string name="about_simplex_chat">Over SimpleX Chat</string>
<string name="above_then_preposition_continuation">hier boven, dan:</string>
<string name="users_delete_all_chats_deleted">Alle chats en berichten worden verwijderd, dit kan niet ongedaan worden gemaakt!</string>
<string name="users_delete_all_chats_deleted">Alle gesprekken en berichten worden verwijderd, dit kan niet ongedaan worden gemaakt!</string>
<string name="clear_chat_warning">Alle berichten worden verwijderd, dit kan niet ongedaan worden gemaakt! De berichten worden ALLEEN voor jou verwijderd.</string>
<string name="allow_disappearing_messages_only_if">Sta verdwijnende berichten alleen toe als uw contact dit toestaat.</string>
<string name="allow_voice_messages_only_if">Sta spraak berichten alleen toe als uw contact ze toestaat.</string>
@@ -90,7 +90,7 @@
<string name="settings_section_title_icon">APP ICON</string>
<string name="app_version_title">App versie</string>
<string name="app_version_name">App versie: v%s</string>
<string name="network_session_mode_user_description"><![CDATA[Er wordt een aparte TCP-verbinding (en SOCKS-referentie) gebruikt <b> voor elk chatprofiel dat je in de app hebt </b>.]]></string>
<string name="network_session_mode_user_description"><![CDATA[Er wordt een aparte TCP-verbinding (en SOCKS-referentie) gebruikt <b> voor elk chat profiel dat je in de app hebt </b>.]]></string>
<string name="audio_call_no_encryption">audio oproep (niet e2e versleuteld)</string>
<string name="notifications_mode_service_desc">Achtergrondservice is altijd actief, meldingen worden weergegeven zodra de berichten beschikbaar zijn.</string>
<string name="icon_descr_call_ended">Oproep beëindigd</string>
@@ -120,9 +120,9 @@
<string name="chat_archive_header">Gesprek archief</string>
<string name="change_database_passphrase_question">Wachtwoord database wijzigen\?</string>
<string name="chat_is_stopped_indication">Chat is gestopt</string>
<string name="chat_preferences">Chat voorkeuren</string>
<string name="network_session_mode_user">Chatprofiel</string>
<string name="settings_section_title_chats">CHATS</string>
<string name="chat_preferences">Gesprek voorkeuren</string>
<string name="network_session_mode_user">Chat profiel</string>
<string name="settings_section_title_chats">GESPREKKEN</string>
<string name="chat_with_developers">Praat met de ontwikkelaars</string>
<string name="smp_servers_check_address">Controleer het server adres en probeer het opnieuw.</string>
<string name="choose_file">Bestand</string>
@@ -180,7 +180,7 @@
<string name="database_will_be_encrypted_and_passphrase_stored">"De database wordt versleuteld en het wachtwoord wordt opgeslagen in de Keychain."</string>
<string name="database_passphrase_will_be_updated">Het wachtwoord voor database versleuteling wordt bijgewerkt.</string>
<string name="database_error">Database fout</string>
<string name="database_passphrase_is_required">Database wachtwoord is vereist om je chats te openen.</string>
<string name="database_passphrase_is_required">Database wachtwoord is vereist om je gesprekken te openen.</string>
<string name="contact_already_exists">Contact bestaat al</string>
<string name="icon_descr_call_connecting">Oproep verbinden</string>
<string name="button_create_group_link">Maak link</string>
@@ -233,7 +233,7 @@
<string name="delete_chat_archive_question">Chat archief verwijderen\?</string>
<string name="delete_archive">Archief verwijderen</string>
<string name="delete_contact_question">Verwijder contact\?</string>
<string name="delete_chat_profile_question">Chatprofiel verwijderen?</string>
<string name="delete_chat_profile_question">Chat profiel verwijderen\?</string>
<string name="full_deletion">Verwijderen voor iedereen</string>
<string name="delete_link">Link verwijderen</string>
<string name="conn_level_desc_direct">direct</string>
@@ -250,7 +250,7 @@
<string name="delete_message__question">Verwijder bericht\?</string>
<string name="delete_messages">Verwijder berichten</string>
<string name="smp_server_test_delete_queue">Wachtrij verwijderen</string>
<string name="delete_files_and_media_for_all_users">Verwijder bestanden voor alle chatprofielen</string>
<string name="delete_files_and_media_for_all_users">Verwijder bestanden voor alle chat profielen</string>
<string name="for_me_only">Verwijder voor mij</string>
<string name="button_delete_group">Groep verwijderen</string>
<string name="delete_link_question">Link verwijderen\?</string>
@@ -284,7 +284,7 @@
<string name="ttl_mth">%dmth</string>
<string name="ttl_hours">%d uren</string>
<string name="ttl_h">%dh</string>
<string name="users_delete_question">Chatprofiel verwijderen?</string>
<string name="users_delete_question">Chat profiel verwijderen\?</string>
<string name="users_delete_profile_for">Chat profiel verwijderen voor</string>
<string name="deleted_description">verwijderd</string>
<string name="simplex_link_mode_description">Beschrijving</string>
@@ -347,7 +347,7 @@
<string name="group_members_can_delete">Groepsleden kunnen verzonden berichten onomkeerbaar verwijderen. (24 uur)</string>
<string name="group_members_can_send_dms">Groepsleden kunnen directe berichten sturen</string>
<string name="group_members_can_send_voice">Groepsleden kunnen spraak berichten verzenden.</string>
<string name="v4_5_transport_isolation_descr">Per chatprofiel (standaard) of per verbinding (BETA).</string>
<string name="v4_5_transport_isolation_descr">Per chat profiel (standaard) of per verbinding (BETA).</string>
<string name="v4_5_multiple_chat_profiles_descr">Verschillende namen, avatars en transportisolatie.</string>
<string name="v4_4_french_interface">Franse interface</string>
<string name="error_saving_group_profile">Fout bij opslaan van groep profiel</string>
@@ -392,7 +392,7 @@
<string name="error_saving_smp_servers">Fout bij opslaan van SMP servers</string>
<string name="error_setting_network_config">Fout bij updaten van netwerk configuratie</string>
<string name="failed_to_parse_chat_title">Kan het gesprek niet laden</string>
<string name="failed_to_parse_chats_title">Kan de chats niet laden</string>
<string name="failed_to_parse_chats_title">Kan de gesprekken niet laden</string>
<string name="simplex_link_mode_full">Volledige link</string>
<string name="integrity_msg_duplicate">dubbel bericht</string>
<string name="invalid_connection_link">Ongeldige verbinding link</string>
@@ -456,10 +456,10 @@
<string name="leave_group_question">Groep verlaten\?</string>
<string name="new_member_role">Nieuwe leden rol</string>
<string name="no_contacts_to_add">Geen contacten om toe te voegen</string>
<string name="incognito_info_allows">Het maakt het mogelijk om veel anonieme verbindingen te hebben zonder enige gedeelde gegevens tussen hen in een enkel chatprofiel.</string>
<string name="incognito_info_allows">Het maakt het mogelijk om veel anonieme verbindingen te hebben zonder enige gedeelde gegevens tussen hen in een enkel chat profiel.</string>
<string name="theme_light">Licht</string>
<string name="chat_preferences_no">nee</string>
<string name="v4_5_multiple_chat_profiles">Meerdere chatprofielen</string>
<string name="v4_5_multiple_chat_profiles">Meerdere chat profielen</string>
<string name="v4_5_italian_interface">Italiaanse interface</string>
<string name="v4_5_message_draft">Concept bericht</string>
<string name="v4_5_reduced_battery_usage_descr">Meer verbeteringen volgen snel!</string>
@@ -590,7 +590,7 @@
<string name="only_your_contact_can_send_voice">Alleen uw contact kan spraak berichten verzenden.</string>
<string name="prohibit_message_deletion">Verbied het onomkeerbaar verwijderen van berichten.</string>
<string name="feature_offered_item">voorgesteld %s</string>
<string name="store_passphrase_securely_without_recover">Sla het wachtwoord veilig op. Als u deze kwijtraakt, heeft u GEEN toegang tot de chats.</string>
<string name="store_passphrase_securely_without_recover">Sla het wachtwoord veilig op. Als u deze kwijtraakt, heeft u GEEN toegang tot de gesprekken.</string>
<string name="store_passphrase_securely">Bewaar het wachtwoord veilig, u kunt deze NIET wijzigen als u deze kwijtraakt.</string>
<string name="open_chat">Chat openen</string>
<string name="restore_database_alert_desc">Voer het vorige wachtwoord in na het herstellen van de database back-up. Deze actie kan niet ongedaan gemaakt worden.</string>
@@ -620,12 +620,12 @@
<string name="you_control_servers_to_receive_your_contacts_to_send"><![CDATA[U bepaalt via welke server(s) je de berichten <b>ontvangt</b>, uw contacten de servers die u gebruikt om ze berichten te sturen.]]></string>
<string name="icon_descr_video_on">Video aan</string>
<string name="delete_chat_profile_action_cannot_be_undone_warning">Deze actie kan niet ongedaan worden gemaakt. Uw profiel, contacten, berichten en bestanden gaan onomkeerbaar verloren.</string>
<string name="messages_section_description">Deze instelling is van toepassing op berichten in uw huidige chatprofiel</string>
<string name="messages_section_description">Deze instelling is van toepassing op berichten in uw huidige chat profiel</string>
<string name="save_archive">Bewaar archief</string>
<string name="rcv_group_event_updated_group_profile">bijgewerkt groep profiel</string>
<string name="group_member_status_removed">verwijderd</string>
<string name="group_main_profile_sent">Uw chatprofiel wordt verzonden naar de groepsleden</string>
<string name="failed_to_create_user_duplicate_desc">Je hebt al een chatprofiel met dezelfde weergave naam. Kies een andere naam.</string>
<string name="group_main_profile_sent">Uw chat profiel wordt verzonden naar de groepsleden</string>
<string name="failed_to_create_user_duplicate_desc">Je hebt al een chat profiel met dezelfde weergave naam. Kies een andere naam.</string>
<string name="you_are_already_connected_to_vName_via_this_link">U bent al verbonden met %1$s.</string>
<string name="error_smp_test_failed_at_step">Test mislukt bij stap %s.</string>
<string name="smp_server_test_secure_queue">Veilige wachtrij</string>
@@ -650,8 +650,8 @@
<string name="this_text_is_available_in_settings">Deze tekst is beschikbaar in instellingen</string>
<string name="welcome">Welkom!</string>
<string name="group_preview_you_are_invited">je bent uitgenodigd voor de groep</string>
<string name="you_have_no_chats">Je hebt geen chats</string>
<string name="your_chats">Chats</string>
<string name="you_have_no_chats">Je hebt geen gesprekken</string>
<string name="your_chats">Gesprekken</string>
<string name="share_file">Deel bestand…</string>
<string name="share_image">Afbeelding delen…</string>
<string name="icon_descr_waiting_for_image">Wachten op afbeelding</string>
@@ -680,7 +680,7 @@
<string name="icon_descr_address">SimpleX Adres</string>
<string name="show_QR_code">Toon QR-code</string>
<string name="image_descr_simplex_logo">SimpleX-Logo</string>
<string name="your_chat_profile_will_be_sent_to_your_contact">Je chatprofiel wordt verzonden naar uw contact</string>
<string name="your_chat_profile_will_be_sent_to_your_contact">Je chat profiel wordt verzonden naar uw contact</string>
<string name="you_will_be_connected_when_group_host_device_is_online">Je wordt verbonden met de groep wanneer het apparaat van de groep host online is, even geduld a.u.b. of controleer het later!</string>
<string name="you_will_be_connected_when_your_connection_request_is_accepted">U wordt verbonden wanneer uw verbindingsverzoek wordt geaccepteerd, even geduld a.u.b. of controleer later!</string>
<string name="you_will_be_connected_when_your_contacts_device_is_online">Je wordt verbonden wanneer het apparaat van je contact online is, even geduld a.u.b. of controleer het later!</string>
@@ -696,7 +696,7 @@
<string name="send_us_an_email">Stuur ons een e-mail</string>
<string name="chat_lock">SimpleX Vergrendelen</string>
<string name="smp_servers">SMP servers</string>
<string name="smp_servers_save">Servers opslaan</string>
<string name="smp_servers_save">Bewaar servers</string>
<string name="smp_servers_test_failed">Servertest mislukt!</string>
<string name="smp_servers_test_some_failed">Sommige servers hebben de test niet doorstaan:</string>
<string name="smp_servers_test_servers">Servers testen</string>
@@ -747,7 +747,7 @@
<string name="run_chat_section">CHAT UITVOEREN</string>
<string name="your_chat_database">Uw chat database</string>
<string name="set_password_to_export">Wachtwoord instellen om te exporteren</string>
<string name="restart_the_app_to_create_a_new_chat_profile">Start de app opnieuw om een nieuw chatprofiel aan te maken.</string>
<string name="restart_the_app_to_create_a_new_chat_profile">Start de app opnieuw om een nieuw chat profiel aan te maken.</string>
<string name="you_must_use_the_most_recent_version_of_database">U mag ALLEEN de meest recente versie van uw chat-database op één apparaat gebruiken, anders ontvangt u mogelijk geen berichten meer van sommige contacten.</string>
<string name="restart_the_app_to_use_imported_chat_database">Start de app opnieuw om de geïmporteerde chat database te gebruiken.</string>
<string name="stop_chat_to_enable_database_actions">Stop de chat om database acties mogelijk te maken.</string>
@@ -842,7 +842,7 @@
<string name="use_camera_button">Camera</string>
<string name="smp_servers_use_server_for_new_conn">Gebruik voor nieuwe verbindingen</string>
<string name="star_on_github">Star on GitHub</string>
<string name="smp_servers_per_user">De servers voor nieuwe verbindingen van je huidige chatprofiel</string>
<string name="smp_servers_per_user">De servers voor nieuwe verbindingen van je huidige chat profiel</string>
<string name="your_SMP_servers">Uw SMP servers</string>
<string name="saved_ICE_servers_will_be_removed">Opgeslagen WebRTC ICE servers worden verwijderd.</string>
<string name="your_ICE_servers">Uw ICE servers</string>
@@ -865,7 +865,7 @@
<string name="v4_3_irreversible_message_deletion_desc">Uw contacten kunnen volledige verwijdering van berichten toestaan.</string>
<string name="you_have_to_enter_passphrase_every_time">U moet elke keer dat de app start het wachtwoord invoeren, deze wordt niet op het apparaat opgeslagen.</string>
<string name="wrong_passphrase">Verkeerd wachtwoord voor de database</string>
<string name="save_passphrase_and_open_chat">Bewaar het wachtwoord en open je chats</string>
<string name="save_passphrase_and_open_chat">Bewaar het wachtwoord en open je gesprekken</string>
<string name="database_backup_can_be_restored">De poging om het wachtwoord van de database te wijzigen is niet voltooid.</string>
<string name="restore_database">Database back-up terugzetten</string>
<string name="restore_database_alert_title">Database back-up terugzetten\?</string>
@@ -963,7 +963,7 @@
<string name="error_updating_user_privacy">Fout bij updaten van gebruikers privacy</string>
<string name="v4_6_reduced_battery_usage">Verder verminderd batterij verbruik</string>
<string name="v4_6_group_welcome_message">Groep welkom bericht</string>
<string name="v4_6_hidden_chat_profiles">Verborgen chatprofielen</string>
<string name="v4_6_hidden_chat_profiles">Verborgen chat profielen</string>
<string name="hide_profile">Profiel verbergen</string>
<string name="user_hide">Verbergen</string>
<string name="hidden_profile_password">Verborgen profiel wachtwoord</string>
@@ -974,7 +974,7 @@
<string name="v4_6_group_moderation_descr">Nu kunnen beheerders:
\n- berichten van leden verwijderen.
\n- schakel leden uit ("waarnemer" rol)</string>
<string name="v4_6_hidden_chat_profiles_descr">Bescherm je chatprofielen met een wachtwoord!</string>
<string name="v4_6_hidden_chat_profiles_descr">Bescherm je chat profielen met een wachtwoord!</string>
<string name="password_to_show">Wachtwoord om weer te geven</string>
<string name="save_and_update_group_profile">Groep profiel opslaan en bijwerken</string>
<string name="smp_save_servers_question">Servers opslaan\?</string>
@@ -988,7 +988,7 @@
<string name="user_unhide">zichtbaar maken</string>
<string name="user_unmute">Dempen opheffen</string>
<string name="group_welcome_title">Welkom bericht</string>
<string name="to_reveal_profile_enter_password">Om uw verborgen profiel te onthullen, voert u een volledig wachtwoord in een zoekveld in op de pagina Uw chatprofielen.</string>
<string name="to_reveal_profile_enter_password">Om uw verborgen profiel te onthullen, voert u een volledig wachtwoord in een zoekveld in op de pagina Uw chat profielen.</string>
<string name="button_welcome_message">Welkom bericht</string>
<string name="you_will_still_receive_calls_and_ntfs">U ontvangt nog steeds oproepen en meldingen van gedempte profielen wanneer deze actief zijn.</string>
<string name="database_downgrade">Database downgraden</string>
@@ -1011,9 +1011,9 @@
<string name="settings_section_title_experimenta">EXPERIMENTEEL</string>
<string name="delete_profile">Verwijder profiel</string>
<string name="profile_password">Profiel wachtwoord</string>
<string name="unhide_chat_profile">Chatprofiel zichtbaar maken</string>
<string name="unhide_chat_profile">Chat profiel zichtbaar maken</string>
<string name="unhide_profile">Profiel zichtbaar maken</string>
<string name="delete_chat_profile">Chatprofiel verwijderen?</string>
<string name="delete_chat_profile">Chat profiel verwijderen\?</string>
<string name="icon_descr_video_asked_to_receive">Gevraagd om de video te ontvangen</string>
<string name="videos_limit_desc">Er kunnen slechts 10 video\'s tegelijk worden verzonden</string>
<string name="videos_limit_title">Te veel video\'s!</string>
@@ -1107,7 +1107,7 @@
<string name="v5_0_polish_interface">Poolse interface</string>
<string name="v5_0_polish_interface_descr">Dank aan de gebruikers draag bij via Weblate!</string>
<string name="v5_0_large_files_support">Video\'s en bestanden tot 1 GB</string>
<string name="auth_open_chat_profiles">Open chatprofielen</string>
<string name="auth_open_chat_profiles">Chat profielen openen</string>
<string name="learn_more_about_address">Over SimpleX adres</string>
<string name="learn_more">Kom meer te weten</string>
<string name="scan_qr_to_connect_to_contact">Om verbinding te maken, kan uw contact de QR-code scannen of de link in de app gebruiken.</string>
@@ -1249,7 +1249,7 @@
<string name="abort_switch_receiving_address_desc">Adres wijziging wordt afgebroken. Het oude ontvangstadres wordt gebruikt.</string>
<string name="abort_switch_receiving_address">Annuleer het wijzigen van het adres</string>
<string name="abort_switch_receiving_address_confirm">Afbreken</string>
<string name="no_filtered_chats">Geen gefilterde chats</string>
<string name="no_filtered_chats">Geen gefilterde gesprekken</string>
<string name="only_owners_can_enable_files_and_media">Alleen groep eigenaren kunnen bestanden en media inschakelen.</string>
<string name="files_are_prohibited_in_group">Bestanden en media zijn verboden in deze groep.</string>
<string name="favorite_chat">Favoriet</string>
@@ -1303,7 +1303,7 @@
<string name="send_receipts">Ontvangst bevestiging verzenden</string>
<string name="v5_2_message_delivery_receipts_descr">De tweede vink die we gemist hebben! ✅</string>
<string name="v5_2_favourites_filter_descr">Filter ongelezen en favoriete chats.</string>
<string name="v5_2_favourites_filter">Vind chats sneller</string>
<string name="v5_2_favourites_filter">Vind gesprekken sneller</string>
<string name="v5_2_fix_encryption_descr">Repareer versleuteling na het herstellen van back-ups.</string>
<string name="v5_2_fix_encryption">Behoud uw verbindingen</string>
<string name="v5_2_disappear_one_message">Eén bericht laten verdwijnen</string>
@@ -1538,7 +1538,7 @@
<string name="recent_history">Zichtbare geschiedenis</string>
<string name="la_app_passcode">App toegangscode</string>
<string name="new_chat">Nieuw gesprek</string>
<string name="loading_chats">Chats laden…</string>
<string name="loading_chats">Gesprekken laden…</string>
<string name="creating_link">Link maken…</string>
<string name="or_scan_qr_code">Of scan de QR-code</string>
<string name="invalid_qr_code">Ongeldige QR-code</string>
@@ -2057,7 +2057,7 @@
<string name="one_hand_ui_change_instruction">U kunt dit wijzigen in de instellingen onder uiterlijk</string>
<string name="create_address_button">Creëren</string>
<string name="v6_0_privacy_blur">Vervagen voor betere privacy.</string>
<string name="v6_0_chat_list_media">Afspelen via de chatlijst.</string>
<string name="v6_0_chat_list_media">Afspelen via de gesprekken lijst.</string>
<string name="v6_0_upgrade_app_descr">Download nieuwe versies van GitHub.</string>
<string name="v6_0_increase_font_size">Vergroot het lettertype.</string>
<string name="v6_0_upgrade_app">App automatisch upgraden</string>
@@ -2067,13 +2067,4 @@
<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>
<string name="switching_profile_error_title">Fout bij wisselen van profiel</string>
<string name="select_chat_profile">Selecteer chatprofiel</string>
<string name="new_chat_share_profile">Profiel delen</string>
<string name="switching_profile_error_message">Uw verbinding is verplaatst naar %s, maar er is een onverwachte fout opgetreden tijdens het omleiden naar het profiel.</string>
<string name="settings_section_title_chat_database">CHAT DATABASE</string>
<string name="system_mode_toast">Systeemmodus</string>
<string name="migrate_from_device_remove_archive_question">Archief verwijderen?</string>
<string name="delete_messages_cannot_be_undone_warning">Berichten worden verwijderd. Dit kan niet ongedaan worden gemaakt!</string>
<string name="migrate_from_device_uploaded_archive_will_be_removed">Het geüploade databasearchief wordt permanent van de servers verwijderd.</string>
</resources>
@@ -949,23 +949,4 @@
<string name="servers_info_details">Detalhes</string>
<string name="you_can_share_this_address_with_your_contacts">Você pode partilhar o seu endereço com os seus contactos para permitir que se conectem com %s.</string>
<string name="you_can_share_your_address">Você pode partilhar o seu endereço como uma ligação ou código QR - qualquer pessoa pode conectar-se a si.</string>
<string name="turn_off_battery_optimization_button">Permitir</string>
<string name="block_member_desc">Todas as novas mensagens de %s serão ocultadas!</string>
<string name="only_you_can_make_calls">Somente você pode fazer ligações.</string>
<string name="chat_theme_apply_to_all_modes">Todos os modos de cores</string>
<string name="feature_roles_admins">administradores</string>
<string name="snd_conn_event_ratchet_sync_started">"aceitando criptografia para %s…"</string>
<string name="add_contact_tab">Adicionar contato</string>
<string name="network_smp_proxy_fallback_allow_downgrade">Permitir downgrade</string>
<string name="clear_note_folder_warning">Todas as mensagens serão deletadas - isso não poderá ser desfeito!</string>
<string name="v5_2_more_things">Mais algumas coisas</string>
<string name="allow_to_send_files">Permitir envio de arquivos e mídias.</string>
<string name="v5_6_safer_groups_descr">Administradores podem bloquear um membro para todos.</string>
<string name="conn_event_ratchet_sync_started">Aceitando criptografia</string>
<string name="wallpaper_advanced_settings">Configurações avançadas</string>
<string name="feature_roles_all_members">todos os membros</string>
<string name="acknowledgement_errors">Erros de reconhecimento</string>
<string name="abort_switch_receiving_address_desc">Mudança de endereço será cancelada. Antigo endereço de recebimento será usado.</string>
<string name="allow_calls_question">Permitir ligações?</string>
<string name="servers_info_subscriptions_connections_subscribed">Conexões ativas</string>
</resources>
@@ -776,7 +776,7 @@
<string name="v4_5_italian_interface_descr">Дякуємо користувачам – приєднуйтеся через Weblate!</string>
<string name="v4_6_group_moderation_descr">Тепер адміністратори можуть:
\n- видаляти повідомлення учасників.
\n- вимикати учасників (роль спостерігача).</string>
\n- вимикати учасників (роль спостерігач)</string>
<string name="v4_6_group_welcome_message_descr">Встановіть повідомлення, яке показується новим учасникам!</string>
<string name="v4_6_reduced_battery_usage">Додатково зменшено використання батареї</string>
<string name="v4_6_reduced_battery_usage_descr">Більше поліпшень незабаром!</string>
@@ -2067,23 +2067,4 @@
<string name="reset_all_hints">Скинути всі підказки</string>
<string name="app_check_for_updates_update_available">Доступно оновлення: %s</string>
<string name="app_check_for_updates_canceled">Завантаження оновлення скасовано</string>
<string name="settings_section_title_chat_database">БАЗА ДАНИХ ЧАТУ</string>
<string name="select_chat_profile">Вибрати профіль чату</string>
<string name="switching_profile_error_title">Помилка при зміні профілю</string>
<string name="delete_messages_cannot_be_undone_warning">Повідомлення будуть видалені — це не можна скасувати!</string>
<string name="migrate_from_device_remove_archive_question">Видалити архів?</string>
<string name="new_chat_share_profile">Поділитися профілем</string>
<string name="migrate_from_device_uploaded_archive_will_be_removed">Завантажений архів бази даних буде остаточно видалено з серверів.</string>
<string name="switching_profile_error_message">Ваше з\'єднання було перенесено на %s, але виникла несподівана помилка під час перенаправлення на профіль.</string>
<string name="system_mode_toast">Режим системи</string>
<string name="network_proxy_auth_mode_no_auth">Не використовуйте облікові дані з проксі.</string>
<string name="network_proxy_auth">Аутентифікація проксі</string>
<string name="network_proxy_auth_mode_isolate_by_auth_entity">Використовуйте різні облікові дані проксі для кожного з\'єднання.</string>
<string name="network_proxy_random_credentials">Використовувати випадкові облікові дані</string>
<string name="network_proxy_auth_mode_username_password">Ваші облікові дані можуть бути надіслані в незашифрованому вигляді.</string>
<string name="network_proxy_incorrect_config_title">Помилка під час збереження проксі</string>
<string name="network_proxy_incorrect_config_desc">Переконайтеся, що конфігурація проксі правильна.</string>
<string name="network_proxy_password">Пароль</string>
<string name="network_proxy_username">Ім\'я користувача</string>
<string name="network_proxy_auth_mode_isolate_by_auth_user">Використовуйте різні облікові дані проксі для кожного профілю.</string>
</resources>

Some files were not shown because too many files have changed in this diff Show More