diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift
index 3c6da34ae5..da859c1606 100644
--- a/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift
+++ b/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift
@@ -70,7 +70,7 @@ struct CIGroupInvitationView: View {
}
.padding(.horizontal, 12)
.padding(.vertical, 6)
- .background(chatItemFrameColor(chatItem, theme))
+ .background { chatItemFrameColor(chatItem, theme).modifier(ChatTailPadding()) }
.textSelection(.disabled)
.onPreferenceChange(DetermineWidth.Key.self) { frameWidth = $0 }
.onChange(of: inProgress) { inProgress in
diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift
index 915af3f479..9f721f83b7 100644
--- a/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift
+++ b/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift
@@ -69,37 +69,40 @@ struct CIRcvDecryptionError: View {
}
@ViewBuilder private func viewBody() -> some View {
- if case let .direct(contact) = chat.chatInfo,
- let contactStats = contact.activeConn?.connectionStats {
- if contactStats.ratchetSyncAllowed {
- decryptionErrorItemFixButton(syncSupported: true) {
- alert = .syncAllowedAlert { syncContactConnection(contact) }
+ Group {
+ if case let .direct(contact) = chat.chatInfo,
+ let contactStats = contact.activeConn?.connectionStats {
+ if contactStats.ratchetSyncAllowed {
+ decryptionErrorItemFixButton(syncSupported: true) {
+ alert = .syncAllowedAlert { syncContactConnection(contact) }
+ }
+ } else if !contactStats.ratchetSyncSupported {
+ decryptionErrorItemFixButton(syncSupported: false) {
+ alert = .syncNotSupportedContactAlert
+ }
+ } else {
+ basicDecryptionErrorItem()
}
- } else if !contactStats.ratchetSyncSupported {
- decryptionErrorItemFixButton(syncSupported: false) {
- alert = .syncNotSupportedContactAlert
+ } else if case let .group(groupInfo) = chat.chatInfo,
+ case let .groupRcv(groupMember) = chatItem.chatDir,
+ let mem = m.getGroupMember(groupMember.groupMemberId),
+ let memberStats = mem.wrapped.activeConn?.connectionStats {
+ if memberStats.ratchetSyncAllowed {
+ decryptionErrorItemFixButton(syncSupported: true) {
+ alert = .syncAllowedAlert { syncMemberConnection(groupInfo, groupMember) }
+ }
+ } else if !memberStats.ratchetSyncSupported {
+ decryptionErrorItemFixButton(syncSupported: false) {
+ alert = .syncNotSupportedMemberAlert
+ }
+ } else {
+ basicDecryptionErrorItem()
}
} else {
basicDecryptionErrorItem()
}
- } else if case let .group(groupInfo) = chat.chatInfo,
- case let .groupRcv(groupMember) = chatItem.chatDir,
- let mem = m.getGroupMember(groupMember.groupMemberId),
- let memberStats = mem.wrapped.activeConn?.connectionStats {
- if memberStats.ratchetSyncAllowed {
- decryptionErrorItemFixButton(syncSupported: true) {
- alert = .syncAllowedAlert { syncMemberConnection(groupInfo, groupMember) }
- }
- } else if !memberStats.ratchetSyncSupported {
- decryptionErrorItemFixButton(syncSupported: false) {
- alert = .syncNotSupportedMemberAlert
- }
- } else {
- basicDecryptionErrorItem()
- }
- } else {
- basicDecryptionErrorItem()
}
+ .background { chatItemFrameColor(chatItem, theme).modifier(ChatTailPadding()) }
}
private func basicDecryptionErrorItem() -> some View {
@@ -132,7 +135,6 @@ struct CIRcvDecryptionError: View {
}
.onTapGesture(perform: { onClick() })
.padding(.vertical, 6)
- .background(Color(uiColor: .tertiarySystemGroupedBackground))
.textSelection(.disabled)
}
@@ -151,7 +153,6 @@ struct CIRcvDecryptionError: View {
}
.onTapGesture(perform: { onClick() })
.padding(.vertical, 6)
- .background(Color(uiColor: .tertiarySystemGroupedBackground))
.textSelection(.disabled)
}
diff --git a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift
index 159d01bbc9..260ac64e43 100644
--- a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift
+++ b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift
@@ -71,8 +71,8 @@ struct FramedItemView: View {
.overlay(DetermineWidth())
.accessibilityLabel("")
}
- }
- .background(chatItemFrameColorMaybeImageOrVideo(chatItem, theme))
+ }
+ .background { chatItemFrameColorMaybeImageOrVideo(chatItem, theme).modifier(ChatTailPadding()) }
.onPreferenceChange(DetermineWidth.Key.self) { msgWidth = $0 }
if let (title, text) = chatItem.meta.itemStatus.statusInfo {
diff --git a/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift
index 822dda4d06..afeb88b05d 100644
--- a/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift
+++ b/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift
@@ -69,7 +69,7 @@ struct CIMsgError: View {
}
.padding(.leading, 12)
.padding(.vertical, 6)
- .background(Color(uiColor: .tertiarySystemGroupedBackground))
+ .background { chatItemFrameColor(chatItem, theme).modifier(ChatTailPadding()) }
.textSelection(.disabled)
.onTapGesture(perform: onTap)
}
diff --git a/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift
index 25e06b9ea4..afd817357c 100644
--- a/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift
+++ b/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift
@@ -22,7 +22,7 @@ struct MarkedDeletedItemView: View {
.foregroundColor(theme.colors.secondary)
.padding(.horizontal, 12)
.padding(.vertical, 6)
- .background(chatItemFrameColor(chatItem, theme))
+ .background { chatItemFrameColor(chatItem, theme).modifier(ChatTailPadding()) }
.textSelection(.disabled)
}
diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift
index 703be5d65f..ea864d4753 100644
--- a/apps/ios/Shared/Views/Chat/ChatView.swift
+++ b/apps/ios/Shared/Views/Chat/ChatView.swift
@@ -726,19 +726,20 @@ struct ChatView: View {
var revealed: Bool { chatItem == revealedChatItem }
- typealias ItemSeparation = (timestamp: Bool, largeGap: Bool)
-
+ typealias ItemSeparation = (timestamp: Bool, largeGap: Bool, date: Date?)
+
func getItemSeparation(_ chatItem: ChatItem, at i: Int?) -> ItemSeparation {
let im = ItemsModel.shared
if let i, i > 0 && im.reversedChatItems.count >= i {
let nextItem = im.reversedChatItems[i - 1]
- let largeGap = !nextItem.chatDir.sameDirection(chatItem.chatDir) || nextItem.meta.createdAt.timeIntervalSince(chatItem.meta.createdAt) > 60
+ let largeGap = !nextItem.chatDir.sameDirection(chatItem.chatDir) || nextItem.meta.itemTs.timeIntervalSince(chatItem.meta.itemTs) > 60
return (
- timestamp: largeGap || formatTimestampText(chatItem.meta.createdAt) != formatTimestampText(nextItem.meta.createdAt),
- largeGap: largeGap
+ timestamp: largeGap || formatTimestampText(chatItem.meta.itemTs) != formatTimestampText(nextItem.meta.itemTs),
+ largeGap: largeGap,
+ date: Calendar.current.isDate(chatItem.meta.itemTs, inSameDayAs: nextItem.meta.itemTs) ? nil : nextItem.meta.itemTs
)
} else {
- return (timestamp: true, largeGap: true)
+ return (timestamp: true, largeGap: true, date: nil)
}
}
@@ -769,7 +770,20 @@ struct ChatView: View {
}
}
} else {
- chatItemView(chatItem, range, prevItem, timeSeparation)
+ VStack(spacing: 0) {
+ chatItemView(chatItem, range, prevItem, timeSeparation)
+ if let date = timeSeparation.date {
+ Text(String.localizedStringWithFormat(
+ NSLocalizedString("%@, %@", comment: "format for date separator in chat"),
+ date.formatted(.dateTime.weekday(.abbreviated)),
+ date.formatted(.dateTime.day().month(.abbreviated))
+ ))
+ .font(.callout)
+ .fontWeight(.medium)
+ .foregroundStyle(.secondary)
+ .padding(8)
+ }
+ }
.overlay {
if let selected = selectedChatItems, chatItem.canBeDeletedForSelf {
Color.clear
@@ -843,14 +857,14 @@ struct ChatView: View {
.foregroundStyle(.secondary)
.lineLimit(2)
.padding(.leading, memberImageSize + 14 + (selectedChatItems != nil && ci.canBeDeletedForSelf ? 12 + 24 : 0))
- .padding(.top, 7)
+ .padding(.top, 3) // this is in addition to message sequence gap
}
HStack(alignment: .center, spacing: 0) {
if selectedChatItems != nil && ci.canBeDeletedForSelf {
SelectedChatItem(ciId: ci.id, selectedChatItems: $selectedChatItems)
.padding(.trailing, 12)
}
- HStack(alignment: .top, spacing: 8) {
+ HStack(alignment: .top, spacing: 10) {
MemberProfileImage(member, size: memberImageSize, backgroundColor: theme.colors.background)
.onTapGesture {
if let member = m.getGroupMember(member.groupMemberId) {
@@ -878,7 +892,7 @@ struct ChatView: View {
}
chatItemWithMenu(ci, range, maxWidth, itemSeparation)
.padding(.trailing)
- .padding(.leading, memberImageSize + 8 + 12)
+ .padding(.leading, 10 + memberImageSize + 12)
}
.padding(.bottom, bottomPadding)
}
@@ -922,7 +936,7 @@ struct ChatView: View {
allowMenu: $allowMenu
)
.environment(\.showTimestamp, itemSeparation.timestamp)
- .modifier(ChatItemClipped(ci))
+ .modifier(ChatItemClipped(ci, tailVisible: itemSeparation.largeGap))
.contextMenu { menu(ci, range, live: composeState.liveMessage != nil) }
.accessibilityLabel("")
if ci.content.msgContent != nil && (ci.meta.itemDeleted == nil || revealed) && ci.reactions.count > 0 {
diff --git a/apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift b/apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift
index 477dc567eb..ddae6a5f6d 100644
--- a/apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift
+++ b/apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift
@@ -14,50 +14,60 @@ import SimpleXChat
/// Supports [Dynamic Type](https://developer.apple.com/documentation/uikit/uifont/scaling_fonts_automatically)
/// by retaining pill shape, even when ``ChatItem``'s height is less that twice its corner radius
struct ChatItemClipped: ViewModifier {
- struct ClipShape: Shape {
- let maxCornerRadius: Double
-
- func path(in rect: CGRect) -> Path {
- Path(
- roundedRect: rect,
- cornerRadius: min((rect.height / 2), maxCornerRadius),
- style: .circular
- )
- }
- }
-
+ @AppStorage(DEFAULT_CHAT_ITEM_ROUNDNESS) private var roundness = defaultChatItemRoundness
+ @AppStorage(DEFAULT_CHAT_ITEM_TAIL) private var tailEnabled = true
+ private let chatItem: (content: CIContent, chatDir: CIDirection)?
+ private let tailVisible: Bool
+
init() {
- clipShape = ClipShape(
- maxCornerRadius: 18
- )
+ self.chatItem = nil
+ self.tailVisible = false
+ }
+
+ init(_ ci: ChatItem, tailVisible: Bool) {
+ self.chatItem = (ci.content, ci.chatDir)
+ self.tailVisible = tailVisible
}
- init(_ chatItem: ChatItem) {
- clipShape = ClipShape(
- maxCornerRadius: {
- switch chatItem.content {
- case
- .sndMsgContent,
+ private func shapeStyle() -> ChatItemShape.Style {
+ if let ci = chatItem {
+ switch ci.content {
+ case
+ .sndMsgContent,
.rcvMsgContent,
.rcvDecryptionError,
.rcvGroupInvitation,
.sndGroupInvitation,
- .sndDeleted,
+ .sndDeleted,
.rcvDeleted,
.rcvIntegrityError,
- .sndModerated,
- .rcvModerated,
+ .sndModerated,
+ .rcvModerated,
.rcvBlocked,
- .invalidJSON: 18
- default: 8
+ .invalidJSON:
+ let tail = if let mc = ci.content.msgContent, mc.isImageOrVideo && mc.text.isEmpty {
+ false
+ } else {
+ tailVisible
}
- }()
- )
+ return tailEnabled
+ ? .bubble(
+ padding: ci.chatDir.sent ? .trailing : .leading,
+ tailVisible: tail
+ )
+ : .roundRect(radius: msgRectMaxRadius)
+ default: return .roundRect(radius: 8)
+ }
+ } else {
+ return.roundRect(radius: msgRectMaxRadius)
+ }
}
-
- private let clipShape: ClipShape
-
+
func body(content: Content) -> some View {
+ let clipShape = ChatItemShape(
+ roundness: roundness,
+ style: shapeStyle()
+ )
content
.contentShape(.dragPreview, clipShape)
.contentShape(.contextMenuPreview, clipShape)
@@ -65,4 +75,106 @@ struct ChatItemClipped: ViewModifier {
}
}
+struct ChatTailPadding: ViewModifier {
+ func body(content: Content) -> some View {
+ content.padding(.horizontal, -msgTailWidth)
+ }
+}
+private let msgRectMaxRadius: Double = 18
+private let msgBubbleMaxRadius: Double = msgRectMaxRadius * 1.2
+private let msgTailWidth: Double = 9
+private let msgTailMinHeight: Double = msgTailWidth * 1.254 // ~56deg
+private let msgTailMaxHeight: Double = msgTailWidth * 1.732 // 60deg
+
+struct ChatItemShape: Shape {
+ fileprivate enum Style {
+ case bubble(padding: HorizontalEdge, tailVisible: Bool)
+ case roundRect(radius: Double)
+ }
+
+ fileprivate let roundness: Double
+ fileprivate let style: Style
+
+ func path(in rect: CGRect) -> Path {
+ switch style {
+ case let .bubble(padding, tailVisible):
+ let w = rect.width
+ let h = rect.height
+ let rxMax = min(msgBubbleMaxRadius, w / 2)
+ let ryMax = min(msgBubbleMaxRadius, h / 2)
+ let rx = roundness * rxMax
+ let ry = roundness * ryMax
+ let tailHeight = min(msgTailMinHeight + roundness * (msgTailMaxHeight - msgTailMinHeight), h / 2)
+ var path = Path()
+ // top side
+ path.move(to: CGPoint(x: rx, y: 0))
+ path.addLine(to: CGPoint(x: w - rx, y: 0))
+ if roundness > 0 {
+ // top-right corner
+ path.addQuadCurve(to: CGPoint(x: w, y: ry), control: CGPoint(x: w, y: 0))
+ }
+ if rect.height > 2 * ry {
+ // right side
+ path.addLine(to: CGPoint(x: w, y: h - ry))
+ }
+ if roundness > 0 {
+ // bottom-right corner
+ path.addQuadCurve(to: CGPoint(x: w - rx, y: h), control: CGPoint(x: w, y: h))
+ }
+ // bottom side
+ if tailVisible {
+ path.addLine(to: CGPoint(x: -msgTailWidth, y: h))
+ if roundness > 0 {
+ // bottom-left tail
+ // distance of control point from touch point, calculated via ratios
+ let d = tailHeight - msgTailWidth * msgTailWidth / tailHeight
+ // tail control point
+ let tc = CGPoint(x: 0, y: h - tailHeight + d * sqrt(roundness))
+ // bottom-left tail curve
+ path.addQuadCurve(to: CGPoint(x: 0, y: h - tailHeight), control: tc)
+ } else {
+ path.addLine(to: CGPoint(x: 0, y: h - tailHeight))
+ }
+ if rect.height > ry + tailHeight {
+ // left side
+ path.addLine(to: CGPoint(x: 0, y: ry))
+ }
+ } else {
+ path.addLine(to: CGPoint(x: rx, y: h))
+ path.addQuadCurve(to: CGPoint(x: 0, y: h - ry), control: CGPoint(x: 0 , y: h))
+ if rect.height > 2 * ry {
+ // left side
+ path.addLine(to: CGPoint(x: 0, y: ry))
+ }
+ }
+ if roundness > 0 {
+ // top-left corner
+ path.addQuadCurve(to: CGPoint(x: rx, y: 0), control: CGPoint(x: 0, y: 0))
+ }
+ path.closeSubpath()
+ return switch padding {
+ case .leading: path
+ case .trailing: path
+ .scale(x: -1, y: 1, anchor: .center)
+ .path(in: rect)
+ }
+ case let .roundRect(radius):
+ return Path(roundedRect: rect, cornerRadius: radius * roundness)
+ }
+ }
+
+ var offset: Double? {
+ switch style {
+ case let .bubble(padding, isTailVisible):
+ if isTailVisible {
+ switch padding {
+ case .leading: -msgTailWidth
+ case .trailing: msgTailWidth
+ }
+ } else { 0 }
+ case .roundRect: 0
+ }
+ }
+
+}
diff --git a/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift b/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift
index 73a789f108..70c33329b1 100644
--- a/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift
+++ b/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift
@@ -33,6 +33,8 @@ struct AppearanceSettings: View {
}()
@State private var darkModeTheme: String = UserDefaults.standard.string(forKey: DEFAULT_SYSTEM_DARK_THEME) ?? DefaultTheme.DARK.themeName
@AppStorage(DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) private var profileImageCornerRadius = defaultProfileImageCorner
+ @AppStorage(DEFAULT_CHAT_ITEM_ROUNDNESS) private var chatItemRoundness = defaultChatItemRoundness
+ @AppStorage(DEFAULT_CHAT_ITEM_TAIL) private var chatItemTail = true
@AppStorage(GROUP_DEFAULT_ONE_HAND_UI, store: groupDefaults) private var oneHandUI = true
@AppStorage(DEFAULT_TOOLBAR_MATERIAL) private var toolbarMaterial = ToolbarMaterial.defaultMaterial
@@ -179,6 +181,14 @@ struct AppearanceSettings: View {
}
}
+ Section(header: Text("Message shape").foregroundColor(theme.colors.secondary)) {
+ HStack {
+ Text("Corner")
+ Slider(value: $chatItemRoundness, in: 0...1, step: 0.05)
+ }
+ Toggle("Tail", isOn: $chatItemTail)
+ }
+
Section(header: Text("Profile images").foregroundColor(theme.colors.secondary)) {
HStack(spacing: 16) {
if let img = m.currentUser?.image, img != "" {
@@ -358,20 +368,21 @@ struct ChatThemePreview: View {
let bob = ChatItem.getSample(2, CIDirection.directSnd, Date.now, NSLocalizedString("Good morning!", comment: "message preview"), quotedItem: CIQuote.getSample(alice.id, alice.meta.itemTs, alice.content.text, chatDir: alice.chatDir))
HStack {
ChatItemView(chat: Chat.sampleData, chatItem: alice, revealed: Binding.constant(false))
- .modifier(ChatItemClipped())
+ .modifier(ChatItemClipped(alice, tailVisible: true))
Spacer()
}
HStack {
Spacer()
ChatItemView(chat: Chat.sampleData, chatItem: bob, revealed: Binding.constant(false))
- .modifier(ChatItemClipped())
+ .modifier(ChatItemClipped(bob, tailVisible: true))
.frame(alignment: .trailing)
}
} else {
Rectangle().fill(.clear)
}
}
- .padding(10)
+ .padding(.vertical, 10)
+ .padding(.horizontal, 16)
.frame(maxWidth: .infinity)
if let wallpaperType, let wallpaperImage = wallpaperType.image, let backgroundColor, let tintColor {
diff --git a/apps/ios/Shared/Views/UserSettings/SettingsView.swift b/apps/ios/Shared/Views/UserSettings/SettingsView.swift
index a4908f628f..d9c83803dd 100644
--- a/apps/ios/Shared/Views/UserSettings/SettingsView.swift
+++ b/apps/ios/Shared/Views/UserSettings/SettingsView.swift
@@ -47,6 +47,8 @@ let DEFAULT_ACCENT_COLOR_GREEN = "accentColorGreen" // deprecated, only used for
let DEFAULT_ACCENT_COLOR_BLUE = "accentColorBlue" // deprecated, only used for migration
let DEFAULT_USER_INTERFACE_STYLE = "userInterfaceStyle" // deprecated, only used for migration
let DEFAULT_PROFILE_IMAGE_CORNER_RADIUS = "profileImageCornerRadius"
+let DEFAULT_CHAT_ITEM_ROUNDNESS = "chatItemRoundness"
+let DEFAULT_CHAT_ITEM_TAIL = "chatItemTail"
let DEFAULT_ONE_HAND_UI_CARD_SHOWN = "oneHandUICardShown"
let DEFAULT_TOOLBAR_MATERIAL = "toolbarMaterial"
let DEFAULT_CONNECT_VIA_LINK_TAB = "connectViaLinkTab"
@@ -75,6 +77,8 @@ let DEFAULT_THEME_OVERRIDES = "themeOverrides"
let ANDROID_DEFAULT_CALL_ON_LOCK_SCREEN = "androidCallOnLockScreen"
+let defaultChatItemRoundness: Double = 0.75
+
let appDefaults: [String: Any] = [
DEFAULT_SHOW_LA_NOTICE: false,
DEFAULT_LA_NOTICE_SHOWN: false,
@@ -98,6 +102,8 @@ let appDefaults: [String: Any] = [
DEFAULT_DEVELOPER_TOOLS: false,
DEFAULT_ENCRYPTION_STARTED: false,
DEFAULT_PROFILE_IMAGE_CORNER_RADIUS: defaultProfileImageCorner,
+ DEFAULT_CHAT_ITEM_ROUNDNESS: defaultChatItemRoundness,
+ DEFAULT_CHAT_ITEM_TAIL: true,
DEFAULT_ONE_HAND_UI_CARD_SHOWN: false,
DEFAULT_TOOLBAR_MATERIAL: ToolbarMaterial.defaultMaterial,
DEFAULT_CONNECT_VIA_LINK_TAB: ConnectViaLinkTab.scan.rawValue,
diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff
index 419f0ae864..89e628e2b6 100644
--- a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff
+++ b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff
@@ -137,6 +137,10 @@
%@ иска да се свърже!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ и %lld членове
@@ -1685,6 +1689,10 @@ This is your own one-time link!
Версия на ядрото: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?Поправи име на %@?
@@ -2645,6 +2653,10 @@ This is your own one-time link!
Грешка при промяна на адресаNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleГрешка при промяна на ролята
@@ -2655,6 +2667,10 @@ This is your own one-time link!
Грешка при промяна на настройкатаNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.No comment provided by engineer.
@@ -2870,6 +2886,10 @@ This is your own one-time link!
Грешка при спиране на чатаNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Грешка при смяна на профил!
@@ -4069,6 +4089,10 @@ This is your link for group %@!
Message serversNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.Източникът на съобщението остава скрит.
@@ -5562,6 +5586,10 @@ Enable in *Network & servers* settings.
Избериchat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldNo comment provided by engineer.
@@ -5911,6 +5939,10 @@ Enable in *Network & servers* settings.
Сподели линкNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkСподели този еднократен линк за връзка
@@ -6235,6 +6267,10 @@ Enable in *Network & servers* settings.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureНаправи снимка
@@ -7480,6 +7516,10 @@ Repeat connection request?
Вашите чат профилиNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).Вашият контакт изпрати файл, който е по-голям от поддържания в момента максимален размер (%@).
diff --git a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff
index a02203e630..65bc83d096 100644
--- a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff
+++ b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff
@@ -135,6 +135,10 @@
%@ se chce připojit!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld membersNo comment provided by engineer.
@@ -1623,6 +1627,10 @@ This is your own one-time link!
Verze jádra: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?No comment provided by engineer.
@@ -2552,6 +2560,10 @@ This is your own one-time link!
Chuba změny adresyNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleChyba při změně role
@@ -2562,6 +2574,10 @@ This is your own one-time link!
Chyba změny nastaveníNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.No comment provided by engineer.
@@ -2772,6 +2788,10 @@ This is your own one-time link!
Chyba při zastavení chatuNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Chyba při přepínání profilu!
@@ -3928,6 +3948,10 @@ This is your link for group %@!
Message serversNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.No comment provided by engineer.
@@ -5363,6 +5387,10 @@ Enable in *Network & servers* settings.
Vybratchat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldNo comment provided by engineer.
@@ -5708,6 +5736,10 @@ Enable in *Network & servers* settings.
Sdílet odkazNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkNo comment provided by engineer.
@@ -6024,6 +6056,10 @@ Enable in *Network & servers* settings.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureVyfotit
@@ -7209,6 +7245,10 @@ Repeat connection request?
Vaše chat profilyNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).Kontakt odeslal soubor, který je větší než aktuálně podporovaná maximální velikost (%@).
diff --git a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff
index 29adfbabf0..357b1c3c47 100644
--- a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff
+++ b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff
@@ -137,6 +137,10 @@
%@ will sich mit Ihnen verbinden!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ und %lld Mitglieder
@@ -1740,6 +1744,10 @@ Das ist Ihr eigener Einmal-Link!
Core Version: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?Richtiger Name für %@?
@@ -2724,6 +2732,10 @@ Das ist Ihr eigener Einmal-Link!
Fehler beim Wechseln der EmpfängeradresseNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleFehler beim Ändern der Rolle
@@ -2734,6 +2746,10 @@ Das ist Ihr eigener Einmal-Link!
Fehler beim Ändern der EinstellungNo comment provided by engineer.
+
+ Error changing to incognito!
+ 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.
@@ -2954,6 +2970,10 @@ Das ist Ihr eigener Einmal-Link!
Fehler beim Beenden des ChatsNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Fehler beim Umschalten des Profils!
@@ -4184,6 +4204,10 @@ Das ist Ihr Link für die Gruppe %@!
Nachrichten-ServerNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.Die Nachrichtenquelle bleibt privat.
@@ -5729,6 +5753,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.
Auswählenchat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lld%lld ausgewählt
@@ -6099,6 +6127,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.
Link teilenNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkTeilen Sie diesen Einmal-Einladungslink
@@ -6439,6 +6471,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureMachen Sie ein Foto
@@ -7719,6 +7755,10 @@ Verbindungsanfrage wiederholen?
Ihre Chat-ProfileNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ 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 (%@).
diff --git a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff
index c217793f03..006996c8d9 100644
--- a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff
+++ b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff
@@ -137,6 +137,11 @@
%@ wants to connect!notification title
+
+ %1$@, %2$@
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ and %lld members
@@ -1740,6 +1745,11 @@ This is your own one-time link!
Core version: v%@No comment provided by engineer.
+
+ Corner
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?Correct name to %@?
@@ -2724,6 +2734,11 @@ This is your own one-time link!
Error changing addressNo comment provided by engineer.
+
+ Error changing connection profile
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleError changing role
@@ -2734,6 +2749,11 @@ This is your own one-time link!
Error changing settingNo comment provided by engineer.
+
+ Error changing to incognito!
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.Error connecting to forwarding server %@. Please try later.
@@ -2954,6 +2974,11 @@ This is your own one-time link!
Error stopping chatNo comment provided by engineer.
+
+ Error switching profile
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Error switching profile!
@@ -4184,6 +4209,11 @@ This is your link for group %@!
Message serversNo comment provided by engineer.
+
+ Message shape
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.Message source remains private.
@@ -5729,6 +5759,11 @@ Enable in *Network & servers* settings.
Selectchat item action
+
+ Select chat profile
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldSelected %lld
@@ -6099,6 +6134,11 @@ Enable in *Network & servers* settings.
Share linkNo comment provided by engineer.
+
+ Share profile
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkShare this 1-time invite link
@@ -6439,6 +6479,11 @@ Enable in *Network & servers* settings.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ Tail
+ No comment provided by engineer.
+ Take pictureTake picture
@@ -7719,6 +7764,11 @@ Repeat connection request?
Your chat profilesNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).Your contact sent a file that is larger than currently supported maximum size (%@).
diff --git a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff
index 6e5ec0e85a..529b185e25 100644
--- a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff
+++ b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff
@@ -137,6 +137,10 @@
¡ %@ quiere contactar!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ y %lld miembro(s) más
@@ -1740,6 +1744,10 @@ This is your own one-time link!
Versión Core: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?¿Corregir el nombre a %@?
@@ -2724,6 +2732,10 @@ This is your own one-time link!
Error al cambiar servidorNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleError al cambiar rol
@@ -2734,6 +2746,10 @@ This is your own one-time link!
Error cambiando configuraciónNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.Error al conectar con el servidor de reenvío %@. Por favor, inténtalo más tarde.
@@ -2954,6 +2970,10 @@ This is your own one-time link!
Error al parar SimpleXNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!¡Error al cambiar perfil!
@@ -4184,6 +4204,10 @@ This is your link for group %@!
Servidores de mensajesNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.El autor del mensaje se mantiene privado.
@@ -5729,6 +5753,10 @@ Actívalo en ajustes de *Servidores y Redes*.
Seleccionarchat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldSeleccionados %lld
@@ -6099,6 +6127,10 @@ Actívalo en ajustes de *Servidores y Redes*.
Compartir enlaceNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkComparte este enlace de un solo uso
@@ -6439,6 +6471,10 @@ Actívalo en ajustes de *Servidores y Redes*.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureTomar foto
@@ -7719,6 +7755,10 @@ Repeat connection request?
Mis perfilesNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).El contacto ha enviado un archivo mayor al máximo admitido (%@).
diff --git a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff
index 211e512a1e..fc31e4f2df 100644
--- a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff
+++ b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff
@@ -133,6 +133,10 @@
%@ haluaa muodostaa yhteyden!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld membersNo comment provided by engineer.
@@ -1616,6 +1620,10 @@ This is your own one-time link!
Ydinversio: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?No comment provided by engineer.
@@ -2544,6 +2552,10 @@ This is your own one-time link!
Virhe osoitteenvaihdossaNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleVirhe roolin vaihdossa
@@ -2554,6 +2566,10 @@ This is your own one-time link!
Virhe asetuksen muuttamisessaNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.No comment provided by engineer.
@@ -2762,6 +2778,10 @@ This is your own one-time link!
Virhe keskustelun lopettamisessaNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Virhe profiilin vaihdossa!
@@ -3918,6 +3938,10 @@ This is your link for group %@!
Message serversNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.No comment provided by engineer.
@@ -5351,6 +5375,10 @@ Enable in *Network & servers* settings.
Valitsechat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldNo comment provided by engineer.
@@ -5695,6 +5723,10 @@ Enable in *Network & servers* settings.
Jaa linkkiNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkNo comment provided by engineer.
@@ -6010,6 +6042,10 @@ Enable in *Network & servers* settings.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureOta kuva
@@ -7194,6 +7230,10 @@ Repeat connection request?
KeskusteluprofiilisiNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).Yhteyshenkilösi lähetti tiedoston, joka on suurempi kuin tällä hetkellä tuettu enimmäiskoko (%@).
diff --git a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff
index c05098980e..6970039315 100644
--- a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff
+++ b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff
@@ -137,6 +137,10 @@
%@ veut se connecter !notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ et %lld membres
@@ -1740,6 +1744,10 @@ Il s'agit de votre propre lien unique !
Version du cœur : v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?Corriger le nom pour %@ ?
@@ -2724,6 +2732,10 @@ Il s'agit de votre propre lien unique !
Erreur de changement d'adresseNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleErreur lors du changement de rôle
@@ -2734,6 +2746,10 @@ Il s'agit de votre propre lien unique !
Erreur de changement de paramètreNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.Erreur de connexion au serveur de redirection %@. Veuillez réessayer plus tard.
@@ -2954,6 +2970,10 @@ Il s'agit de votre propre lien unique !
Erreur lors de l'arrêt du chatNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Erreur lors du changement de profil !
@@ -4184,6 +4204,10 @@ Voici votre lien pour le groupe %@ !
Serveurs de messagesNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.La source du message reste privée.
@@ -5729,6 +5753,10 @@ Activez-le dans les paramètres *Réseau et serveurs*.
Choisirchat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lld%lld sélectionné(s)
@@ -6099,6 +6127,10 @@ Activez-le dans les paramètres *Réseau et serveurs*.
Partager le lienNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkPartager ce lien d'invitation unique
@@ -6439,6 +6471,10 @@ Activez-le dans les paramètres *Réseau et serveurs*.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take picturePrendre une photo
@@ -7719,6 +7755,10 @@ Répéter la demande de connexion ?
Vos profils de chatNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).Votre contact a envoyé un fichier plus grand que la taille maximale supportée actuellement(%@).
diff --git a/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff b/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff
index f7328eed91..de95de3421 100644
--- a/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff
+++ b/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff
@@ -137,6 +137,10 @@
%@ kapcsolódni szeretne!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ és további %lld tag
@@ -1740,6 +1744,10 @@ Ez az egyszer használatos hivatkozása!
Alapverziószám: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?Név javítása erre: %@?
@@ -2724,6 +2732,10 @@ Ez az egyszer használatos hivatkozása!
Hiba a cím megváltoztatásakorNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleHiba a szerepkör megváltoztatásakor
@@ -2734,6 +2746,10 @@ Ez az egyszer használatos hivatkozása!
Hiba a beállítás megváltoztatásakorNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.Hiba a(z) %@ továbbító kiszolgálóhoz való kapcsolódáskor. Próbálja meg később.
@@ -2954,6 +2970,10 @@ Ez az egyszer használatos hivatkozása!
Hiba a csevegés megállításakorNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Hiba a profil váltásakor!
@@ -4184,6 +4204,10 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!
ÜzenetkiszolgálókNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.Az üzenet forrása titokban marad.
@@ -5729,6 +5753,10 @@ Engedélyezze a Beállítások / Hálózat és kiszolgálók menüben.
Választáschat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lld%lld kiválasztva
@@ -6099,6 +6127,10 @@ Engedélyezze a Beállítások / Hálózat és kiszolgálók menüben.
Hivatkozás megosztásaNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkEgyszer használatos meghívó hivatkozás megosztása
@@ -6439,6 +6471,10 @@ Engedélyezze a Beállítások / Hálózat és kiszolgálók menüben.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureKép készítése
@@ -7719,6 +7755,10 @@ Kapcsolódási kérés megismétlése?
Csevegési profilokNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).Ismerőse olyan fájlt küldött, amely meghaladja a jelenleg támogatott maximális méretet (%@).
diff --git a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff
index 72eb3561e3..700d181aab 100644
--- a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff
+++ b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff
@@ -137,6 +137,10 @@
%@ si vuole connettere!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ e %lld membri
@@ -1740,6 +1744,10 @@ Questo è il tuo link una tantum!
Versione core: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?Correggere il nome a %@?
@@ -2724,6 +2732,10 @@ Questo è il tuo link una tantum!
Errore nella modifica dell'indirizzoNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleErrore nel cambio di ruolo
@@ -2734,6 +2746,10 @@ Questo è il tuo link una tantum!
Errore nella modifica dell'impostazioneNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.Errore di connessione al server di inoltro %@. Riprova più tardi.
@@ -2954,6 +2970,10 @@ Questo è il tuo link una tantum!
Errore nell'interruzione della chatNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Errore nel cambio di profilo!
@@ -4184,6 +4204,10 @@ Questo è il tuo link per il gruppo %@!
Server dei messaggiNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.La fonte del messaggio resta privata.
@@ -5729,6 +5753,10 @@ Attivalo nelle impostazioni *Rete e server*.
Selezionachat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lld%lld selezionato
@@ -6099,6 +6127,10 @@ Attivalo nelle impostazioni *Rete e server*.
Condividi linkNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkCondividi questo link di invito una tantum
@@ -6439,6 +6471,10 @@ Attivalo nelle impostazioni *Rete e server*.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureScatta foto
@@ -7719,6 +7755,10 @@ Ripetere la richiesta di connessione?
I tuoi profili di chatNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ 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 (%@).
diff --git a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff
index a545f3ba05..0b9b431c8b 100644
--- a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff
+++ b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff
@@ -137,6 +137,10 @@
%@ が接続を希望しています!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@や%@など%lld人のメンバー
@@ -1640,6 +1644,10 @@ This is your own one-time link!
コアのバージョン: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?No comment provided by engineer.
@@ -2569,6 +2577,10 @@ This is your own one-time link!
アドレス変更にエラー発生No comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing role役割変更にエラー発生
@@ -2579,6 +2591,10 @@ This is your own one-time link!
設定変更にエラー発生No comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.No comment provided by engineer.
@@ -2787,6 +2803,10 @@ This is your own one-time link!
チャット停止にエラー発生No comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!プロフィール切り替えにエラー発生!
@@ -3942,6 +3962,10 @@ This is your link for group %@!
Message serversNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.No comment provided by engineer.
@@ -5376,6 +5400,10 @@ Enable in *Network & servers* settings.
選択chat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldNo comment provided by engineer.
@@ -5713,6 +5741,10 @@ Enable in *Network & servers* settings.
リンクを送るNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkNo comment provided by engineer.
@@ -6029,6 +6061,10 @@ Enable in *Network & servers* settings.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take picture写真を撮影
@@ -7212,6 +7248,10 @@ Repeat connection request?
あなたのチャットプロフィールNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).連絡先が現在サポートされている最大サイズ (%@) より大きいファイルを送信しました。
diff --git a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff
index 15a8c01a64..cd52825882 100644
--- a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff
+++ b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff
@@ -137,6 +137,10 @@
%@ wil verbinding maken!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ en %lld leden
@@ -1740,6 +1744,10 @@ Dit is uw eigen eenmalige link!
Core versie: v% @No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?Juiste naam voor %@?
@@ -2724,6 +2732,10 @@ Dit is uw eigen eenmalige link!
Fout bij wijzigen van adresNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleFout bij wisselen van rol
@@ -2734,6 +2746,10 @@ Dit is uw eigen eenmalige link!
Fout bij wijzigen van instellingNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.Fout bij het verbinden met doorstuurserver %@. Probeer het later opnieuw.
@@ -2954,6 +2970,10 @@ Dit is uw eigen eenmalige link!
Fout bij het stoppen van de chatNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Fout bij wisselen van profiel!
@@ -4184,6 +4204,10 @@ Dit is jouw link voor groep %@!
BerichtserversNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.Berichtbron blijft privé.
@@ -5729,6 +5753,10 @@ Schakel dit in in *Netwerk en servers*-instellingen.
Selecteerchat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lld%lld geselecteerd
@@ -6099,6 +6127,10 @@ Schakel dit in in *Netwerk en servers*-instellingen.
Deel linkNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkDeel deze eenmalige uitnodigingslink
@@ -6439,6 +6471,10 @@ Schakel dit in in *Netwerk en servers*-instellingen.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureFoto nemen
@@ -7719,6 +7755,10 @@ Verbindingsverzoek herhalen?
Uw chat profielenNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ 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 (%@).
diff --git a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff
index 525d30daa6..a474f30768 100644
--- a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff
+++ b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff
@@ -137,6 +137,10 @@
%@ chce się połączyć!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ i %lld członków
@@ -1740,6 +1744,10 @@ To jest twój jednorazowy link!
Wersja rdzenia: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?Poprawić imię na %@?
@@ -2724,6 +2732,10 @@ To jest twój jednorazowy link!
Błąd zmiany adresuNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleBłąd zmiany roli
@@ -2734,6 +2746,10 @@ To jest twój jednorazowy link!
Błąd zmiany ustawieniaNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.Błąd połączenia z serwerem przekierowania %@. Spróbuj ponownie później.
@@ -2954,6 +2970,10 @@ To jest twój jednorazowy link!
Błąd zatrzymania czatuNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Błąd przełączania profilu!
@@ -4184,6 +4204,10 @@ To jest twój link do grupy %@!
Serwery wiadomościNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.Źródło wiadomości pozostaje prywatne.
@@ -5729,6 +5753,10 @@ Włącz w ustawianiach *Sieć i serwery* .
Wybierzchat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldZaznaczono %lld
@@ -6099,6 +6127,10 @@ Włącz w ustawianiach *Sieć i serwery* .
Udostępnij linkNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkUdostępnij ten jednorazowy link
@@ -6439,6 +6471,10 @@ Włącz w ustawianiach *Sieć i serwery* .
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureZrób zdjęcie
@@ -7719,6 +7755,10 @@ Powtórzyć prośbę połączenia?
Twoje profile czatuNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).Twój kontakt wysłał plik, który jest większy niż obecnie obsługiwany maksymalny rozmiar (%@).
diff --git a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff
index 969a7d68e0..957e599e85 100644
--- a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff
+++ b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff
@@ -137,6 +137,10 @@
%@ хочет соединиться!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ и %lld членов группы
@@ -1740,6 +1744,10 @@ This is your own one-time link!
Версия ядра: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?Исправить имя на %@?
@@ -2724,6 +2732,10 @@ This is your own one-time link!
Ошибка при изменении адресаNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleОшибка при изменении роли
@@ -2734,6 +2746,10 @@ This is your own one-time link!
Ошибка при изменении настройкиNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.Ошибка подключения к пересылающему серверу %@. Попробуйте позже.
@@ -2954,6 +2970,10 @@ This is your own one-time link!
Ошибка при остановке чатаNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Ошибка выбора профиля!
@@ -4184,6 +4204,10 @@ This is your link for group %@!
Серверы сообщенийNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.Источник сообщения остаётся конфиденциальным.
@@ -5729,6 +5753,10 @@ Enable in *Network & servers* settings.
Выбратьchat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldВыбрано %lld
@@ -6099,6 +6127,10 @@ Enable in *Network & servers* settings.
Поделиться ссылкойNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkПоделиться одноразовой ссылкой-приглашением
@@ -6439,6 +6471,10 @@ Enable in *Network & servers* settings.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureСделать фото
@@ -7719,6 +7755,10 @@ Repeat connection request?
Ваши профили чатаNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).Ваш контакт отправил файл, размер которого превышает максимальный размер (%@).
diff --git a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff
index 646a94a337..366f67d0cd 100644
--- a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff
+++ b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff
@@ -129,6 +129,10 @@
%@ อยากเชื่อมต่อ!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld membersNo comment provided by engineer.
@@ -1606,6 +1610,10 @@ This is your own one-time link!
รุ่นหลัก: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?No comment provided by engineer.
@@ -2530,6 +2538,10 @@ This is your own one-time link!
เกิดข้อผิดพลาดในการเปลี่ยนที่อยู่No comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleเกิดข้อผิดพลาดในการเปลี่ยนบทบาท
@@ -2540,6 +2552,10 @@ This is your own one-time link!
เกิดข้อผิดพลาดในการเปลี่ยนการตั้งค่าNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.No comment provided by engineer.
@@ -2747,6 +2763,10 @@ This is your own one-time link!
เกิดข้อผิดพลาดในการหยุดแชทNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!เกิดข้อผิดพลาดในการเปลี่ยนโปรไฟล์!
@@ -3901,6 +3921,10 @@ This is your link for group %@!
Message serversNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.No comment provided by engineer.
@@ -5328,6 +5352,10 @@ Enable in *Network & servers* settings.
เลือกchat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldNo comment provided by engineer.
@@ -5670,6 +5698,10 @@ Enable in *Network & servers* settings.
แชร์ลิงก์No comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkNo comment provided by engineer.
@@ -5983,6 +6015,10 @@ Enable in *Network & servers* settings.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureถ่ายภาพ
@@ -7163,6 +7199,10 @@ Repeat connection request?
โปรไฟล์แชทของคุณNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).ผู้ติดต่อของคุณส่งไฟล์ที่ใหญ่กว่าขนาดสูงสุดที่รองรับในปัจจุบัน (%@)
diff --git a/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff b/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff
index 054f65110f..13fa3c8a84 100644
--- a/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff
+++ b/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff
@@ -137,6 +137,10 @@
%@ bağlanmak istiyor!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ ve %lld üyeleri
@@ -1689,6 +1693,10 @@ Bu senin kendi tek kullanımlık bağlantın!
Çekirdek sürümü: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?İsim %@ olarak düzeltilsin mi?
@@ -2653,6 +2661,10 @@ Bu senin kendi tek kullanımlık bağlantın!
Adres değiştirilirken hata oluştuNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleRol değiştirilirken hata oluştu
@@ -2663,6 +2675,10 @@ Bu senin kendi tek kullanımlık bağlantın!
Ayar değiştirilirken hata oluştuNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.No comment provided by engineer.
@@ -2878,6 +2894,10 @@ Bu senin kendi tek kullanımlık bağlantın!
Sohbet durdurulurken hata oluştuNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Profil değiştirilirken hata oluştu!
@@ -4084,6 +4104,10 @@ Bu senin grup için bağlantın %@!
Message serversNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.Mesaj kaynağı gizli kalır.
@@ -5585,6 +5609,10 @@ Enable in *Network & servers* settings.
Seçchat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldNo comment provided by engineer.
@@ -5938,6 +5966,10 @@ Enable in *Network & servers* settings.
Bağlantıyı paylaşNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkBu tek kullanımlık bağlantı davetini paylaş
@@ -6264,6 +6296,10 @@ Enable in *Network & servers* settings.
TCP_TVLDEKALNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureFotoğraf çek
@@ -7517,6 +7553,10 @@ Bağlantı isteği tekrarlansın mı?
Sohbet profillerinNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).Kişiniz şu anda desteklenen maksimum boyuttan (%@) daha büyük bir dosya gönderdi.
diff --git a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff
index 7bcb30c1db..69685620ba 100644
--- a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff
+++ b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff
@@ -137,6 +137,10 @@
%@ хоче підключитися!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ та %lld учасників
@@ -1740,6 +1744,10 @@ This is your own one-time link!
Основна версія: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?Виправити ім'я на %@?
@@ -2724,6 +2732,10 @@ This is your own one-time link!
Помилка зміни адресиNo comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing roleПомилка зміни ролі
@@ -2734,6 +2746,10 @@ This is your own one-time link!
Помилка зміни налаштуванняNo comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.Помилка підключення до сервера переадресації %@. Спробуйте пізніше.
@@ -2954,6 +2970,10 @@ This is your own one-time link!
Помилка зупинки чатуNo comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!Помилка перемикання профілю!
@@ -4184,6 +4204,10 @@ This is your link for group %@!
Сервери повідомленьNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.Джерело повідомлення залишається приватним.
@@ -5729,6 +5753,10 @@ Enable in *Network & servers* settings.
Виберітьchat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldВибрано %lld
@@ -6099,6 +6127,10 @@ Enable in *Network & servers* settings.
Поділіться посиланнямNo comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite linkПоділіться цим одноразовим посиланням-запрошенням
@@ -6439,6 +6471,10 @@ Enable in *Network & servers* settings.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take pictureСфотографуйте
@@ -7719,6 +7755,10 @@ Repeat connection request?
Ваші профілі чатуNo comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).Ваш контакт надіслав файл, розмір якого перевищує підтримуваний на цей момент максимальний розмір (%@).
diff --git a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff
index 8c3641549d..b524846ffd 100644
--- a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff
+++ b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff
@@ -135,6 +135,10 @@
%@ 要连接!notification title
+
+ %1$@, %2$@
+ format for date separator in chat
+ %@, %@ and %lld members%@, %@ 和 %lld 成员
@@ -1665,6 +1669,10 @@ This is your own one-time link!
核心版本: v%@No comment provided by engineer.
+
+ Corner
+ No comment provided by engineer.
+ Correct name to %@?No comment provided by engineer.
@@ -2618,6 +2626,10 @@ This is your own one-time link!
更改地址错误No comment provided by engineer.
+
+ Error changing connection profile
+ No comment provided by engineer.
+ Error changing role更改角色错误
@@ -2628,6 +2640,10 @@ This is your own one-time link!
更改设置错误No comment provided by engineer.
+
+ Error changing to incognito!
+ No comment provided by engineer.
+ Error connecting to forwarding server %@. Please try later.No comment provided by engineer.
@@ -2841,6 +2857,10 @@ This is your own one-time link!
停止聊天错误No comment provided by engineer.
+
+ Error switching profile
+ No comment provided by engineer.
+ Error switching profile!切换资料错误!
@@ -4033,6 +4053,10 @@ This is your link for group %@!
Message serversNo comment provided by engineer.
+
+ Message shape
+ No comment provided by engineer.
+ Message source remains private.消息来源保持私密。
@@ -5512,6 +5536,10 @@ Enable in *Network & servers* settings.
选择chat item action
+
+ Select chat profile
+ No comment provided by engineer.
+ Selected %lldNo comment provided by engineer.
@@ -5861,6 +5889,10 @@ Enable in *Network & servers* settings.
分享链接No comment provided by engineer.
+
+ Share profile
+ No comment provided by engineer.
+ Share this 1-time invite link分享此一次性邀请链接
@@ -6185,6 +6217,10 @@ Enable in *Network & servers* settings.
TCP_KEEPINTVLNo comment provided by engineer.
+
+ Tail
+ No comment provided by engineer.
+ Take picture拍照
@@ -7417,6 +7453,10 @@ Repeat connection request?
您的聊天资料No comment provided by engineer.
+
+ Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.
+ No comment provided by engineer.
+ Your contact sent a file that is larger than currently supported maximum size (%@).您的联系人发送的文件大于当前支持的最大大小 (%@)。
diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift
index d51e5a7cc3..07340bb963 100644
--- a/apps/ios/SimpleXChat/ChatTypes.swift
+++ b/apps/ios/SimpleXChat/ChatTypes.swift
@@ -2765,26 +2765,8 @@ public struct CITimed: Decodable, Hashable {
public var deleteAt: Date?
}
-let msgTimeFormat = Date.FormatStyle.dateTime.hour().minute()
-let msgDateFormat = Date.FormatStyle.dateTime.day(.twoDigits).month(.twoDigits)
-
public func formatTimestampText(_ date: Date) -> Text {
- Text(verbatim: date.formatted(recent(date) ? msgTimeFormat : msgDateFormat))
-}
-
-private func recent(_ date: Date) -> Bool {
- let now = Date()
- let calendar = Calendar.current
-
- guard let previousDay = calendar.date(byAdding: DateComponents(day: -1), to: now),
- let previousDay18 = calendar.date(bySettingHour: 18, minute: 0, second: 0, of: previousDay),
- let currentDay00 = calendar.date(bySettingHour: 0, minute: 0, second: 0, of: now),
- let currentDay12 = calendar.date(bySettingHour: 12, minute: 0, second: 0, of: now) else {
- return false
- }
-
- let isSameDay = calendar.isDate(date, inSameDayAs: now)
- return isSameDay || (now < currentDay12 && date >= previousDay18 && date < currentDay00)
+ Text(verbatim: date.formatted(date: .omitted, time: .shortened))
}
public enum CIStatus: Decodable, Hashable {
diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt
index e92b3d714a..de13f05dbd 100644
--- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt
+++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt
@@ -784,7 +784,8 @@ object ChatModel {
data class ShowingInvitation(
val connId: String,
val connReq: String,
- val connChatUsed: Boolean
+ val connChatUsed: Boolean,
+ val conn: PendingContactConnection
)
enum class ChatType(val type: String) {
diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt
index 060e75a9a1..c621b9eacf 100644
--- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt
+++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt
@@ -1132,9 +1132,30 @@ object ChatController {
suspend fun apiSetConnectionIncognito(rh: Long?, connId: Long, incognito: Boolean): PendingContactConnection? {
val r = sendCmd(rh, CC.ApiSetConnectionIncognito(connId, incognito))
- if (r is CR.ConnectionIncognitoUpdated) return r.toConnection
- Log.e(TAG, "apiSetConnectionIncognito bad response: ${r.responseType} ${r.details}")
- return null
+
+ return when (r) {
+ is CR.ConnectionIncognitoUpdated -> r.toConnection
+ else -> {
+ if (!(networkErrorAlert(r))) {
+ apiErrorAlert("apiSetConnectionIncognito", generalGetString(MR.strings.error_sending_message), r)
+ }
+ null
+ }
+ }
+ }
+
+ suspend fun apiChangeConnectionUser(rh: Long?, connId: Long, userId: Long): PendingContactConnection? {
+ val r = sendCmd(rh, CC.ApiChangeConnectionUser(connId, userId))
+
+ return when (r) {
+ is CR.ConnectionUserChanged -> r.toConnection
+ else -> {
+ if (!(networkErrorAlert(r))) {
+ apiErrorAlert("apiChangeConnectionUser", generalGetString(MR.strings.error_sending_message), r)
+ }
+ null
+ }
+ }
}
suspend fun apiConnectPlan(rh: Long?, connReq: String): ConnectionPlan? {
@@ -2916,6 +2937,7 @@ sealed class CC {
class APIVerifyGroupMember(val groupId: Long, val groupMemberId: Long, val connectionCode: String?): CC()
class APIAddContact(val userId: Long, val incognito: Boolean): CC()
class ApiSetConnectionIncognito(val connId: Long, val incognito: Boolean): CC()
+ class ApiChangeConnectionUser(val connId: Long, val userId: Long): CC()
class APIConnectPlan(val userId: Long, val connReq: String): CC()
class APIConnect(val userId: Long, val incognito: Boolean, val connReq: String): CC()
class ApiConnectContactViaAddress(val userId: Long, val incognito: Boolean, val contactId: Long): CC()
@@ -3071,6 +3093,7 @@ sealed class CC {
is APIVerifyGroupMember -> "/_verify code #$groupId $groupMemberId" + if (connectionCode != null) " $connectionCode" else ""
is APIAddContact -> "/_connect $userId incognito=${onOff(incognito)}"
is ApiSetConnectionIncognito -> "/_set incognito :$connId ${onOff(incognito)}"
+ is ApiChangeConnectionUser -> "/_set conn user :$connId $userId"
is APIConnectPlan -> "/_connect plan $userId $connReq"
is APIConnect -> "/_connect $userId incognito=${onOff(incognito)} $connReq"
is ApiConnectContactViaAddress -> "/_connect contact $userId incognito=${onOff(incognito)} $contactId"
@@ -3213,6 +3236,7 @@ sealed class CC {
is APIVerifyGroupMember -> "apiVerifyGroupMember"
is APIAddContact -> "apiAddContact"
is ApiSetConnectionIncognito -> "apiSetConnectionIncognito"
+ is ApiChangeConnectionUser -> "apiChangeConnectionUser"
is APIConnectPlan -> "apiConnectPlan"
is APIConnect -> "apiConnect"
is ApiConnectContactViaAddress -> "apiConnectContactViaAddress"
@@ -4757,6 +4781,7 @@ sealed class CR {
@Serializable @SerialName("connectionVerified") class ConnectionVerified(val user: UserRef, val verified: Boolean, val expectedCode: String): CR()
@Serializable @SerialName("invitation") class Invitation(val user: UserRef, val connReqInvitation: String, val connection: PendingContactConnection): CR()
@Serializable @SerialName("connectionIncognitoUpdated") class ConnectionIncognitoUpdated(val user: UserRef, val toConnection: PendingContactConnection): CR()
+ @Serializable @SerialName("connectionUserChanged") class ConnectionUserChanged(val user: UserRef, val fromConnection: PendingContactConnection, val toConnection: PendingContactConnection, val newUser: UserRef): CR()
@Serializable @SerialName("connectionPlan") class CRConnectionPlan(val user: UserRef, val connectionPlan: ConnectionPlan): CR()
@Serializable @SerialName("sentConfirmation") class SentConfirmation(val user: UserRef, val connection: PendingContactConnection): CR()
@Serializable @SerialName("sentInvitation") class SentInvitation(val user: UserRef, val connection: PendingContactConnection): CR()
@@ -4935,6 +4960,7 @@ sealed class CR {
is ConnectionVerified -> "connectionVerified"
is Invitation -> "invitation"
is ConnectionIncognitoUpdated -> "connectionIncognitoUpdated"
+ is ConnectionUserChanged -> "ConnectionUserChanged"
is CRConnectionPlan -> "connectionPlan"
is SentConfirmation -> "sentConfirmation"
is SentInvitation -> "sentInvitation"
@@ -5103,6 +5129,7 @@ sealed class CR {
is ConnectionVerified -> withUser(user, "verified: $verified\nconnectionCode: $expectedCode")
is Invitation -> withUser(user, "connReqInvitation: $connReqInvitation\nconnection: $connection")
is ConnectionIncognitoUpdated -> withUser(user, json.encodeToString(toConnection))
+ is ConnectionUserChanged -> withUser(user, "fromConnection: ${json.encodeToString(fromConnection)}\ntoConnection: ${json.encodeToString(toConnection)}\nnewUser: ${json.encodeToString(newUser)}" )
is CRConnectionPlan -> withUser(user, json.encodeToString(connectionPlan))
is SentConfirmation -> withUser(user, json.encodeToString(connection))
is SentInvitation -> withUser(user, json.encodeToString(connection))
@@ -5553,6 +5580,7 @@ sealed class ChatErrorType {
is AgentCommandError -> "agentCommandError"
is InvalidFileDescription -> "invalidFileDescription"
is ConnectionIncognitoChangeProhibited -> "connectionIncognitoChangeProhibited"
+ is ConnectionUserChangeProhibited -> "connectionUserChangeProhibited"
is PeerChatVRangeIncompatible -> "peerChatVRangeIncompatible"
is InternalError -> "internalError"
is CEException -> "exception $message"
@@ -5630,6 +5658,7 @@ sealed class ChatErrorType {
@Serializable @SerialName("agentCommandError") class AgentCommandError(val message: String): ChatErrorType()
@Serializable @SerialName("invalidFileDescription") class InvalidFileDescription(val message: String): ChatErrorType()
@Serializable @SerialName("connectionIncognitoChangeProhibited") object ConnectionIncognitoChangeProhibited: ChatErrorType()
+ @Serializable @SerialName("connectionUserChangeProhibited") object ConnectionUserChangeProhibited: ChatErrorType()
@Serializable @SerialName("peerChatVRangeIncompatible") object PeerChatVRangeIncompatible: ChatErrorType()
@Serializable @SerialName("internalError") class InternalError(val message: String): ChatErrorType()
@Serializable @SerialName("exception") class CEException(val message: String): ChatErrorType()
diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ContactConnectionInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ContactConnectionInfoView.kt
index 88e483e92d..64ff7e4f40 100644
--- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ContactConnectionInfoView.kt
+++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ContactConnectionInfoView.kt
@@ -39,7 +39,7 @@ fun ContactConnectionInfoView(
) {
LaunchedEffect(connReqInvitation) {
if (connReqInvitation != null) {
- chatModel.showingInvitation.value = ShowingInvitation(contactConnection.id, connReqInvitation, false)
+ chatModel.showingInvitation.value = ShowingInvitation(contactConnection.id, connReqInvitation, false, conn = contactConnection)
}
}
/** When [AddContactLearnMore] is open, we don't need to drop [ChatModel.showingInvitation].
diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt
index d2e8ac7a6c..544f5f72bb 100644
--- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt
+++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt
@@ -2,20 +2,25 @@ package chat.simplex.common.views.newchat
import SectionBottomSpacer
import SectionItemView
+import SectionSpacer
import SectionTextFooter
import SectionView
+import TextIconSpaced
import androidx.compose.foundation.*
-import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
+import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.text.TextStyle
@@ -32,6 +37,7 @@ import chat.simplex.common.ui.theme.*
import chat.simplex.common.views.helpers.*
import chat.simplex.common.views.usersettings.*
import chat.simplex.res.MR
+import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.net.URI
@@ -43,7 +49,7 @@ enum class NewChatOption {
fun ModalData.NewChatView(rh: RemoteHostInfo?, selection: NewChatOption, showQRCodeScanner: Boolean = false, close: () -> Unit) {
val selection = remember { stateGetOrPut("selection") { selection } }
val showQRCodeScanner = remember { stateGetOrPut("showQRCodeScanner") { showQRCodeScanner } }
- val contactConnection: MutableState = rememberSaveable(stateSaver = serializableSaver()) { mutableStateOf(null) }
+ val contactConnection: MutableState = rememberSaveable(stateSaver = serializableSaver()) { mutableStateOf(chatModel.showingInvitation.value?.conn) }
val connReqInvitation by remember { derivedStateOf { chatModel.showingInvitation.value?.connReq ?: "" } }
val creatingConnReq = rememberSaveable { mutableStateOf(false) }
val pastedLink = rememberSaveable { mutableStateOf("") }
@@ -177,6 +183,15 @@ private fun CreatingLinkProgressView() {
DefaultProgressView(stringResource(MR.strings.creating_link))
}
+private fun updateShownConnection(conn: PendingContactConnection) {
+ chatModel.showingInvitation.value = chatModel.showingInvitation.value?.copy(
+ conn = conn,
+ connId = conn.id,
+ connReq = conn.connReqInv ?: "",
+ connChatUsed = true
+ )
+}
+
@Composable
private fun RetryButton(onClick: () -> Unit) {
Column(
@@ -192,6 +207,248 @@ private fun RetryButton(onClick: () -> Unit) {
}
}
+@Composable
+private fun ProfilePickerOption(
+ title: String,
+ selected: Boolean,
+ disabled: Boolean,
+ onSelected: () -> Unit,
+ image: @Composable () -> Unit,
+ onInfo: (() -> Unit)? = null
+) {
+ Row(
+ Modifier
+ .fillMaxWidth()
+ .sizeIn(minHeight = DEFAULT_MIN_SECTION_ITEM_HEIGHT + 8.dp)
+ .clickable(enabled = !disabled, onClick = onSelected)
+ .padding(horizontal = DEFAULT_PADDING, vertical = 4.dp),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ image()
+ TextIconSpaced(false)
+ Text(title, modifier = Modifier.align(Alignment.CenterVertically))
+ if (onInfo != null) {
+ Spacer(Modifier.padding(6.dp))
+ Column(Modifier
+ .size(48.dp)
+ .clip(CircleShape)
+ .clickable(
+ enabled = !disabled,
+ onClick = { ModalManager.start.showModal { IncognitoView() } }
+ ),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center
+ ) {
+ Icon(
+ painterResource(MR.images.ic_info),
+ stringResource(MR.strings.incognito),
+ tint = MaterialTheme.colors.primary
+ )
+ }
+ }
+ Spacer(Modifier.weight(1f))
+ if (selected) {
+ Icon(
+ painterResource(
+ MR.images.ic_check
+ ),
+ title,
+ Modifier.size(20.dp),
+ tint = MaterialTheme.colors.primary,
+ )
+ }
+ }
+ Divider(
+ Modifier.padding(
+ start = DEFAULT_PADDING_HALF,
+ end = DEFAULT_PADDING_HALF,
+ )
+ )
+}
+
+private fun filteredProfiles(users: List, searchTextOrPassword: String): List {
+ val s = searchTextOrPassword.trim()
+ val lower = s.lowercase()
+ return users.filter { u ->
+ if ((u.activeUser || !u.hidden) && (s == "" || u.anyNameContains(lower))) {
+ true
+ } else {
+ correctPassword(u, s)
+ }
+ }
+}
+
+@Composable
+private fun ActiveProfilePicker(
+ search: MutableState,
+ contactConnection: PendingContactConnection?,
+ close: () -> Unit,
+ rhId: Long?
+) {
+ val switchingProfile = remember { mutableStateOf(false) }
+ val incognito = remember {
+ chatModel.showingInvitation.value?.conn?.incognito ?: controller.appPrefs.incognito.get()
+ }
+ val selectedProfile by remember { chatModel.currentUser }
+ val searchTextOrPassword = rememberSaveable { search }
+ val profiles = remember {
+ chatModel.users.map { it.user }.sortedBy { !it.activeUser }
+ }
+ val filteredProfiles by remember {
+ derivedStateOf { filteredProfiles(profiles, searchTextOrPassword.value) }
+ }
+
+ var progressByTimeout by rememberSaveable { mutableStateOf(false) }
+
+ LaunchedEffect(switchingProfile.value) {
+ progressByTimeout = if (switchingProfile.value) {
+ delay(500)
+ switchingProfile.value
+ } else {
+ false
+ }
+ }
+
+ @Composable
+ fun ProfilePickerUserOption(user: User) {
+ val selected = selectedProfile?.userId == user.userId && !incognito
+
+ ProfilePickerOption(
+ title = user.chatViewName,
+ disabled = switchingProfile.value || selected,
+ selected = selected,
+ onSelected = {
+ switchingProfile.value = true
+ withApi {
+ try {
+ if (contactConnection != null) {
+ val conn = controller.apiChangeConnectionUser(rhId, contactConnection.pccConnId, user.userId)
+ if (conn != null) {
+ withChats {
+ updateContactConnection(rhId, conn)
+ updateShownConnection(conn)
+ }
+ controller.changeActiveUser_(
+ rhId = user.remoteHostId,
+ toUserId = user.userId,
+ viewPwd = if (user.hidden) searchTextOrPassword.value else null
+ )
+
+ if (chatModel.currentUser.value?.userId != user.userId) {
+ AlertManager.shared.showAlertMsg(generalGetString(
+ MR.strings.switching_profile_error_title),
+ String.format(generalGetString(MR.strings.switching_profile_error_message), user.chatViewName)
+ )
+ }
+
+ withChats {
+ updateContactConnection(user.remoteHostId, conn)
+ }
+ close.invoke()
+ }
+ }
+ } finally {
+ switchingProfile.value = false
+ }
+ }
+ },
+ image = { ProfileImage(size = 42.dp, image = user.image) }
+ )
+ }
+
+ @Composable
+ fun IncognitoUserOption() {
+ ProfilePickerOption(
+ disabled = switchingProfile.value,
+ title = stringResource(MR.strings.incognito),
+ selected = incognito,
+ onSelected = {
+ if (!incognito) {
+ switchingProfile.value = true
+ withApi {
+ try {
+ if (contactConnection != null) {
+ val conn = controller.apiSetConnectionIncognito(rhId, contactConnection.pccConnId, true)
+
+ if (conn != null) {
+ withChats {
+ updateContactConnection(rhId, conn)
+ updateShownConnection(conn)
+ }
+ close.invoke()
+ }
+ }
+ } finally {
+ switchingProfile.value = false
+ }
+ }
+ }
+ },
+ image = {
+ Spacer(Modifier.width(8.dp))
+ Icon(
+ painterResource(MR.images.ic_theater_comedy_filled),
+ contentDescription = stringResource(MR.strings.incognito),
+ Modifier.size(32.dp),
+ tint = Indigo,
+ )
+ Spacer(Modifier.width(2.dp))
+ },
+ onInfo = { ModalManager.start.showModal { IncognitoView() } },
+ )
+ }
+
+ BoxWithConstraints {
+ Column(
+ Modifier
+ .fillMaxSize()
+ .alpha(if (progressByTimeout) 0.6f else 1f)
+ ) {
+ LazyColumnWithScrollBar(userScrollEnabled = !switchingProfile.value) {
+ item {
+ AppBarTitle(stringResource(MR.strings.select_chat_profile), hostDevice(rhId), bottomPadding = DEFAULT_PADDING)
+ }
+ val activeProfile = filteredProfiles.firstOrNull { it.activeUser }
+
+ if (activeProfile != null) {
+ val otherProfiles = filteredProfiles.filter { it.userId != activeProfile.userId }
+
+ if (incognito) {
+ item {
+ IncognitoUserOption()
+ }
+ item {
+ ProfilePickerUserOption(activeProfile)
+ }
+ } else {
+ item {
+ ProfilePickerUserOption(activeProfile)
+ }
+ item {
+ IncognitoUserOption()
+ }
+ }
+
+ itemsIndexed(otherProfiles) { _, p ->
+ ProfilePickerUserOption(p)
+ }
+ } else {
+ item {
+ IncognitoUserOption()
+ }
+ itemsIndexed(filteredProfiles) { _, p ->
+ ProfilePickerUserOption(p)
+ }
+ }
+ }
+ }
+ if (progressByTimeout) {
+ DefaultProgressView("")
+ }
+ }
+}
+
@Composable
private fun InviteView(rhId: Long?, connReqInvitation: String, contactConnection: MutableState) {
SectionView(stringResource(MR.strings.share_this_1_time_link).uppercase(), headerBottomPadding = 5.dp) {
@@ -204,23 +461,72 @@ private fun InviteView(rhId: Long?, connReqInvitation: String, contactConnection
SimpleXLinkQRCode(connReqInvitation, onShare = { chatModel.markShowingInvitationUsed() })
}
- Spacer(Modifier.height(10.dp))
- val incognito = remember { mutableStateOf(controller.appPrefs.incognito.get()) }
- IncognitoToggle(controller.appPrefs.incognito, incognito) {
- ModalManager.start.showModal { IncognitoView() }
+ Spacer(Modifier.height(DEFAULT_PADDING))
+ val incognito by remember(chatModel.showingInvitation.value?.conn?.incognito, controller.appPrefs.incognito.get()) {
+ derivedStateOf {
+ chatModel.showingInvitation.value?.conn?.incognito ?: controller.appPrefs.incognito.get()
+ }
}
- KeyChangeEffect(incognito.value) {
- withBGApi {
- val contactConn = contactConnection.value ?: return@withBGApi
- val conn = controller.apiSetConnectionIncognito(rhId, contactConn.pccConnId, incognito.value) ?: return@withBGApi
- withChats {
- contactConnection.value = conn
- updateContactConnection(rhId, conn)
+ val currentUser = remember { chatModel.currentUser }.value
+
+ if (currentUser != null) {
+ SectionView(stringResource(MR.strings.new_chat_share_profile).uppercase(), headerBottomPadding = 5.dp) {
+ SectionItemView(
+ padding = PaddingValues(
+ top = 0.dp,
+ bottom = 0.dp,
+ start = 16.dp,
+ end = 16.dp
+ ),
+ click = {
+ ModalManager.start.showCustomModal { close ->
+ val search = rememberSaveable { mutableStateOf("") }
+ ModalView(
+ { close() },
+ endButtons = {
+ SearchTextField(Modifier.fillMaxWidth(), placeholder = stringResource(MR.strings.search_verb), alwaysVisible = true) { search.value = it }
+ },
+ content = {
+ ActiveProfilePicker(
+ search = search,
+ close = close,
+ rhId = rhId,
+ contactConnection = contactConnection.value
+ )
+ })
+ }
+ }
+ ) {
+ if (incognito) {
+ Spacer(Modifier.width(8.dp))
+ Icon(
+ painterResource(MR.images.ic_theater_comedy_filled),
+ contentDescription = stringResource(MR.strings.incognito),
+ tint = Indigo,
+ modifier = Modifier.size(32.dp)
+ )
+ Spacer(Modifier.width(2.dp))
+ } else {
+ ProfileImage(size = 42.dp, image = currentUser.image)
+ }
+ TextIconSpaced(false)
+ Text(
+ text = if (incognito) stringResource(MR.strings.incognito) else currentUser.chatViewName,
+ color = MaterialTheme.colors.onBackground
+ )
+ Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.End) {
+ Icon(
+ painter = painterResource(MR.images.ic_arrow_forward_ios),
+ contentDescription = stringResource(MR.strings.new_chat_share_profile),
+ tint = MaterialTheme.colors.secondary,
+ )
+ }
}
}
- chatModel.markShowingInvitationUsed()
+ if (incognito) {
+ SectionTextFooter(generalGetString(MR.strings.connect__a_new_random_profile_will_be_shared))
+ }
}
- SectionTextFooter(sharedProfileInfo(chatModel, incognito.value))
}
@Composable
@@ -366,7 +672,7 @@ private fun createInvitation(
if (r != null) {
withChats {
updateContactConnection(rhId, r.second)
- chatModel.showingInvitation.value = ShowingInvitation(connId = r.second.id, connReq = simplexChatLink(r.first), connChatUsed = false)
+ chatModel.showingInvitation.value = ShowingInvitation(connId = r.second.id, connReq = simplexChatLink(r.first), connChatUsed = false, conn = r.second)
contactConnection.value = r.second
}
} else {
diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt
index a7bf5920e4..d4334dfed2 100644
--- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt
+++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt
@@ -303,7 +303,7 @@ private fun ProfileActionView(action: UserProfileAction, user: User, doAction: (
}
}
-private fun filteredUsers(m: ChatModel, searchTextOrPassword: String): List {
+fun filteredUsers(m: ChatModel, searchTextOrPassword: String): List {
val s = searchTextOrPassword.trim()
val lower = s.lowercase()
return m.users.filter { u ->
@@ -317,7 +317,7 @@ private fun filteredUsers(m: ChatModel, searchTextOrPassword: String): List !u.user.hidden }.size
-private fun correctPassword(user: User, pwd: String): Boolean {
+fun correctPassword(user: User, pwd: String): Boolean {
val ph = user.viewPwdHash
return ph != null && pwd != "" && chatPasswordHash(pwd, ph.salt) == ph.hash
}
diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml
index f5272ce7fc..9e9beef86b 100644
--- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml
+++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml
@@ -665,6 +665,10 @@
1-time linkSimpleX addressOr show this code
+ Share profile
+ Select chat profile
+ Error switching profile
+ Your connection was moved to %s but an unexpected error occurred while redirecting you to the profile.Or scan QR codeKeep unused invitation?You can view invitation link again in connection details.
diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs
index dc3b4b2e54..796a128abe 100644
--- a/src/Simplex/Chat.hs
+++ b/src/Simplex/Chat.hs
@@ -1709,7 +1709,7 @@ processChatCommand' vr = \case
pure conn'
recreateConn user conn@PendingContactConnection {customUserProfileId} newUser = do
subMode <- chatReadVar subscriptionMode
- (agConnId, cReq) <- withAgent $ \a -> createConnection a (aUserId user) True SCMInvitation Nothing IKPQOn subMode
+ (agConnId, cReq) <- withAgent $ \a -> createConnection a (aUserId newUser) True SCMInvitation Nothing IKPQOn subMode
conn' <- withFastStore' $ \db -> do
deleteConnectionRecord db user connId
forM_ customUserProfileId $ \profileId ->
diff --git a/tests/ChatTests/Profiles.hs b/tests/ChatTests/Profiles.hs
index 878546ba21..a36eef8ca9 100644
--- a/tests/ChatTests/Profiles.hs
+++ b/tests/ChatTests/Profiles.hs
@@ -1,6 +1,7 @@
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PostfixOperators #-}
+{-# LANGUAGE TypeApplications #-}
module ChatTests.Profiles where
@@ -18,6 +19,8 @@ import Simplex.Chat.Types (ConnStatus (..), Profile (..))
import Simplex.Chat.Types.Shared (GroupMemberRole (..))
import Simplex.Chat.Types.UITheme
import Simplex.Messaging.Encoding.String (StrEncoding (..))
+import Simplex.Messaging.Server.Env.STM hiding (subscriptions)
+import Simplex.Messaging.Transport
import Simplex.Messaging.Util (encodeJSON)
import System.Directory (copyFile, createDirectoryIfMissing)
import Test.Hspec hiding (it)
@@ -1653,34 +1656,42 @@ testChangePCCUserAndThenIncognito = testChat2 aliceProfile bobProfile $
]
testChangePCCUserDiffSrv :: HasCallStack => FilePath -> IO ()
-testChangePCCUserDiffSrv = testChat2 aliceProfile bobProfile $
- \alice bob -> do
- -- Create a new invite
- alice ##> "/connect"
- _ <- getInvitation alice
- alice ##> "/_set incognito :1 on"
- alice <## "connection 1 changed to incognito"
- -- Create new user with different servers
- alice ##> "/create user alisa"
- showActiveUser alice "alisa"
- alice #$> ("/smp smp://2345-w==@smp2.example.im smp://3456-w==@smp3.example.im:5224", id, "ok")
- alice ##> "/user alice"
- showActiveUser alice "alice (Alice)"
- -- Change connection to newly created user and use the newly created connection
- alice ##> "/_set conn user :1 2"
- alice <## "connection 1 changed from user alice to user alisa, new link:"
- alice <## ""
- inv <- getTermLine alice
- alice <## ""
- alice `hasContactProfiles` ["alice"]
- alice ##> "/user alisa"
- showActiveUser alice "alisa"
- -- Connect
- bob ##> ("/connect " <> inv)
- bob <## "confirmation sent!"
- concurrently_
- (alice <## "bob (Bob): contact is connected")
- (bob <## "alisa: contact is connected")
+testChangePCCUserDiffSrv tmp = do
+ withSmpServer' serverCfg' $ do
+ withNewTestChatCfgOpts tmp testCfg testOpts "alice" aliceProfile $ \alice -> do
+ withNewTestChatCfgOpts tmp testCfg testOpts "bob" bobProfile $ \bob -> do
+ -- Create a new invite
+ alice ##> "/connect"
+ _ <- getInvitation alice
+ alice ##> "/_set incognito :1 on"
+ alice <## "connection 1 changed to incognito"
+ -- Create new user with different servers
+ alice ##> "/create user alisa"
+ showActiveUser alice "alisa"
+ alice #$> ("/smp smp://LcJUMfVhwD8yxjAiSaDzzGF3-kLG4Uh0Fl_ZIjrRwjI=:server_password@localhost:7003", id, "ok")
+ alice ##> "/user alice"
+ showActiveUser alice "alice (Alice)"
+ -- Change connection to newly created user and use the newly created connection
+ alice ##> "/_set conn user :1 2"
+ alice <## "connection 1 changed from user alice to user alisa, new link:"
+ alice <## ""
+ inv <- getTermLine alice
+ alice <## ""
+ alice `hasContactProfiles` ["alice"]
+ alice ##> "/user alisa"
+ showActiveUser alice "alisa"
+ -- Connect
+ bob ##> ("/connect " <> inv)
+ bob <## "confirmation sent!"
+ concurrently_
+ (alice <## "bob (Bob): contact is connected")
+ (bob <## "alisa: contact is connected")
+ where
+ serverCfg' =
+ smpServerCfg
+ { transports = [("7003", transport @TLS), ("7002", transport @TLS)],
+ msgQueueQuota = 2
+ }
testSetConnectionAlias :: HasCallStack => FilePath -> IO ()
testSetConnectionAlias = testChat2 aliceProfile bobProfile $