Compare commits

...

14 commits

Author SHA1 Message Date
spaced4ndy
3d22b738d8
core: fix change connection user (#5992)
* core: fix change connection user

* plans
2025-06-16 22:38:02 +01:00
Evgeny Poberezkin
c08189108e
6.3.6: ios 282, android 295, desktop 106 2025-06-14 20:12:19 +01:00
Evgeny Poberezkin
442d9afc4b
android: remove Contribute link from Android bundle 2025-06-14 19:26:46 +01:00
Evgeny Poberezkin
a593557c21
core: 6.3.6.0 (simplexmq 6.4.0.3.1) 2025-06-14 14:46:08 +01:00
Evgeny
07abe24e18
core: make decoding for short link data forward compatible (#5989)
* core: make decoding for short link data forward compatible

* simplexmq
2025-06-14 14:17:34 +01:00
Evgeny Poberezkin
5f6595dda9
6.3.5: ios 280, android 292, desktop 104 2025-06-09 09:32:32 +01:00
Evgeny Poberezkin
6fdd50efb9
core: 6.3.5.0 2025-06-08 18:28:26 +01:00
Evgeny
50dfda6c09
core: fix deletion queries for PostgreSQL client (#5969)
* core: fix deletion queries for PostgreSQL client

* disable test in posrgres

* plan
2025-06-08 18:27:42 +01:00
Evgeny Poberezkin
ea1a81fcac
core: 6.3.4.2 (simplexmq 6.4.0.3) 2025-06-06 12:26:46 +01:00
Evgeny
cf0639bf28
website: add Whonix to reviews (#5966) 2025-06-05 21:05:16 +01:00
Evgeny
7b362ff655
ui: label in compose when user cannot send messages (#5922)
* ui: label in compose when user cannot send messages

* gray buttons when user cannot send messages

* improve

* kotlin

* fix order

* fix alert

---------

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
2025-05-19 14:50:33 +00:00
Evgeny
26e5742354
ios: fix swipe in members list for iOS 15 (#5914)
* ios: fix swipe in members list for iOS 15

* refactor
2025-05-15 14:58:40 +01:00
Evgeny
5dd89fe127
ios: fix swipe on iOS 15, fix onboarding layout on iOS 15 and small screens (#5913)
* ios: fix onboarding layout issues on iOS 15 and small screens

* fix swipe on iOS 15
2025-05-15 14:25:46 +01:00
sh
a36a6d44db
flatpak: update metainfo (#5899)
* flatpak: update metainfo

* flatpak: rewrite metainfo
2025-05-14 10:55:03 +01:00
87 changed files with 529 additions and 496 deletions

View file

@ -10,7 +10,7 @@
# SimpleX - the first messaging platform that has no user identifiers of any kind - 100% private by design!
[<img src="./images/trail-of-bits.jpg" height="100">](http://simplex.chat/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html) &nbsp;&nbsp;&nbsp; [<img src="./images/privacy-guides.jpg" height="80">](https://www.privacyguides.org/en/real-time-communication/#simplex-chat) &nbsp;&nbsp;&nbsp; [<img src="./images/kuketz-blog.jpg" height="80">](https://www.kuketz-blog.de/simplex-eindruecke-vom-messenger-ohne-identifier/)
[<img src="./images/trail-of-bits.jpg" height="80">](http://simplex.chat/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html) &nbsp;&nbsp;&nbsp; [<img src="./images/privacy-guides.jpg" height="64">](https://www.privacyguides.org/en/real-time-communication/#simplex-chat) &nbsp;&nbsp;&nbsp; [<img src="./images/whonix-logo.jpg" height="64">](https://www.whonix.org/wiki/Chat#Recommendation) &nbsp;&nbsp;&nbsp; [<img src="./images/kuketz-blog.jpg" height="64">](https://www.kuketz-blog.de/simplex-eindruecke-vom-messenger-ohne-identifier/)
## Welcome to SimpleX Chat!
@ -110,6 +110,15 @@ After you connect, you can [verify connection security code](./blog/20230103-sim
Read about the app features and settings in the new [User guide](./docs/guide/README.md).
## Contribute
We would love to have you join the development! You can help us with:
- [share the color theme](./docs/THEMES.md) you use in Android app!
- writing a tutorial or recipes about hosting servers, chat bot automations, etc.
- contributing to SimpleX Chat knowledge-base.
- developing features - please connect to us via chat so we can help you get started.
## Help translating SimpleX Chat
Thanks to our users and [Weblate](https://hosted.weblate.org/engage/simplex-chat/), SimpleX Chat apps, website and documents are translated to many other languages.
@ -141,15 +150,6 @@ Join our translators to help SimpleX grow!
Languages in progress: Arabic, Japanese, Korean, Portuguese and [others](https://hosted.weblate.org/projects/simplex-chat/#languages). We will be adding more languages as some of the already added are completed please suggest new languages, review the [translation guide](./docs/TRANSLATIONS.md) and get in touch with us!
## Contribute
We would love to have you join the development! You can help us with:
- [share the color theme](./docs/THEMES.md) you use in Android app!
- writing a tutorial or recipes about hosting servers, chat bot automations, etc.
- contributing to SimpleX Chat knowledge-base.
- developing features - please connect to us via chat so we can help you get started.
## Please support us with your donations
Huge thank you to everybody who donated to SimpleX Chat!

View file

@ -1152,27 +1152,6 @@ final class Chat: ObservableObject, Identifiable, ChatLike {
)
}
var userCanSend: Bool {
switch chatInfo {
case .direct: return true
case let .group(groupInfo):
let m = groupInfo.membership
return m.memberActive && m.memberRole >= .member
case .local:
return true
default: return false
}
}
var userIsObserver: Bool {
switch chatInfo {
case let .group(groupInfo):
let m = groupInfo.membership
return m.memberActive && m.memberRole == .observer
default: return false
}
}
var unreadTag: Bool {
switch chatInfo.chatSettings?.enableNtfs {
case .all: chatStats.unreadChat || chatStats.unreadCount > 0

View file

@ -98,14 +98,24 @@ struct ChatView: View {
}
connectingText()
if selectedChatItems == nil {
let reason = chat.chatInfo.userCantSendReason
ComposeView(
chat: chat,
composeState: $composeState,
keyboardVisible: $keyboardVisible,
keyboardHiddenDate: $keyboardHiddenDate,
selectedRange: $selectedRange
selectedRange: $selectedRange,
disabledText: reason?.composeLabel
)
.disabled(!cInfo.sendMsgEnabled)
.if(!cInfo.sendMsgEnabled) { v in
v.disabled(true).onTapGesture {
AlertManager.shared.showAlertMsg(
title: "You can't send messages!",
message: reason?.alertMessage
)
}
}
} else {
SelectedItemsBottomToolbar(
chatItems: ItemsModel.shared.reversedChatItems,

View file

@ -327,6 +327,7 @@ struct ComposeView: View {
@Binding var keyboardVisible: Bool
@Binding var keyboardHiddenDate: Date
@Binding var selectedRange: NSRange
var disabledText: LocalizedStringKey? = nil
@State var linkUrl: URL? = nil
@State var hasSimplexLink: Bool = false
@ -391,7 +392,7 @@ struct ComposeView: View {
Image(systemName: "paperclip")
.resizable()
}
.disabled(composeState.attachmentDisabled || !chat.userCanSend || (chat.chatInfo.contact?.nextSendGrpInv ?? false))
.disabled(composeState.attachmentDisabled || !chat.chatInfo.sendMsgEnabled || (chat.chatInfo.contact?.nextSendGrpInv ?? false))
.frame(width: 25, height: 25)
.padding(.bottom, 16)
.padding(.leading, 12)
@ -441,19 +442,13 @@ struct ComposeView: View {
: theme.colors.primary
)
.padding(.trailing, 12)
.disabled(!chat.userCanSend)
.disabled(!chat.chatInfo.sendMsgEnabled)
if chat.userIsObserver {
Text("you are observer")
if let disabledText {
Text(disabledText)
.italic()
.foregroundColor(theme.colors.secondary)
.padding(.horizontal, 12)
.onTapGesture {
AlertManager.shared.showAlertMsg(
title: "You can't send messages!",
message: "Please contact group admin."
)
}
}
}
}
@ -479,8 +474,8 @@ struct ComposeView: View {
hasSimplexLink = false
}
}
.onChange(of: chat.userCanSend) { canSend in
if !canSend {
.onChange(of: chat.chatInfo.sendMsgEnabled) { sendEnabled in
if !sendEnabled {
cancelCurrentVoiceRecording()
clearCurrentDraft()
clearState()

View file

@ -15,6 +15,7 @@ struct SendMessageView: View {
@Binding var composeState: ComposeState
@Binding var selectedRange: NSRange
@EnvironmentObject var theme: AppTheme
@Environment(\.isEnabled) var isEnabled
var sendMessage: (Int?) -> Void
var sendLiveMessage: (() async -> Void)? = nil
var updateLiveMessage: (() async -> Void)? = nil
@ -255,6 +256,7 @@ struct SendMessageView: View {
}
private struct RecordVoiceMessageButton: View {
@Environment(\.isEnabled) var isEnabled
@EnvironmentObject var theme: AppTheme
var startVoiceMessageRecording: (() -> Void)?
var finishVoiceMessageRecording: (() -> Void)?
@ -263,11 +265,11 @@ struct SendMessageView: View {
@State private var pressed: TimeInterval? = nil
var body: some View {
Image(systemName: "mic.fill")
Image(systemName: isEnabled ? "mic.fill" : "mic")
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.foregroundColor(theme.colors.primary)
.foregroundColor(isEnabled ? theme.colors.primary : theme.colors.secondary)
.opacity(holdingVMR ? 0.7 : 1)
.disabled(disabled)
.frame(width: 31, height: 31)
@ -352,7 +354,7 @@ struct SendMessageView: View {
Image(systemName: "bolt.fill")
.resizable()
.scaledToFit()
.foregroundColor(theme.colors.primary)
.foregroundColor(isEnabled ? theme.colors.primary : theme.colors.secondary)
.frame(width: 20, height: 20)
}
.frame(width: 29, height: 29)

View file

@ -144,17 +144,9 @@ struct GroupChatInfoView: View {
let filteredMembers = s == ""
? members
: members.filter { $0.wrapped.localAliasAndFullName.localizedLowercase.contains(s) }
MemberRowView(groupInfo: groupInfo, groupMember: GMember(groupInfo.membership), user: true, alert: $alert)
MemberRowView(chat: chat, groupInfo: groupInfo, groupMember: GMember(groupInfo.membership), user: true, alert: $alert)
ForEach(filteredMembers) { member in
ZStack {
NavigationLink {
memberInfoView(member)
} label: {
EmptyView()
}
.opacity(0)
MemberRowView(groupInfo: groupInfo, groupMember: member, alert: $alert)
}
MemberRowView(chat: chat, groupInfo: groupInfo, groupMember: member, alert: $alert)
}
}
@ -358,6 +350,7 @@ struct GroupChatInfoView: View {
}
private struct MemberRowView: View {
var chat: Chat
var groupInfo: GroupInfo
@ObservedObject var groupMember: GMember
@EnvironmentObject var theme: AppTheme
@ -366,7 +359,7 @@ struct GroupChatInfoView: View {
var body: some View {
let member = groupMember.wrapped
let v = HStack{
let v1 = HStack{
MemberProfileImage(member, size: 38)
.padding(.trailing, 2)
// TODO server connection status
@ -383,6 +376,20 @@ struct GroupChatInfoView: View {
memberInfo(member)
}
let v = ZStack {
if user {
v1
} else {
NavigationLink {
memberInfoView()
} label: {
EmptyView()
}
.opacity(0)
v1
}
}
if user {
v
} else if groupInfo.membership.memberRole >= .admin {
@ -407,6 +414,11 @@ struct GroupChatInfoView: View {
}
}
private func memberInfoView() -> some View {
GroupMemberInfoView(groupInfo: groupInfo, chat: chat, groupMember: groupMember)
.navigationBarHidden(false)
}
private func memberConnStatus(_ member: GroupMember) -> LocalizedStringKey {
if member.activeConn?.connDisabled ?? false {
return "disabled"
@ -485,11 +497,6 @@ struct GroupChatInfoView: View {
.foregroundColor(theme.colors.secondary)
}
}
private func memberInfoView(_ groupMember: GMember) -> some View {
GroupMemberInfoView(groupInfo: groupInfo, chat: chat, groupMember: groupMember)
.navigationBarHidden(false)
}
private func groupLinkButton() -> some View {
NavigationLink {

View file

@ -94,7 +94,7 @@ struct ChatListNavLink: View {
Group {
if contact.activeConn == nil && contact.profile.contactLink != nil && contact.active {
ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false))
.frame(height: dynamicRowHeight)
.frameCompat(height: dynamicRowHeight)
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
Button {
deleteContactDialog(
@ -121,6 +121,7 @@ struct ChatListNavLink: View {
selection: $chatModel.chatId,
label: { ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false)) }
)
.frameCompat(height: dynamicRowHeight)
.swipeActions(edge: .leading, allowsFullSwipe: true) {
markReadButton()
toggleFavoriteButton()
@ -145,7 +146,6 @@ struct ChatListNavLink: View {
}
.tint(.red)
}
.frame(height: dynamicRowHeight)
}
}
.alert(item: $alert) { $0.alert }
@ -163,7 +163,7 @@ struct ChatListNavLink: View {
switch (groupInfo.membership.memberStatus) {
case .memInvited:
ChatPreviewView(chat: chat, progressByTimeout: $progressByTimeout)
.frame(height: dynamicRowHeight)
.frameCompat(height: dynamicRowHeight)
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
joinGroupButton()
if groupInfo.canDelete {
@ -183,7 +183,7 @@ struct ChatListNavLink: View {
.disabled(inProgress)
case .memAccepted:
ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false))
.frame(height: dynamicRowHeight)
.frameCompat(height: dynamicRowHeight)
.onTapGesture {
AlertManager.shared.showAlert(groupInvitationAcceptedAlert())
}
@ -203,7 +203,7 @@ struct ChatListNavLink: View {
label: { ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false)) },
disabled: !groupInfo.ready
)
.frame(height: dynamicRowHeight)
.frameCompat(height: dynamicRowHeight)
.swipeActions(edge: .leading, allowsFullSwipe: true) {
markReadButton()
toggleFavoriteButton()
@ -250,7 +250,7 @@ struct ChatListNavLink: View {
label: { ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false)) },
disabled: !noteFolder.ready
)
.frame(height: dynamicRowHeight)
.frameCompat(height: dynamicRowHeight)
.swipeActions(edge: .leading, allowsFullSwipe: true) {
markReadButton()
}
@ -433,6 +433,7 @@ struct ChatListNavLink: View {
private func contactRequestNavLink(_ contactRequest: UserContactRequest) -> some View {
ContactRequestView(contactRequest: contactRequest, chat: chat)
.frameCompat(height: dynamicRowHeight)
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
Button {
Task { await acceptContactRequest(incognito: false, contactRequest: contactRequest) }
@ -451,7 +452,6 @@ struct ChatListNavLink: View {
}
.tint(.red)
}
.frame(height: dynamicRowHeight)
.contentShape(Rectangle())
.onTapGesture { showContactRequestDialog = true }
.confirmationDialog("Accept connection request?", isPresented: $showContactRequestDialog, titleVisibility: .visible) {
@ -463,6 +463,7 @@ struct ChatListNavLink: View {
private func contactConnectionNavLink(_ contactConnection: PendingContactConnection) -> some View {
ContactConnectionView(chat: chat)
.frameCompat(height: dynamicRowHeight)
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
Button {
AlertManager.shared.showAlert(deleteContactConnectionAlert(contactConnection) { a in
@ -480,7 +481,6 @@ struct ChatListNavLink: View {
}
.tint(theme.colors.primary)
}
.frame(height: dynamicRowHeight)
.appSheet(isPresented: $showContactConnectionInfo) {
Group {
if case let .contactConnection(contactConnection) = chat.chatInfo {
@ -583,7 +583,7 @@ struct ChatListNavLink: View {
Text("invalid chat data")
.foregroundColor(.red)
.padding(4)
.frame(height: dynamicRowHeight)
.frameCompat(height: dynamicRowHeight)
.onTapGesture { showInvalidJSON = true }
.appSheet(isPresented: $showInvalidJSON) {
invalidJSONView(dataToString(json))
@ -603,6 +603,24 @@ struct ChatListNavLink: View {
}
}
extension View {
@inline(__always)
@ViewBuilder fileprivate func frameCompat(height: CGFloat) -> some View {
if #available(iOS 16, *) {
self.frame(height: height)
} else {
VStack(spacing: 0) {
Divider()
.padding(.leading, 16)
self
.frame(height: height)
.padding(.horizontal, 8)
.padding(.vertical, 8)
}
}
}
}
func rejectContactRequestAlert(_ contactRequest: UserContactRequest) -> Alert {
Alert(
title: Text("Reject contact request"),

View file

@ -367,13 +367,7 @@ struct ChatListView: View {
.offset(x: -8)
} else {
ForEach(cs, id: \.viewId) { chat in
VStack(spacing: .zero) {
Divider()
.padding(.leading, 16)
ChatListNavLink(chat: chat, parentSheet: $sheet)
.padding(.horizontal, 8)
.padding(.vertical, 6)
}
ChatListNavLink(chat: chat, parentSheet: $sheet)
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
.listRowSeparator(.hidden)
.listRowInsets(EdgeInsets())

View file

@ -67,7 +67,7 @@ struct OnboardingConditionsView: View {
var body: some View {
GeometryReader { g in
ScrollView {
let v = ScrollView {
VStack(alignment: .leading, spacing: 20) {
Text("Conditions of use")
.font(.largeTitle)
@ -107,6 +107,7 @@ struct OnboardingConditionsView: View {
.frame(minHeight: 40)
}
}
.padding(25)
.frame(minHeight: g.size.height)
}
.onAppear {
@ -127,9 +128,14 @@ struct OnboardingConditionsView: View {
}
}
.frame(maxHeight: .infinity, alignment: .top)
if #available(iOS 16.4, *) {
v.scrollBounceBehavior(.basedOnSize)
} else {
v
}
}
.frame(maxHeight: .infinity, alignment: .top)
.padding(25)
.navigationBarHidden(true) // necessary on iOS 15
}
private func continueToNextStep() {

View file

@ -62,8 +62,7 @@ struct CreateProfile: View {
.frame(height: 20)
} footer: {
VStack(alignment: .leading, spacing: 8) {
Text("Your profile, contacts and delivered messages are stored on your device.")
Text("The profile is only shared with your contacts.")
Text("Your profile is stored on your device and only shared with your contacts.")
}
.foregroundColor(theme.colors.secondary)
.frame(maxWidth: .infinity, alignment: .leading)
@ -118,25 +117,22 @@ struct CreateFirstProfile: View {
@State private var nextStepNavLinkActive = false
var body: some View {
VStack(alignment: .leading, spacing: 20) {
VStack(alignment: .center, spacing: 20) {
Text("Create your profile")
let v = VStack(alignment: .leading, spacing: 16) {
VStack(alignment: .center, spacing: 16) {
Text("Create profile")
.font(.largeTitle)
.bold()
.multilineTextAlignment(.center)
Text("Your profile, contacts and delivered messages are stored on your device.")
.font(.callout)
.foregroundColor(theme.colors.secondary)
.multilineTextAlignment(.center)
Text("The profile is only shared with your contacts.")
Text("Your profile is stored on your device and only shared with your contacts.")
.font(.callout)
.foregroundColor(theme.colors.secondary)
.multilineTextAlignment(.center)
}
.fixedSize(horizontal: false, vertical: true)
.frame(maxWidth: .infinity) // Ensures it takes up the full width
.padding(.horizontal, 10)
.onTapGesture { focusDisplayName = false }
HStack {
let name = displayName.trimmingCharacters(in: .whitespaces)
@ -174,12 +170,23 @@ struct CreateFirstProfile: View {
}
}
.onAppear() {
focusDisplayName = true
if #available(iOS 16, *) {
focusDisplayName = true
} else {
// it does not work before animation completes on iOS 15
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
focusDisplayName = true
}
}
}
.padding(.horizontal, 25)
.padding(.top, 10)
.padding(.bottom, 25)
.frame(maxWidth: .infinity, alignment: .leading)
if #available(iOS 16, *) {
return v.padding(.top, 10)
} else {
return v.padding(.top, 75).ignoresSafeArea(.all, edges: .top)
}
}
func createProfileButton() -> some View {

View file

@ -17,7 +17,7 @@ struct SetNotificationsMode: View {
var body: some View {
GeometryReader { g in
ScrollView {
let v = ScrollView {
VStack(alignment: .center, spacing: 20) {
Text("Push notifications")
.font(.largeTitle)
@ -57,11 +57,17 @@ struct SetNotificationsMode: View {
.padding(25)
.frame(minHeight: g.size.height)
}
if #available(iOS 16.4, *) {
v.scrollBounceBehavior(.basedOnSize)
} else {
v
}
}
.frame(maxHeight: .infinity)
.sheet(isPresented: $showInfo) {
NotificationsInfoView()
}
.navigationBarHidden(true) // necessary on iOS 15
}
private func setNotificationsMode(_ token: DeviceToken, _ mode: NotificationsMode) {

View file

@ -18,7 +18,7 @@ struct SimpleXInfo: View {
var body: some View {
GeometryReader { g in
ScrollView {
let v = ScrollView {
VStack(alignment: .leading) {
VStack(alignment: .center, spacing: 10) {
Image(colorScheme == .light ? "logo" : "logo-light")
@ -36,7 +36,7 @@ struct SimpleXInfo: View {
.font(.headline)
}
}
Spacer()
VStack(alignment: .leading) {
@ -66,6 +66,9 @@ struct SimpleXInfo: View {
}
}
}
.padding(.horizontal, 25)
.padding(.top, 75)
.padding(.bottom, 25)
.frame(minHeight: g.size.height)
}
.sheet(isPresented: Binding(
@ -88,14 +91,17 @@ struct SimpleXInfo: View {
createProfileNavLinkActive: $createProfileNavLinkActive
)
}
if #available(iOS 16.4, *) {
v.scrollBounceBehavior(.basedOnSize)
} else {
v
}
}
.onAppear() {
setLastVersionDefault()
}
.frame(maxHeight: .infinity)
.padding(.horizontal, 25)
.padding(.top, 75)
.padding(.bottom, 25)
.navigationBarHidden(true) // necessary on iOS 15
}
private func onboardingInfoRow(_ image: String, _ title: LocalizedStringKey, _ text: LocalizedStringKey, width: CGFloat) -> some View {

View file

@ -2826,8 +2826,8 @@ We will be adding server redundancy to prevent lost messages.</source>
<source>The old database was not removed during the migration, it can be deleted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The sender will NOT be notified" xml:space="preserve">

View file

@ -7329,11 +7329,6 @@ It can happen because of some bug or when the connection is compromised.</source
<target>Старата база данни не бе премахната по време на миграцията, тя може да бъде изтрита.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Профилът се споделя само с вашите контакти.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<note>No comment provided by engineer.</note>
@ -8577,6 +8572,11 @@ Repeat connection request?</source>
<target>Вашият профил **%@** ще бъде споделен.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Профилът се споделя само с вашите контакти.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Вашият профил се съхранява на вашето устройство и се споделя само с вашите контакти. SimpleX сървърите не могат да видят вашия профил.</target>
@ -8586,11 +8586,6 @@ Repeat connection request?</source>
<source>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Вашият профил, контакти и доставени съобщения се съхраняват на вашето устройство.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Вашият автоматично генериран профил</target>

View file

@ -3422,8 +3422,8 @@ It can happen because of some bug or when the connection is compromised.</source
<source>The old database was not removed during the migration, it can be deleted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The sender will NOT be notified" xml:space="preserve">

View file

@ -1942,6 +1942,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create profile" xml:space="preserve">
<source>Create profile</source>
<target>Vytvořte si profil</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create queue" xml:space="preserve">
@ -7080,11 +7081,6 @@ Může se to stát kvůli nějaké chybě, nebo pokud je spojení kompromitován
<target>Stará databáze nebyla během přenášení odstraněna, lze ji smazat.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Profil je sdílen pouze s vašimi kontakty.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<note>No comment provided by engineer.</note>
@ -8271,6 +8267,11 @@ Repeat connection request?</source>
<target>Váš profil **%@** bude sdílen.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Profil je sdílen pouze s vašimi kontakty.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Váš profil je uložen ve vašem zařízení a sdílen pouze s vašimi kontakty. Servery SimpleX nevidí váš profil.</target>
@ -8280,11 +8281,6 @@ Repeat connection request?</source>
<source>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Váš profil, kontakty a doručené zprávy jsou uloženy ve vašem zařízení.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Váš náhodný profil</target>

View file

@ -7763,11 +7763,6 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro
<target>Die alte Datenbank wurde während der Migration nicht entfernt. Sie kann gelöscht werden.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Das Profil wird nur mit Ihren Kontakten geteilt.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<target>Dieselben Nutzungsbedingungen gelten auch für den Betreiber **%@**.</target>
@ -9081,6 +9076,11 @@ Verbindungsanfrage wiederholen?</target>
<target>Ihr Profil **%@** wird geteilt.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Das Profil wird nur mit Ihren Kontakten geteilt.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Ihr Profil wird auf Ihrem Gerät gespeichert und nur mit Ihren Kontakten geteilt. SimpleX-Server können Ihr Profil nicht einsehen.</target>
@ -9091,11 +9091,6 @@ Verbindungsanfrage wiederholen?</target>
<target>Ihr Profil wurde geändert. Wenn Sie es speichern, wird das aktualisierte Profil an alle Ihre Kontakte gesendet.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Ihr Profil, Ihre Kontakte und zugestellten Nachrichten werden auf Ihrem Gerät gespeichert.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Ihr Zufallsprofil</target>

View file

@ -3043,8 +3043,8 @@ It can happen because of some bug or when the connection is compromised.</source
<source>The old database was not removed during the migration, it can be deleted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The sender will NOT be notified" xml:space="preserve">

View file

@ -7764,11 +7764,6 @@ It can happen because of some bug or when the connection is compromised.</target
<target>The old database was not removed during the migration, it can be deleted.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>The profile is only shared with your contacts.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<target>The same conditions will apply to operator **%@**.</target>
@ -9082,6 +9077,11 @@ Repeat connection request?</target>
<target>Your profile **%@** will be shared.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Your profile is stored on your device and only shared with your contacts.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</target>
@ -9092,11 +9092,6 @@ Repeat connection request?</target>
<target>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Your profile, contacts and delivered messages are stored on your device.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Your random profile</target>

View file

@ -7763,11 +7763,6 @@ Puede ocurrir por algún bug o cuando la conexión está comprometida.</target>
<target>La base de datos antigua no se eliminó durante la migración, puede eliminarse.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>El perfil sólo se comparte con tus contactos.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<target>Las mismas condiciones se aplicarán al operador **%@**.</target>
@ -9081,6 +9076,11 @@ Repeat connection request?</source>
<target>El perfil **%@** será compartido.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>El perfil sólo se comparte con tus contactos.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Tu perfil es almacenado en tu dispositivo y solamente se comparte con tus contactos. Los servidores SimpleX no pueden ver tu perfil.</target>
@ -9091,11 +9091,6 @@ Repeat connection request?</source>
<target>Tu perfil ha sido modificado. Si lo guardas la actualización será enviada a todos tus contactos.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Tu perfil, contactos y mensajes se almacenan en tu dispositivo.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Tu perfil aleatorio</target>

View file

@ -1923,6 +1923,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create profile" xml:space="preserve">
<source>Create profile</source>
<target>Luo profiilisi</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create queue" xml:space="preserve">
@ -7054,11 +7055,6 @@ Tämä voi johtua jostain virheestä tai siitä, että yhteys on vaarantunut.</t
<target>Vanhaa tietokantaa ei poistettu siirron aikana, se voidaan kuitenkin poistaa.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Profiili jaetaan vain kontaktiesi kanssa.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<note>No comment provided by engineer.</note>
@ -8244,6 +8240,11 @@ Repeat connection request?</source>
<target>Profiilisi **%@** jaetaan.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Profiili jaetaan vain kontaktiesi kanssa.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Profiilisi tallennetaan laitteeseesi ja jaetaan vain yhteystietojesi kanssa. SimpleX-palvelimet eivät näe profiiliasi.</target>
@ -8253,11 +8254,6 @@ Repeat connection request?</source>
<source>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Profiilisi, kontaktisi ja toimitetut viestit tallennetaan laitteellesi.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Satunnainen profiilisi</target>

View file

@ -7696,11 +7696,6 @@ Cela peut se produire en raison d'un bug ou lorsque la connexion est compromise.
<target>L'ancienne base de données n'a pas été supprimée lors de la migration, elle peut être supprimée.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Le profil n'est partagé qu'avec vos contacts.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<target>Les mêmes conditions s'appliquent à l'opérateur **%@**.</target>
@ -9003,6 +8998,11 @@ Répéter la demande de connexion ?</target>
<target>Votre profil **%@** sera partagé.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Le profil n'est partagé qu'avec vos contacts.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Votre profil est stocké sur votre appareil et est seulement partagé avec vos contacts. Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
@ -9013,11 +9013,6 @@ Répéter la demande de connexion ?</target>
<target>Votre profil a été modifié. Si vous l'enregistrez, le profil mis à jour sera envoyé à tous vos contacts.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Votre profil, vos contacts et les messages reçus sont stockés sur votre appareil.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Votre profil aléatoire</target>

View file

@ -3569,8 +3569,8 @@ It can happen because of some bug or when the connection is compromised.</source
<source>The old database was not removed during the migration, it can be deleted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The sender will NOT be notified" xml:space="preserve">

View file

@ -2619,8 +2619,8 @@ We will be adding server redundancy to prevent lost messages.</source>
<source>The old database was not removed during the migration, it can be deleted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The sender will NOT be notified" xml:space="preserve">

View file

@ -7763,11 +7763,6 @@ Ez valamilyen hiba vagy sérült kapcsolat esetén fordulhat elő.</target>
<target>A régi adatbázis nem lett eltávolítva az átköltöztetéskor, ezért törölhető.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>A profilja csak a partnereivel van megosztva.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<target>Ugyanezek a feltételek lesznek elfogadva a következő üzemeltető számára is: **%@**.</target>
@ -9081,6 +9076,11 @@ Megismétli a meghívási kérést?</target>
<target>A(z) **%@** nevű profilja meg lesz osztva.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>A profilja csak a partnereivel van megosztva.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>A profilja az eszközén van tárolva és csak a partnereivel van megosztva. A SimpleX-kiszolgálók nem láthatják a profilját.</target>
@ -9091,11 +9091,6 @@ Megismétli a meghívási kérést?</target>
<target>A profilja módosult. Ha elmenti, a profilfrissítés el lesz küldve a partnerei számára.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>A profilja, a partnerei és az elküldött üzenetei a saját eszközén vannak tárolva.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Véletlenszerű profil</target>

View file

@ -7763,11 +7763,6 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.</ta
<target>Il database vecchio non è stato rimosso durante la migrazione, può essere eliminato.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Il profilo è condiviso solo con i tuoi contatti.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<target>Le stesse condizioni si applicheranno all'operatore **%@**.</target>
@ -9081,6 +9076,11 @@ Ripetere la richiesta di connessione?</target>
<target>Verrà condiviso il tuo profilo **%@**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Il profilo è condiviso solo con i tuoi contatti.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Il tuo profilo è memorizzato sul tuo dispositivo e condiviso solo con i tuoi contatti. I server di SimpleX non possono vedere il tuo profilo.</target>
@ -9091,11 +9091,6 @@ Ripetere la richiesta di connessione?</target>
<target>Il tuo profilo è stato cambiato. Se lo salvi, il profilo aggiornato verrà inviato a tutti i tuoi contatti.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Il tuo profilo, i contatti e i messaggi recapitati sono memorizzati sul tuo dispositivo.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Il tuo profilo casuale</target>

View file

@ -1990,6 +1990,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create profile" xml:space="preserve">
<source>Create profile</source>
<target>プロフィールを作成する</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create queue" xml:space="preserve">
@ -7125,11 +7126,6 @@ It can happen because of some bug or when the connection is compromised.</source
<target>古いデータベースは移行時に削除されなかったので、削除することができます。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>プロフィールは連絡先にしか共有されません。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<note>No comment provided by engineer.</note>
@ -8315,6 +8311,11 @@ Repeat connection request?</source>
<target>あなたのプロファイル **%@** が共有されます。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>プロフィールは連絡先にしか共有されません。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>プロフィールはデバイスに保存され、連絡先とのみ共有されます。 SimpleX サーバーはあなたのプロファイルを参照できません。</target>
@ -8324,11 +8325,6 @@ Repeat connection request?</source>
<source>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>あなたのプロフィール、連絡先、送信したメッセージがご自分の端末に保存されます。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>あなたのランダム・プロフィール</target>

View file

@ -2867,8 +2867,8 @@ We will be adding server redundancy to prevent lost messages.</source>
<source>The old database was not removed during the migration, it can be deleted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The sender will NOT be notified" xml:space="preserve">

View file

@ -2631,8 +2631,8 @@ We will be adding server redundancy to prevent lost messages.</source>
<source>The old database was not removed during the migration, it can be deleted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The sender will NOT be notified" xml:space="preserve">

View file

@ -7760,11 +7760,6 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast.</target>
<target>De oude database is niet verwijderd tijdens de migratie, deze kan worden verwijderd.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Het profiel wordt alleen gedeeld met uw contacten.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<target>Dezelfde voorwaarden gelden voor operator **%@**.</target>
@ -9074,6 +9069,11 @@ Verbindingsverzoek herhalen?</target>
<target>Uw profiel **%@** wordt gedeeld.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Het profiel wordt alleen gedeeld met uw contacten.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Uw profiel wordt op uw apparaat opgeslagen en alleen gedeeld met uw contacten. SimpleX servers kunnen uw profiel niet zien.</target>
@ -9084,11 +9084,6 @@ Verbindingsverzoek herhalen?</target>
<target>Je profiel is gewijzigd. Als je het opslaat, wordt het bijgewerkte profiel naar al je contacten verzonden.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Uw profiel, contacten en afgeleverde berichten worden op uw apparaat opgeslagen.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Je willekeurige profiel</target>

View file

@ -7583,11 +7583,6 @@ Może się to zdarzyć z powodu jakiegoś błędu lub gdy połączenie jest skom
<target>Stara baza danych nie została usunięta podczas migracji, można ją usunąć.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Profil jest udostępniany tylko Twoim kontaktom.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<note>No comment provided by engineer.</note>
@ -8870,6 +8865,11 @@ Powtórzyć prośbę połączenia?</target>
<target>Twój profil **%@** zostanie udostępniony.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Profil jest udostępniany tylko Twoim kontaktom.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Twój profil jest przechowywany na urządzeniu i udostępniany tylko Twoim kontaktom. Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
@ -8880,11 +8880,6 @@ Powtórzyć prośbę połączenia?</target>
<target>Twój profil został zmieniony. Jeśli go zapiszesz, zaktualizowany profil zostanie wysłany do wszystkich kontaktów.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Twój profil, kontakty i dostarczone wiadomości są przechowywane na Twoim urządzeniu.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Twój losowy profil</target>

View file

@ -3002,8 +3002,8 @@ We will be adding server redundancy to prevent lost messages.</source>
<source>The old database was not removed during the migration, it can be deleted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve" approved="no">
<source>The profile is only shared with your contacts.</source>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve" approved="no">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target state="translated">O perfil é compartilhado apenas com seus contatos.</target>
<note>No comment provided by engineer.</note>
</trans-unit>

View file

@ -3146,8 +3146,8 @@ It can happen because of some bug or when the connection is compromised.</source
<source>The old database was not removed during the migration, it can be deleted.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The sender will NOT be notified" xml:space="preserve">

View file

@ -7715,11 +7715,6 @@ It can happen because of some bug or when the connection is compromised.</source
<target>Предыдущая версия данных чата не удалена при перемещении, её можно удалить.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Профиль отправляется только Вашим контактам.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<target>Те же самые условия будут приняты для оператора **%@**.</target>
@ -9021,6 +9016,11 @@ Repeat connection request?</source>
<target>Будет отправлен Ваш профиль **%@**.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Ваш профиль храниться на Вашем устройстве и отправляется только контактам.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Ваш профиль хранится на Вашем устройстве и отправляется только Вашим контактам. SimpleX серверы не могут получить доступ к Вашему профилю.</target>
@ -9031,11 +9031,6 @@ Repeat connection request?</source>
<target>Ваш профиль был изменен. Если вы сохраните его, обновленный профиль будет отправлен всем вашим контактам.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Ваш профиль, контакты и доставленные сообщения хранятся на Вашем устройстве.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Случайный профиль</target>

View file

@ -7028,11 +7028,6 @@ It can happen because of some bug or when the connection is compromised.</source
<target>ฐานข้อมูลเก่าไม่ได้ถูกลบในระหว่างการย้ายข้อมูล แต่สามารถลบได้</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>โปรไฟล์นี้แชร์กับผู้ติดต่อของคุณเท่านั้น</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<note>No comment provided by engineer.</note>
@ -8212,6 +8207,11 @@ Repeat connection request?</source>
<source>Your profile **%@** will be shared.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>โปรไฟล์นี้แชร์กับผู้ติดต่อของคุณเท่านั้น</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>โปรไฟล์ของคุณจะถูกจัดเก็บไว้ในอุปกรณ์ของคุณและแชร์กับผู้ติดต่อของคุณเท่านั้น เซิร์ฟเวอร์ SimpleX ไม่สามารถดูโปรไฟล์ของคุณได้</target>
@ -8221,11 +8221,6 @@ Repeat connection request?</source>
<source>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>โปรไฟล์ รายชื่อผู้ติดต่อ และข้อความที่ส่งของคุณจะถูกจัดเก็บไว้ในอุปกรณ์ของคุณ</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>โปรไฟล์แบบสุ่มของคุณ</target>

View file

@ -7599,11 +7599,6 @@ Bazı hatalar nedeniyle veya bağlantı tehlikeye girdiğinde meydana gelebilir.
<target>Eski veritabanı geçiş sırasında kaldırılmadı, silinebilir.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Profil sadece kişilerinle paylaşılacak.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<note>No comment provided by engineer.</note>
@ -8886,6 +8881,11 @@ Bağlantı isteği tekrarlansın mı?</target>
<target>Profiliniz **%@** paylaşılacaktır.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Profil sadece kişilerinle paylaşılacak.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Profiliniz cihazınızda saklanır ve sadece kişilerinizle paylaşılır. SimpleX sunucuları profilinizi göremez.</target>
@ -8896,11 +8896,6 @@ Bağlantı isteği tekrarlansın mı?</target>
<target>Profiliniz değiştirildi. Kaydederseniz, güncellenmiş profil tüm kişilerinize gönderilecektir.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Profiliniz, kişileriniz ve gönderilmiş mesajlar cihazınızda saklanır.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Rasgele profiliniz</target>

View file

@ -7638,11 +7638,6 @@ It can happen because of some bug or when the connection is compromised.</source
<target>Стара база даних не була видалена під час міграції, її можна видалити.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>Профіль доступний лише вашим контактам.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<target>Такі ж умови діятимуть і для оператора **%@**.</target>
@ -8945,6 +8940,11 @@ Repeat connection request?</source>
<target>Ваш профіль **%@** буде опублікований.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>Профіль доступний лише вашим контактам.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>Ваш профіль зберігається на вашому пристрої і доступний лише вашим контактам. Сервери SimpleX не бачать ваш профіль.</target>
@ -8955,11 +8955,6 @@ Repeat connection request?</source>
<target>Ваш профіль було змінено. Якщо ви збережете його, оновлений профіль буде надіслано всім вашим контактам.</target>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>Ваш профіль, контакти та доставлені повідомлення зберігаються на вашому пристрої.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>Ваш випадковий профіль</target>

View file

@ -7708,11 +7708,6 @@ It can happen because of some bug or when the connection is compromised.</source
<target>旧数据库在迁移过程中没有被移除,可以删除。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
<source>The profile is only shared with your contacts.</source>
<target>该资料仅与您的联系人共享。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The same conditions will apply to operator **%@**." xml:space="preserve">
<source>The same conditions will apply to operator **%@**.</source>
<note>No comment provided by engineer.</note>
@ -8987,6 +8982,11 @@ Repeat connection request?</source>
<target>您的个人资料 **%@** 将被共享。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target>该资料仅与您的联系人共享。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." xml:space="preserve">
<source>Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile.</source>
<target>您的资料存储在您的设备上并仅与您的联系人共享。 SimpleX 服务器无法看到您的资料。</target>
@ -8996,11 +8996,6 @@ Repeat connection request?</source>
<source>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</source>
<note>alert message</note>
</trans-unit>
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
<source>Your profile, contacts and delivered messages are stored on your device.</source>
<target>您的资料、联系人和发送的消息存储在您的设备上。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your random profile" xml:space="preserve">
<source>Your random profile</source>
<target>您的随机资料</target>

View file

@ -3054,8 +3054,8 @@ We will be adding server redundancy to prevent lost messages.</source>
<target state="translated">舊的數據庫在遷移過程中沒有被移除,可以刪除。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve" approved="no">
<source>The profile is only shared with your contacts.</source>
<trans-unit id="Your profile is stored on your device and only shared with your contacts." xml:space="preserve" approved="no">
<source>Your profile is stored on your device and only shared with your contacts.</source>
<target state="translated">你的個人檔案只會和你的聯絡人分享。</target>
<note>No comment provided by engineer.</note>
</trans-unit>

View file

@ -174,8 +174,8 @@
64C3B0212A0D359700E19930 /* CustomTimePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C3B0202A0D359700E19930 /* CustomTimePicker.swift */; };
64C8299D2D54AEEE006B9E89 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C829982D54AEED006B9E89 /* libgmp.a */; };
64C8299E2D54AEEE006B9E89 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C829992D54AEEE006B9E89 /* libffi.a */; };
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO-ghc9.6.3.a */; };
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO.a */; };
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss-ghc9.6.3.a */; };
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss.a */; };
64C829A12D54AEEE006B9E89 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299C2D54AEEE006B9E89 /* libgmpxx.a */; };
64D0C2C029F9688300B38D5F /* UserAddressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2BF29F9688300B38D5F /* UserAddressView.swift */; };
64D0C2C229FA57AB00B38D5F /* UserAddressLearnMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2C129FA57AB00B38D5F /* UserAddressLearnMore.swift */; };
@ -533,8 +533,8 @@
64C3B0202A0D359700E19930 /* CustomTimePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTimePicker.swift; sourceTree = "<group>"; };
64C829982D54AEED006B9E89 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
64C829992D54AEEE006B9E89 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO-ghc9.6.3.a"; sourceTree = "<group>"; };
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO.a"; sourceTree = "<group>"; };
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss-ghc9.6.3.a"; sourceTree = "<group>"; };
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss.a"; sourceTree = "<group>"; };
64C8299C2D54AEEE006B9E89 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
64D0C2BF29F9688300B38D5F /* UserAddressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAddressView.swift; sourceTree = "<group>"; };
64D0C2C129FA57AB00B38D5F /* UserAddressLearnMore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAddressLearnMore.swift; sourceTree = "<group>"; };
@ -692,8 +692,8 @@
64C8299D2D54AEEE006B9E89 /* libgmp.a in Frameworks */,
64C8299E2D54AEEE006B9E89 /* libffi.a in Frameworks */,
64C829A12D54AEEE006B9E89 /* libgmpxx.a in Frameworks */,
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO-ghc9.6.3.a in Frameworks */,
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO.a in Frameworks */,
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss-ghc9.6.3.a in Frameworks */,
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss.a in Frameworks */,
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -778,8 +778,8 @@
64C829992D54AEEE006B9E89 /* libffi.a */,
64C829982D54AEED006B9E89 /* libgmp.a */,
64C8299C2D54AEEE006B9E89 /* libgmpxx.a */,
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO-ghc9.6.3.a */,
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.4.1-Cm6JGiMgJjo4088oWn41JO.a */,
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss-ghc9.6.3.a */,
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.6.0-64eNxtIoLF9BaOhAoPagss.a */,
);
path = Libraries;
sourceTree = "<group>";
@ -1971,7 +1971,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 277;
CURRENT_PROJECT_VERSION = 282;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
@ -1996,7 +1996,7 @@
"@executable_path/Frameworks",
);
LLVM_LTO = YES_THIN;
MARKETING_VERSION = 6.3.4;
MARKETING_VERSION = 6.3.6;
OTHER_LDFLAGS = "-Wl,-stack_size,0x1000000";
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX;
@ -2021,7 +2021,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 277;
CURRENT_PROJECT_VERSION = 282;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
@ -2046,7 +2046,7 @@
"@executable_path/Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.3.4;
MARKETING_VERSION = 6.3.6;
OTHER_LDFLAGS = "-Wl,-stack_size,0x1000000";
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX;
@ -2063,11 +2063,11 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 277;
CURRENT_PROJECT_VERSION = 282;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 6.3.4;
MARKETING_VERSION = 6.3.6;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@ -2083,11 +2083,11 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 277;
CURRENT_PROJECT_VERSION = 282;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 6.3.4;
MARKETING_VERSION = 6.3.6;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@ -2108,7 +2108,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 277;
CURRENT_PROJECT_VERSION = 282;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = s;
@ -2123,7 +2123,7 @@
"@executable_path/../../Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.3.4;
MARKETING_VERSION = 6.3.6;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -2145,7 +2145,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 277;
CURRENT_PROJECT_VERSION = 282;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_CODE_COVERAGE = NO;
@ -2160,7 +2160,7 @@
"@executable_path/../../Frameworks",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.3.4;
MARKETING_VERSION = 6.3.6;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -2182,7 +2182,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 277;
CURRENT_PROJECT_VERSION = 282;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@ -2208,7 +2208,7 @@
"$(PROJECT_DIR)/Libraries/sim",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.3.4;
MARKETING_VERSION = 6.3.6;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
@ -2233,7 +2233,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 277;
CURRENT_PROJECT_VERSION = 282;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@ -2259,7 +2259,7 @@
"$(PROJECT_DIR)/Libraries/sim",
);
LLVM_LTO = YES;
MARKETING_VERSION = 6.3.4;
MARKETING_VERSION = 6.3.6;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
@ -2284,7 +2284,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 277;
CURRENT_PROJECT_VERSION = 282;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
@ -2299,7 +2299,7 @@
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.3.4;
MARKETING_VERSION = 6.3.6;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@ -2318,7 +2318,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 277;
CURRENT_PROJECT_VERSION = 282;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
@ -2333,7 +2333,7 @@
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.3.4;
MARKETING_VERSION = 6.3.6;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;

View file

@ -1333,6 +1333,19 @@ public enum ChatInfo: Identifiable, Decodable, NamedChat, Hashable {
}
}
public var userCantSendReason: (composeLabel: LocalizedStringKey, alertMessage: LocalizedStringKey?)? {
get {
switch self {
case let .direct(contact): return contact.userCantSendReason
case let .group(groupInfo): return groupInfo.userCantSendReason
case let .local(noteFolder): return noteFolder.userCantSendReason
case let .contactRequest(contactRequest): return contactRequest.userCantSendReason
case let .contactConnection(contactConnection): return contactConnection.userCantSendReason
case .invalidJSON: return ("can't send messages", nil)
}
}
}
public var sendMsgEnabled: Bool {
get {
switch self {
@ -1642,15 +1655,16 @@ public struct Contact: Identifiable, Decodable, NamedChat, Hashable {
public var ready: Bool { get { activeConn?.connStatus == .ready } }
public var sndReady: Bool { get { ready || activeConn?.connStatus == .sndReady } }
public var active: Bool { get { contactStatus == .active } }
public var sendMsgEnabled: Bool { get {
(
sndReady
&& active
&& !(activeConn?.connectionStats?.ratchetSyncSendProhibited ?? false)
&& !(activeConn?.connDisabled ?? true)
)
|| nextSendGrpInv
} }
public var userCantSendReason: (composeLabel: LocalizedStringKey, alertMessage: LocalizedStringKey?)? {
// TODO [short links] this will have additional statuses for pending contact requests before they are accepted
if nextSendGrpInv { return nil }
if !active { return ("contact deleted", nil) }
if !sndReady { return ("contact not ready", nil) }
if activeConn?.connectionStats?.ratchetSyncSendProhibited ?? false { return ("not synchronized", nil) }
if activeConn?.connDisabled ?? true { return ("contact disabled", nil) }
return nil
}
public var sendMsgEnabled: Bool { userCantSendReason == nil }
public var nextSendGrpInv: Bool { get { contactGroupMemberId != nil && !contactGrpInvSent } }
public var displayName: String { localAlias == "" ? profile.displayName : localAlias }
public var fullName: String { get { profile.fullName } }
@ -1829,6 +1843,7 @@ public struct UserContactRequest: Decodable, NamedChat, Hashable {
public var id: ChatId { get { "<@\(contactRequestId)" } }
public var apiId: Int64 { get { contactRequestId } }
var ready: Bool { get { true } }
public var userCantSendReason: (composeLabel: LocalizedStringKey, alertMessage: LocalizedStringKey?)? { ("can't send messages", nil) }
public var sendMsgEnabled: Bool { get { false } }
public var displayName: String { get { profile.displayName } }
public var fullName: String { get { profile.fullName } }
@ -1861,6 +1876,7 @@ public struct PendingContactConnection: Decodable, NamedChat, Hashable {
public var id: ChatId { get { ":\(pccConnId)" } }
public var apiId: Int64 { get { pccConnId } }
var ready: Bool { get { false } }
public var userCantSendReason: (composeLabel: LocalizedStringKey, alertMessage: LocalizedStringKey?)? { ("can't send messages", nil) }
public var sendMsgEnabled: Bool { get { false } }
var localDisplayName: String {
get { String.localizedStringWithFormat(NSLocalizedString("connection:%@", comment: "connection information"), pccConnId) }
@ -1990,7 +2006,20 @@ public struct GroupInfo: Identifiable, Decodable, NamedChat, Hashable {
public var id: ChatId { get { "#\(groupId)" } }
public var apiId: Int64 { get { groupId } }
public var ready: Bool { get { true } }
public var sendMsgEnabled: Bool { get { membership.memberActive } }
public var userCantSendReason: (composeLabel: LocalizedStringKey, alertMessage: LocalizedStringKey?)? {
return if membership.memberActive {
membership.memberRole == .observer ? ("you are observer", "Please contact group admin.") : nil
} else {
switch membership.memberStatus {
case .memRejected: ("request to join rejected", nil)
case .memGroupDeleted: ("group is deleted", nil)
case .memRemoved: ("removed from group", nil)
case .memLeft: ("you left", nil)
default: ("can't send messages", nil)
}
}
}
public var sendMsgEnabled: Bool { userCantSendReason == nil }
public var displayName: String { localAlias == "" ? groupProfile.displayName : localAlias }
public var fullName: String { get { groupProfile.fullName } }
public var image: String? { get { groupProfile.image } }
@ -2357,6 +2386,7 @@ public struct NoteFolder: Identifiable, Decodable, NamedChat, Hashable {
public var id: ChatId { get { "*\(noteFolderId)" } }
public var apiId: Int64 { get { noteFolderId } }
public var ready: Bool { get { true } }
public var userCantSendReason: (composeLabel: LocalizedStringKey, alertMessage: LocalizedStringKey?)? { nil }
public var sendMsgEnabled: Bool { get { true } }
public var displayName: String { get { ChatInfo.privateNotesChatName } }
public var fullName: String { get { "" } }

View file

@ -3777,7 +3777,7 @@ chat item action */
"The old database was not removed during the migration, it can be deleted." = "Старата база данни не бе премахната по време на миграцията, тя може да бъде изтрита.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Профилът се споделя само с вашите контакти.";
"Your profile is stored on your device and only shared with your contacts." = "Профилът се споделя само с вашите контакти.";
/* No comment provided by engineer. */
"The second tick we missed! ✅" = "Втората отметка, която пропуснахме! ✅";

View file

@ -822,6 +822,9 @@ set passcode view */
/* No comment provided by engineer. */
"Create new profile in [desktop app](https://simplex.chat/downloads/). 💻" = "Vytvořit nový profil v [desktop app](https://simplex.chat/downloads/). 💻";
/* No comment provided by engineer. */
"Create profile" = "Vytvořte si profil";
/* server test step */
"Create queue" = "Vytvořit frontu";
@ -2986,7 +2989,7 @@ chat item action */
"The old database was not removed during the migration, it can be deleted." = "Stará databáze nebyla během přenášení odstraněna, lze ji smazat.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Profil je sdílen pouze s vašimi kontakty.";
"Your profile is stored on your device and only shared with your contacts." = "Profil je sdílen pouze s vašimi kontakty.";
/* No comment provided by engineer. */
"The second tick we missed! ✅" = "Druhé zaškrtnutí jsme přehlédli! ✅";

View file

@ -5101,7 +5101,7 @@ report reason */
"The old database was not removed during the migration, it can be deleted." = "Die alte Datenbank wurde während der Migration nicht entfernt. Sie kann gelöscht werden.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Das Profil wird nur mit Ihren Kontakten geteilt.";
"Your profile is stored on your device and only shared with your contacts." = "Das Profil wird nur mit Ihren Kontakten geteilt.";
/* No comment provided by engineer. */
"The same conditions will apply to operator **%@**." = "Dieselben Nutzungsbedingungen gelten auch für den Betreiber **%@**.";

View file

@ -5101,7 +5101,7 @@ report reason */
"The old database was not removed during the migration, it can be deleted." = "La base de datos antigua no se eliminó durante la migración, puede eliminarse.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "El perfil sólo se comparte con tus contactos.";
"Your profile is stored on your device and only shared with your contacts." = "El perfil sólo se comparte con tus contactos.";
/* No comment provided by engineer. */
"The same conditions will apply to operator **%@**." = "Las mismas condiciones se aplicarán al operador **%@**.";

View file

@ -768,6 +768,9 @@ set passcode view */
/* No comment provided by engineer. */
"Create new profile in [desktop app](https://simplex.chat/downloads/). 💻" = "Luo uusi profiili [työpöytäsovelluksessa](https://simplex.chat/downloads/). 💻";
/* No comment provided by engineer. */
"Create profile" = "Luo profiilisi";
/* server test step */
"Create queue" = "Luo jono";
@ -2908,7 +2911,7 @@ chat item action */
"The old database was not removed during the migration, it can be deleted." = "Vanhaa tietokantaa ei poistettu siirron aikana, se voidaan kuitenkin poistaa.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Profiili jaetaan vain kontaktiesi kanssa.";
"Your profile is stored on your device and only shared with your contacts." = "Profiili jaetaan vain kontaktiesi kanssa.";
/* No comment provided by engineer. */
"The second tick we missed! ✅" = "Toinen kuittaus, joka uupui! ✅";

View file

@ -4884,7 +4884,7 @@ chat item action */
"The old database was not removed during the migration, it can be deleted." = "L'ancienne base de données n'a pas été supprimée lors de la migration, elle peut être supprimée.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Le profil n'est partagé qu'avec vos contacts.";
"Your profile is stored on your device and only shared with your contacts." = "Le profil n'est partagé qu'avec vos contacts.";
/* No comment provided by engineer. */
"The same conditions will apply to operator **%@**." = "Les mêmes conditions s'appliquent à l'opérateur **%@**.";

View file

@ -5101,7 +5101,7 @@ report reason */
"The old database was not removed during the migration, it can be deleted." = "A régi adatbázis nem lett eltávolítva az átköltöztetéskor, ezért törölhető.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "A profilja csak a partnereivel van megosztva.";
"Your profile is stored on your device and only shared with your contacts." = "A profilja csak a partnereivel van megosztva.";
/* No comment provided by engineer. */
"The same conditions will apply to operator **%@**." = "Ugyanezek a feltételek lesznek elfogadva a következő üzemeltető számára is: **%@**.";

View file

@ -5101,7 +5101,7 @@ report reason */
"The old database was not removed during the migration, it can be deleted." = "Il database vecchio non è stato rimosso durante la migrazione, può essere eliminato.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Il profilo è condiviso solo con i tuoi contatti.";
"Your profile is stored on your device and only shared with your contacts." = "Il profilo è condiviso solo con i tuoi contatti.";
/* No comment provided by engineer. */
"The same conditions will apply to operator **%@**." = "Le stesse condizioni si applicheranno all'operatore **%@**.";

View file

@ -957,6 +957,9 @@ set passcode view */
/* No comment provided by engineer. */
"Create new profile in [desktop app](https://simplex.chat/downloads/). 💻" = "[デスクトップアプリ](https://simplex.chat/downloads/)で新しいプロファイルを作成します。 💻";
/* No comment provided by engineer. */
"Create profile" = "プロフィールを作成する";
/* server test step */
"Create queue" = "キューの作成";
@ -3109,7 +3112,7 @@ chat item action */
"The old database was not removed during the migration, it can be deleted." = "古いデータベースは移行時に削除されなかったので、削除することができます。";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "プロフィールは連絡先にしか共有されません。";
"Your profile is stored on your device and only shared with your contacts." = "プロフィールは連絡先にしか共有されません。";
/* No comment provided by engineer. */
"The second tick we missed! ✅" = "長らくお待たせしました! ✅";

View file

@ -5092,7 +5092,7 @@ report reason */
"The old database was not removed during the migration, it can be deleted." = "De oude database is niet verwijderd tijdens de migratie, deze kan worden verwijderd.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Het profiel wordt alleen gedeeld met uw contacten.";
"Your profile is stored on your device and only shared with your contacts." = "Het profiel wordt alleen gedeeld met uw contacten.";
/* No comment provided by engineer. */
"The same conditions will apply to operator **%@**." = "Dezelfde voorwaarden gelden voor operator **%@**.";

View file

@ -4557,7 +4557,7 @@ chat item action */
"The old database was not removed during the migration, it can be deleted." = "Stara baza danych nie została usunięta podczas migracji, można ją usunąć.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Profil jest udostępniany tylko Twoim kontaktom.";
"Your profile is stored on your device and only shared with your contacts." = "Profil jest udostępniany tylko Twoim kontaktom.";
/* No comment provided by engineer. */
"The second tick we missed! ✅" = "Drugi tik, który przegapiliśmy! ✅";

View file

@ -4957,7 +4957,7 @@ report reason */
"The old database was not removed during the migration, it can be deleted." = "Предыдущая версия данных чата не удалена при перемещении, её можно удалить.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Профиль отправляется только Вашим контактам.";
"Your profile is stored on your device and only shared with your contacts." = "Ваш профиль храниться на Вашем устройстве и отправляется только контактам.";
/* No comment provided by engineer. */
"The same conditions will apply to operator **%@**." = "Те же самые условия будут приняты для оператора **%@**.";

View file

@ -2830,7 +2830,7 @@ chat item action */
"The old database was not removed during the migration, it can be deleted." = "ฐานข้อมูลเก่าไม่ได้ถูกลบในระหว่างการย้ายข้อมูล แต่สามารถลบได้";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "โปรไฟล์นี้แชร์กับผู้ติดต่อของคุณเท่านั้น";
"Your profile is stored on your device and only shared with your contacts." = "โปรไฟล์นี้แชร์กับผู้ติดต่อของคุณเท่านั้น";
/* No comment provided by engineer. */
"The second tick we missed! ✅" = "ขีดที่สองที่เราพลาด! ✅";

View file

@ -4602,7 +4602,7 @@ chat item action */
"The old database was not removed during the migration, it can be deleted." = "Eski veritabanı geçiş sırasında kaldırılmadı, silinebilir.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Profil sadece kişilerinle paylaşılacak.";
"Your profile is stored on your device and only shared with your contacts." = "Profil sadece kişilerinle paylaşılacak.";
/* No comment provided by engineer. */
"The second tick we missed! ✅" = "Özlediğimiz ikinci tik! ✅";

View file

@ -4722,7 +4722,7 @@ chat item action */
"The old database was not removed during the migration, it can be deleted." = "Стара база даних не була видалена під час міграції, її можна видалити.";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "Профіль доступний лише вашим контактам.";
"Your profile is stored on your device and only shared with your contacts." = "Профіль доступний лише вашим контактам.";
/* No comment provided by engineer. */
"The same conditions will apply to operator **%@**." = "Такі ж умови діятимуть і для оператора **%@**.";

View file

@ -4923,7 +4923,7 @@ chat item action */
"The old database was not removed during the migration, it can be deleted." = "旧数据库在迁移过程中没有被移除,可以删除。";
/* No comment provided by engineer. */
"The profile is only shared with your contacts." = "该资料仅与您的联系人共享。";
"Your profile is stored on your device and only shared with your contacts." = "该资料仅与您的联系人共享。";
/* No comment provided by engineer. */
"The second tick we missed! ✅" = "我们错过的第二个\"√\"!✅";

View file

@ -155,6 +155,7 @@ buildConfig {
buildConfigField("String", "DESKTOP_VERSION_NAME", "\"${extra["desktop.version_name"]}\"")
buildConfigField("int", "DESKTOP_VERSION_CODE", "${extra["desktop.version_code"]}")
buildConfigField("String", "DATABASE_BACKEND", "\"${extra["database.backend"]}\"")
buildConfigField("Boolean", "ANDROID_BUNDLE", "${extra["android.bundle"]}")
}
}

View file

@ -42,7 +42,6 @@ import chat.simplex.common.views.helpers.*
import chat.simplex.res.MR
import dev.icerock.moko.resources.StringResource
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter
import java.lang.reflect.Field
import java.net.URI
@ -51,10 +50,10 @@ import java.net.URI
actual fun PlatformTextField(
composeState: MutableState<ComposeState>,
sendMsgEnabled: Boolean,
disabledText: String?,
sendMsgButtonDisabled: Boolean,
textStyle: MutableState<TextStyle>,
showDeleteTextButton: MutableState<Boolean>,
userIsObserver: Boolean,
placeholder: String,
showVoiceButton: Boolean,
onMessageChange: (ComposeMessage) -> Unit,
@ -197,16 +196,16 @@ actual fun PlatformTextField(
showDeleteTextButton.value = it.lineCount >= 4 && !cs.inProgress
}
if (composeState.value.preview is ComposePreview.VoicePreview) {
ComposeOverlay(MR.strings.voice_message_send_text, textStyle, padding)
} else if (userIsObserver) {
ComposeOverlay(MR.strings.you_are_observer, textStyle, padding)
ComposeOverlay(generalGetString(MR.strings.voice_message_send_text), textStyle, padding)
} else if (disabledText != null) {
ComposeOverlay(disabledText, textStyle, padding)
}
}
@Composable
private fun ComposeOverlay(textId: StringResource, textStyle: MutableState<TextStyle>, padding: PaddingValues) {
private fun ComposeOverlay(text: String, textStyle: MutableState<TextStyle>, padding: PaddingValues) {
Text(
generalGetString(textId),
text,
Modifier.padding(padding),
color = MaterialTheme.colors.secondary,
style = textStyle.value.copy(fontStyle = FontStyle.Italic)

View file

@ -1204,6 +1204,7 @@ interface SomeChat {
val apiId: Long
val ready: Boolean
val chatDeleted: Boolean
val userCantSendReason: Pair<String, String?>?
val sendMsgEnabled: Boolean
val incognito: Boolean
fun featureEnabled(feature: ChatFeature): Boolean
@ -1228,14 +1229,6 @@ data class Chat(
else -> false
}
val userIsObserver: Boolean get() = when(chatInfo) {
is ChatInfo.Group -> {
val m = chatInfo.groupInfo.membership
m.memberActive && m.memberRole == GroupMemberRole.Observer
}
else -> false
}
val unreadTag: Boolean get() = when (chatInfo.chatSettings?.enableNtfs) {
All -> chatStats.unreadChat || chatStats.unreadCount > 0
Mentions -> chatStats.unreadChat || chatStats.unreadMentions > 0
@ -1282,6 +1275,7 @@ sealed class ChatInfo: SomeChat, NamedChat {
override val apiId get() = contact.apiId
override val ready get() = contact.ready
override val chatDeleted get() = contact.chatDeleted
override val userCantSendReason get() = contact.userCantSendReason
override val sendMsgEnabled get() = contact.sendMsgEnabled
override val incognito get() = contact.incognito
override fun featureEnabled(feature: ChatFeature) = contact.featureEnabled(feature)
@ -1307,6 +1301,7 @@ sealed class ChatInfo: SomeChat, NamedChat {
override val apiId get() = groupInfo.apiId
override val ready get() = groupInfo.ready
override val chatDeleted get() = groupInfo.chatDeleted
override val userCantSendReason get() = groupInfo.userCantSendReason
override val sendMsgEnabled get() = groupInfo.sendMsgEnabled
override val incognito get() = groupInfo.incognito
override fun featureEnabled(feature: ChatFeature) = groupInfo.featureEnabled(feature)
@ -1331,6 +1326,7 @@ sealed class ChatInfo: SomeChat, NamedChat {
override val apiId get() = noteFolder.apiId
override val ready get() = noteFolder.ready
override val chatDeleted get() = noteFolder.chatDeleted
override val userCantSendReason get() = noteFolder.userCantSendReason
override val sendMsgEnabled get() = noteFolder.sendMsgEnabled
override val incognito get() = noteFolder.incognito
override fun featureEnabled(feature: ChatFeature) = noteFolder.featureEnabled(feature)
@ -1355,6 +1351,7 @@ sealed class ChatInfo: SomeChat, NamedChat {
override val apiId get() = contactRequest.apiId
override val ready get() = contactRequest.ready
override val chatDeleted get() = contactRequest.chatDeleted
override val userCantSendReason get() = contactRequest.userCantSendReason
override val sendMsgEnabled get() = contactRequest.sendMsgEnabled
override val incognito get() = contactRequest.incognito
override fun featureEnabled(feature: ChatFeature) = contactRequest.featureEnabled(feature)
@ -1379,6 +1376,7 @@ sealed class ChatInfo: SomeChat, NamedChat {
override val apiId get() = contactConnection.apiId
override val ready get() = contactConnection.ready
override val chatDeleted get() = contactConnection.chatDeleted
override val userCantSendReason get() = contactConnection.userCantSendReason
override val sendMsgEnabled get() = contactConnection.sendMsgEnabled
override val incognito get() = contactConnection.incognito
override fun featureEnabled(feature: ChatFeature) = contactConnection.featureEnabled(feature)
@ -1408,6 +1406,7 @@ sealed class ChatInfo: SomeChat, NamedChat {
override val id get() = "?$apiId"
override val ready get() = false
override val chatDeleted get() = false
override val userCantSendReason get() = generalGetString(MR.strings.cant_send_message_generic) to null
override val sendMsgEnabled get() = false
override val incognito get() = false
override fun featureEnabled(feature: ChatFeature) = false
@ -1450,14 +1449,6 @@ sealed class ChatInfo: SomeChat, NamedChat {
is InvalidJSON -> updatedAt
}
val userCanSend: Boolean
get() = when (this) {
is ChatInfo.Direct -> true
is ChatInfo.Group -> groupInfo.membership.memberRole >= GroupMemberRole.Member
is ChatInfo.Local -> true
else -> false
}
val chatTags: List<Long>?
get() = when (this) {
is Direct -> contact.chatTags
@ -1528,13 +1519,17 @@ data class Contact(
override val ready get() = activeConn?.connStatus == ConnStatus.Ready
val sndReady get() = ready || activeConn?.connStatus == ConnStatus.SndReady
val active get() = contactStatus == ContactStatus.Active
override val sendMsgEnabled get() = (
sndReady
&& active
&& !(activeConn?.connectionStats?.ratchetSyncSendProhibited ?: false)
&& !(activeConn?.connDisabled ?: true)
)
|| nextSendGrpInv
override val userCantSendReason: Pair<String, String?>?
get() {
// TODO [short links] this will have additional statuses for pending contact requests before they are accepted
if (nextSendGrpInv) return null
if (!active) return generalGetString(MR.strings.cant_send_message_contact_deleted) to null
if (!sndReady) return generalGetString(MR.strings.cant_send_message_contact_not_ready) to null
if (activeConn?.connectionStats?.ratchetSyncSendProhibited == true) return generalGetString(MR.strings.cant_send_message_contact_not_synchronized) to null
if (activeConn?.connDisabled == true) return generalGetString(MR.strings.cant_send_message_contact_disabled) to null
return null
}
override val sendMsgEnabled get() = userCantSendReason == null
val nextSendGrpInv get() = contactGroupMemberId != null && !contactGrpInvSent
override val incognito get() = contactConnIncognito
override fun featureEnabled(feature: ChatFeature) = when (feature) {
@ -1768,7 +1763,23 @@ data class GroupInfo (
override val apiId get() = groupId
override val ready get() = membership.memberActive
override val chatDeleted get() = false
override val sendMsgEnabled get() = membership.memberActive
override val userCantSendReason: Pair<String, String?>? get() =
if (membership.memberActive) {
if (membership.memberRole == GroupMemberRole.Observer) {
generalGetString(MR.strings.observer_cant_send_message_title) to generalGetString(MR.strings.observer_cant_send_message_desc)
} else {
null
}
} else {
when (membership.memberStatus) {
GroupMemberStatus.MemRejected -> generalGetString(MR.strings.cant_send_message_rejected) to null
GroupMemberStatus.MemGroupDeleted -> generalGetString(MR.strings.cant_send_message_group_deleted) to null
GroupMemberStatus.MemRemoved -> generalGetString(MR.strings.cant_send_message_mem_removed) to null
GroupMemberStatus.MemLeft -> generalGetString(MR.strings.cant_send_message_you_left) to null
else -> generalGetString(MR.strings.cant_send_message_generic) to null
}
}
override val sendMsgEnabled get() = userCantSendReason == null
override val incognito get() = membership.memberIncognito
override fun featureEnabled(feature: ChatFeature) = when (feature) {
ChatFeature.TimedMessages -> fullGroupPreferences.timedMessages.on
@ -2144,6 +2155,7 @@ class NoteFolder(
override val apiId get() = noteFolderId
override val chatDeleted get() = false
override val ready get() = true
override val userCantSendReason: Pair<String, String?>? = null
override val sendMsgEnabled get() = true
override val incognito get() = false
override fun featureEnabled(feature: ChatFeature) = feature == ChatFeature.Voice
@ -2180,6 +2192,7 @@ class UserContactRequest (
override val apiId get() = contactRequestId
override val chatDeleted get() = false
override val ready get() = true
override val userCantSendReason = generalGetString(MR.strings.cant_send_message_generic) to null
override val sendMsgEnabled get() = false
override val incognito get() = false
override fun featureEnabled(feature: ChatFeature) = false
@ -2219,6 +2232,7 @@ class PendingContactConnection(
override val apiId get() = pccConnId
override val chatDeleted get() = false
override val ready get() = false
override val userCantSendReason = generalGetString(MR.strings.cant_send_message_generic) to null
override val sendMsgEnabled get() = false
override val incognito get() = customUserProfileId != null
override fun featureEnabled(feature: ChatFeature) = false

View file

@ -12,10 +12,10 @@ import java.net.URI
expect fun PlatformTextField(
composeState: MutableState<ComposeState>,
sendMsgEnabled: Boolean,
disabledText: String?,
sendMsgButtonDisabled: Boolean,
textStyle: MutableState<TextStyle>,
showDeleteTextButton: MutableState<Boolean>,
userIsObserver: Boolean,
placeholder: String,
showVoiceButton: Boolean,
onMessageChange: (ComposeMessage) -> Unit,

View file

@ -99,12 +99,11 @@ fun TerminalLayout(
isDirectChat = false,
liveMessageAlertShown = SharedPreference(get = { false }, set = {}),
sendMsgEnabled = true,
userCantSendReason = null,
sendButtonEnabled = true,
nextSendGrpInv = false,
needToAllowVoiceToContact = false,
allowedVoiceByPrefs = false,
userIsObserver = false,
userCanSend = true,
allowVoiceToContact = {},
placeholder = "",
sendMessage = { sendCommand() },

View file

@ -723,7 +723,7 @@ fun ChatLayout(
Modifier
.fillMaxWidth()
.desktopOnExternalDrag(
enabled = remember(attachmentDisabled.value, chatInfo.value?.userCanSend) { mutableStateOf(!attachmentDisabled.value && chatInfo.value?.userCanSend == true) }.value,
enabled = remember(attachmentDisabled.value, chatInfo.value?.sendMsgEnabled) { mutableStateOf(!attachmentDisabled.value && chatInfo.value?.sendMsgEnabled == true) }.value,
onFiles = { paths -> composeState.onFilesAttached(paths.map { it.toURI() }) },
onImage = { file -> CoroutineScope(Dispatchers.IO).launch { composeState.processPickedMedia(listOf(file.toURI()), null) } },
onText = {

View file

@ -999,9 +999,8 @@ fun ComposeView(
chatModel.sharedContent.value = null
}
val userCanSend = rememberUpdatedState(chat.chatInfo.userCanSend)
val sendMsgEnabled = rememberUpdatedState(chat.chatInfo.sendMsgEnabled)
val userIsObserver = rememberUpdatedState(chat.userIsObserver)
val userCantSendReason = rememberUpdatedState(chat.chatInfo.userCantSendReason)
val nextSendGrpInv = rememberUpdatedState(chat.nextSendGrpInv)
Column {
@ -1056,7 +1055,6 @@ fun ComposeView(
val attachmentEnabled =
!composeState.value.attachmentDisabled
&& sendMsgEnabled.value
&& userCanSend.value
&& !isGroupAndProhibitedFiles
&& !nextSendGrpInv.value
IconButton(
@ -1102,8 +1100,8 @@ fun ComposeView(
}
}
LaunchedEffect(rememberUpdatedState(chat.chatInfo.userCanSend).value) {
if (!chat.chatInfo.userCanSend) {
LaunchedEffect(rememberUpdatedState(chat.chatInfo.sendMsgEnabled).value) {
if (!chat.chatInfo.sendMsgEnabled) {
clearCurrentDraft()
clearState()
}
@ -1159,13 +1157,12 @@ fun ComposeView(
chat.chatInfo is ChatInfo.Direct,
liveMessageAlertShown = chatModel.controller.appPrefs.liveMessageAlertShown,
sendMsgEnabled = sendMsgEnabled.value,
userCantSendReason = userCantSendReason.value,
sendButtonEnabled = sendMsgEnabled.value && !(simplexLinkProhibited || fileProhibited || voiceProhibited),
nextSendGrpInv = nextSendGrpInv.value,
needToAllowVoiceToContact,
allowedVoiceByPrefs,
allowVoiceToContact = ::allowVoiceToContact,
userIsObserver = userIsObserver.value,
userCanSend = userCanSend.value,
sendButtonColor = sendButtonColor,
timedMessageAllowed = timedMessageAllowed,
customDisappearingMessageTimePref = chatModel.controller.appPrefs.customDisappearingMessageTime,

View file

@ -15,9 +15,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.graphics.*
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.*
import chat.simplex.common.model.*
@ -41,12 +39,11 @@ fun SendMsgView(
isDirectChat: Boolean,
liveMessageAlertShown: SharedPreference<Boolean>,
sendMsgEnabled: Boolean,
userCantSendReason: Pair<String, String?>?,
sendButtonEnabled: Boolean,
nextSendGrpInv: Boolean,
needToAllowVoiceToContact: Boolean,
allowedVoiceByPrefs: Boolean,
userIsObserver: Boolean,
userCanSend: Boolean,
sendButtonColor: Color = MaterialTheme.colors.primary,
allowVoiceToContact: () -> Unit,
timedMessageAllowed: Boolean = false,
@ -82,14 +79,14 @@ fun SendMsgView(
(!allowedVoiceByPrefs && cs.preview is ComposePreview.VoicePreview) ||
cs.endLiveDisabled ||
!sendButtonEnabled
val clicksOnTextFieldDisabled = !sendMsgEnabled || cs.preview is ComposePreview.VoicePreview || !userCanSend || cs.inProgress
val clicksOnTextFieldDisabled = !sendMsgEnabled || cs.preview is ComposePreview.VoicePreview || cs.inProgress
PlatformTextField(
composeState,
sendMsgEnabled,
disabledText = userCantSendReason?.first,
sendMsgButtonDisabled,
textStyle,
showDeleteTextButton,
userIsObserver,
if (clicksOnTextFieldDisabled) "" else placeholder,
showVoiceButton,
onMessageChange,
@ -102,16 +99,23 @@ fun SendMsgView(
}
}
if (clicksOnTextFieldDisabled) {
Box(
Modifier
.matchParentSize()
.clickable(enabled = !userCanSend, indication = null, interactionSource = remember { MutableInteractionSource() }, onClick = {
AlertManager.shared.showAlertMsg(
title = generalGetString(MR.strings.observer_cant_send_message_title),
text = generalGetString(MR.strings.observer_cant_send_message_desc)
)
})
)
if (userCantSendReason != null) {
Box(
Modifier
.matchParentSize()
.clickable(indication = null, interactionSource = remember { MutableInteractionSource() }, onClick = {
AlertManager.shared.showAlertMsg(
title = generalGetString(MR.strings.cant_send_message_alert_title),
text = userCantSendReason.second
)
})
)
} else {
Box(
Modifier
.matchParentSize()
)
}
}
if (showDeleteTextButton.value) {
DeleteTextButton(composeState)
@ -135,11 +139,11 @@ fun SendMsgView(
Row(verticalAlignment = Alignment.CenterVertically) {
val stopRecOnNextClick = remember { mutableStateOf(false) }
when {
needToAllowVoiceToContact || !allowedVoiceByPrefs || !userCanSend -> {
DisallowedVoiceButton(userCanSend) {
needToAllowVoiceToContact || !allowedVoiceByPrefs -> {
DisallowedVoiceButton {
if (needToAllowVoiceToContact) {
showNeedToAllowVoiceAlert(allowVoiceToContact)
} else if (!allowedVoiceByPrefs) {
} else {
showDisabledVoiceAlert(isDirectChat)
}
}
@ -155,7 +159,7 @@ fun SendMsgView(
&& cs.contextItem is ComposeContextItem.NoContextItem
) {
Spacer(Modifier.width(12.dp))
StartLiveMessageButton(userCanSend) {
StartLiveMessageButton {
if (composeState.value.preview is ComposePreview.NoPreview) {
startLiveMessage(scope, sendLiveMessage, updateLiveMessage, sendButtonSize, sendButtonAlpha, composeState, liveMessageAlertShown)
}
@ -343,8 +347,8 @@ private fun RecordVoiceView(recState: MutableState<RecordingState>, stopRecOnNex
}
@Composable
private fun DisallowedVoiceButton(enabled: Boolean, onClick: () -> Unit) {
IconButton(onClick, Modifier.size(36.dp), enabled = enabled) {
private fun DisallowedVoiceButton(onClick: () -> Unit) {
IconButton(onClick, Modifier.size(36.dp)) {
Icon(
painterResource(MR.images.ic_keyboard_voice),
stringResource(MR.strings.icon_descr_record_voice_message),
@ -460,14 +464,13 @@ private fun SendMsgButton(
}
@Composable
private fun StartLiveMessageButton(enabled: Boolean, onClick: () -> Unit) {
private fun StartLiveMessageButton(onClick: () -> Unit) {
val interactionSource = remember { MutableInteractionSource() }
val ripple = remember { ripple(bounded = false, radius = 24.dp) }
Box(
modifier = Modifier.requiredSize(36.dp)
.clickable(
onClick = onClick,
enabled = enabled,
role = Role.Button,
interactionSource = interactionSource,
indication = ripple
@ -477,7 +480,7 @@ private fun StartLiveMessageButton(enabled: Boolean, onClick: () -> Unit) {
Icon(
BoltFilled,
stringResource(MR.strings.icon_descr_send_message),
tint = if (enabled) MaterialTheme.colors.primary else MaterialTheme.colors.secondary,
tint = MaterialTheme.colors.primary,
modifier = Modifier
.size(36.dp)
.padding(4.dp)
@ -576,12 +579,11 @@ fun PreviewSendMsgView() {
isDirectChat = true,
liveMessageAlertShown = SharedPreference(get = { true }, set = { }),
sendMsgEnabled = true,
userCantSendReason = null,
sendButtonEnabled = true,
nextSendGrpInv = false,
needToAllowVoiceToContact = false,
allowedVoiceByPrefs = true,
userIsObserver = false,
userCanSend = true,
allowVoiceToContact = {},
timedMessageAllowed = false,
placeholder = "",
@ -612,12 +614,11 @@ fun PreviewSendMsgViewEditing() {
isDirectChat = true,
liveMessageAlertShown = SharedPreference(get = { true }, set = { }),
sendMsgEnabled = true,
userCantSendReason = null,
sendButtonEnabled = true,
nextSendGrpInv = false,
needToAllowVoiceToContact = false,
allowedVoiceByPrefs = true,
userIsObserver = false,
userCanSend = true,
allowVoiceToContact = {},
timedMessageAllowed = false,
placeholder = "",
@ -648,12 +649,11 @@ fun PreviewSendMsgViewInProgress() {
isDirectChat = true,
liveMessageAlertShown = SharedPreference(get = { true }, set = { }),
sendMsgEnabled = true,
userCantSendReason = null,
sendButtonEnabled = true,
nextSendGrpInv = false,
needToAllowVoiceToContact = false,
allowedVoiceByPrefs = true,
userIsObserver = false,
userCanSend = true,
allowVoiceToContact = {},
timedMessageAllowed = false,
placeholder = "",

View file

@ -21,6 +21,7 @@ import dev.icerock.moko.resources.compose.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.*
import chat.simplex.common.BuildConfigCommon
import chat.simplex.common.model.*
import chat.simplex.common.model.ChatController.appPrefs
import chat.simplex.common.platform.*
@ -127,7 +128,9 @@ fun SettingsLayout(
SectionDividerSpaced()
SectionView(stringResource(MR.strings.settings_section_title_support)) {
ContributeItem(uriHandler)
if (!BuildConfigCommon.ANDROID_BUNDLE) {
ContributeItem(uriHandler)
}
RateAppItem(uriHandler)
StarOnGithubItem(uriHandler)
}

View file

@ -487,8 +487,6 @@
<string name="image_decoding_exception_desc">The image cannot be decoded. Please, try a different image or contact developers.</string>
<string name="video_decoding_exception_desc">The video cannot be decoded. Please, try a different video or contact developers.</string>
<string name="you_are_observer">you are observer</string>
<string name="observer_cant_send_message_title">You can\'t send messages!</string>
<string name="observer_cant_send_message_desc">Please contact group admin.</string>
<string name="files_and_media_prohibited">Files and media prohibited!</string>
<string name="only_owners_can_enable_files_and_media">Only group owners can enable files and media.</string>
<string name="compose_send_direct_message_to_connect">Send direct message to connect</string>
@ -508,6 +506,19 @@
<string name="report_compose_reason_header_illegal">Report content: only group moderators will see it.</string>
<string name="report_compose_reason_header_other">Report other: only group moderators will see it.</string>
<string name="cant_send_message_alert_title">You can\'t send messages!</string>
<string name="cant_send_message_contact_not_ready">contact not ready</string>
<string name="cant_send_message_contact_deleted">contact deleted</string>
<string name="cant_send_message_contact_not_synchronized">not synchronized</string>
<string name="cant_send_message_contact_disabled">contact disabled</string>
<string name="observer_cant_send_message_title">you are observer</string>
<string name="observer_cant_send_message_desc">Please contact group admin.</string>
<string name="cant_send_message_rejected">request to join rejected</string>
<string name="cant_send_message_group_deleted">group is deleted</string>
<string name="cant_send_message_mem_removed">removed from group</string>
<string name="cant_send_message_you_left">you left</string>
<string name="cant_send_message_generic">can\'t send messages</string>
<!-- Images - chat.simplex.app.views.chat.item.CIImageView.kt -->
<string name="image_descr">Image</string>
<string name="icon_descr_waiting_for_image">Waiting for image</string>

View file

@ -44,10 +44,10 @@ import kotlin.text.substring
actual fun PlatformTextField(
composeState: MutableState<ComposeState>,
sendMsgEnabled: Boolean,
disabledText: String?,
sendMsgButtonDisabled: Boolean,
textStyle: MutableState<TextStyle>,
showDeleteTextButton: MutableState<Boolean>,
userIsObserver: Boolean,
placeholder: String,
showVoiceButton: Boolean,
onMessageChange: (ComposeMessage) -> Unit,
@ -203,16 +203,16 @@ actual fun PlatformTextField(
)
showDeleteTextButton.value = cs.message.text.split("\n").size >= 4 && !cs.inProgress
if (composeState.value.preview is ComposePreview.VoicePreview) {
ComposeOverlay(MR.strings.voice_message_send_text, textStyle, padding)
} else if (userIsObserver) {
ComposeOverlay(MR.strings.you_are_observer, textStyle, padding)
ComposeOverlay(generalGetString(MR.strings.voice_message_send_text), textStyle, padding)
} else if (disabledText != null) {
ComposeOverlay(disabledText, textStyle, padding)
}
}
@Composable
private fun ComposeOverlay(textId: StringResource, textStyle: MutableState<TextStyle>, padding: PaddingValues) {
private fun ComposeOverlay(text: String, textStyle: MutableState<TextStyle>, padding: PaddingValues) {
Text(
generalGetString(textId),
text,
Modifier.padding(padding),
color = MaterialTheme.colors.secondary,
style = textStyle.value.copy(fontStyle = FontStyle.Italic)

View file

@ -24,11 +24,13 @@ android.nonTransitiveRClass=true
kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.jvm.target=11
android.version_name=6.3.4
android.version_code=288
android.version_name=6.3.6
android.version_code=295
desktop.version_name=6.3.4
desktop.version_code=101
android.bundle=false
desktop.version_name=6.3.6
desktop.version_code=106
kotlin.version=1.9.23
gradle.plugin.version=8.2.0

View file

@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: deaec3cce286e959bd594b9620c307954b510a07
tag: 3d62a383d5dcae6529d6d866233857182bcb4d47
source-repository-package
type: git

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before After
Before After

BIN
images/whonix-logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

View file

@ -38,6 +38,32 @@
</description>
<releases>
<release version="6.3.4" date="2025-05-12">
<url type="details">https://simplex.chat/blog/20250308-simplex-chat-v6-3-new-user-experience-safety-in-public-groups.html</url>
<description>
<p>New in v6.3.1-4:</p>
<ul>
<li>fixes mentions with trailing punctuation (e.g., hello @name!).</li>
<li>recognizes domain names as links (e.g., simplex.chat).</li>
<li>forward compatibility with "knocking" (a feature for group admins to review and to chat with the new members prior to admitting them to groups, it will be released in 6.4)</li>
<li>support for connecting via short connection links.</li>
<li>fix related to backward/forward compatibility of the app in some rare cases.</li>
<li>scrolling/navigation improvements.</li>
<li>faster onboarding (conditions and operators are combined to one screen).</li>
</ul>
<p>New in v6.3.0:</p>
<ul>
<li>Mention members and get notified when mentioned.</li>
<li>Send private reports to moderators.</li>
<li>Delete, block and change role for multiple members at once</li>
<li>Faster sending messages and faster deletion.</li>
<li>Organize chats into lists to keep track of what's important.</li>
<li>Jump to found and forwarded messages.</li>
<li>Private media file names.</li>
<li>Message expiration in chats.</li>
</ul>
</description>
</release>
<release version="6.3.3" date="2025-04-24">
<url type="details">https://simplex.chat/blog/20250308-simplex-chat-v6-3-new-user-experience-safety-in-public-groups.html</url>
<description>

View file

@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."deaec3cce286e959bd594b9620c307954b510a07" = "0b8m4czjiwsi9169plslyk2rjw0f370vv7ha6qm2hpx14bxzz7xm";
"https://github.com/simplex-chat/simplexmq.git"."3d62a383d5dcae6529d6d866233857182bcb4d47" = "133xm8jkim7agd6drwm3lbx1z7v8nf4l3asrm46ag3n2q201yfxc";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";

View file

@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack
name: simplex-chat
version: 6.3.4.1
version: 6.3.6.0
category: Web, System, Services, Cryptography
homepage: https://github.com/simplex-chat/simplex-chat#readme
author: simplex.chat

View file

@ -1671,25 +1671,10 @@ processChatCommand' vr = \case
case (pccConnStatus, connLinkInv) of
(ConnNew, Just (CCLink cReqInv _)) -> do
newUser <- privateGetUser newUserId
conn' <- ifM (canKeepLink cReqInv newUser) (updateConnRecord user conn newUser) (recreateConn user conn newUser)
conn' <- recreateConn user conn newUser
pure $ CRConnectionUserChanged user conn conn' newUser
_ -> throwChatError CEConnectionUserChangeProhibited
where
canKeepLink :: ConnReqInvitation -> User -> CM Bool
canKeepLink (CRInvitationUri crData _) newUser = do
let ConnReqUriData {crSmpQueues = q :| _} = crData
SMPQueueUri {queueAddress = SMPQueueAddress {smpServer}} = q
newUserServers <-
map protoServer' . L.filter (\ServerCfg {enabled} -> enabled)
<$> getKnownAgentServers SPSMP newUser
pure $ smpServer `elem` newUserServers
updateConnRecord user@User {userId} conn@PendingContactConnection {customUserProfileId} newUser = do
withAgent $ \a -> changeConnectionUser a (aUserId user) (aConnId' conn) (aUserId newUser)
withFastStore' $ \db -> do
conn' <- updatePCCUser db userId conn newUserId
forM_ customUserProfileId $ \profileId ->
deletePCCIncognitoProfile db user profileId
pure conn'
recreateConn user conn@PendingContactConnection {customUserProfileId, connLinkInv} newUser = do
subMode <- chatReadVar subscriptionMode
let userData = shortLinkUserData $ isJust $ connShortLink =<< connLinkInv

View file

@ -66,7 +66,6 @@ module Simplex.Chat.Store.Direct
updateContactAccepted,
getUserByContactRequestId,
getPendingContactConnections,
updatePCCUser,
getContactConnections,
getConnectionById,
getConnectionsContacts,
@ -440,19 +439,6 @@ updatePCCIncognito db User {userId} conn customUserProfileId = do
(customUserProfileId, updatedAt, userId, pccConnId conn)
pure (conn :: PendingContactConnection) {customUserProfileId, updatedAt}
updatePCCUser :: DB.Connection -> UserId -> PendingContactConnection -> UserId -> IO PendingContactConnection
updatePCCUser db userId conn newUserId = do
updatedAt <- getCurrentTime
DB.execute
db
[sql|
UPDATE connections
SET user_id = ?, custom_user_profile_id = NULL, updated_at = ?
WHERE user_id = ? AND connection_id = ?
|]
(newUserId, updatedAt, userId, pccConnId conn)
pure (conn :: PendingContactConnection) {customUserProfileId = Nothing, updatedAt}
deletePCCIncognitoProfile :: DB.Connection -> User -> ProfileId -> IO ()
deletePCCIncognitoProfile db User {userId} profileId =
DB.execute

View file

@ -171,7 +171,7 @@ import Simplex.Messaging.Crypto.File (CryptoFile (..), CryptoFileArgs (..))
import Simplex.Messaging.Util (eitherToMaybe)
import UnliftIO.STM
#if defined(dbPostgres)
import Database.PostgreSQL.Simple (FromRow, Only (..), Query, ToRow, (:.) (..))
import Database.PostgreSQL.Simple (FromRow, In (..), Only (..), Query, ToRow, (:.) (..))
import Database.PostgreSQL.Simple.SqlQQ (sql)
#else
import Database.SQLite.Simple (FromRow, Only (..), Query, ToRow, (:.) (..))
@ -2370,8 +2370,14 @@ updateGroupChatItemModerated db User {userId} GroupInfo {groupId} ci m@GroupMemb
updateMemberCIsModerated :: MsgDirectionI d => DB.Connection -> User -> GroupInfo -> GroupMember -> GroupMember -> SMsgDirection d -> UTCTime -> IO ()
updateMemberCIsModerated db User {userId} GroupInfo {groupId, membership} member byGroupMember md deletedTs = do
itemIds <- updateCIs =<< getCurrentTime
#if defined(dbPostgres)
let inItemIds = Only $ In (map fromOnly itemIds)
DB.execute db "DELETE FROM messages WHERE message_id IN (SELECT message_id FROM chat_item_messages WHERE chat_item_id IN ?)" inItemIds
DB.execute db "DELETE FROM chat_item_versions WHERE chat_item_id IN ?" inItemIds
#else
DB.executeMany db deleteChatItemMessagesQuery itemIds
DB.executeMany db "DELETE FROM chat_item_versions WHERE chat_item_id = ?" itemIds
#endif
where
memId = groupMemberId' member
updateQuery =
@ -2887,7 +2893,7 @@ getGroupCIMentions db ciId =
SELECT r.display_name, r.member_id, m.group_member_id, m.member_role, p.display_name, p.local_alias
FROM chat_item_mentions r
LEFT JOIN group_members m ON r.group_id = m.group_id AND r.member_id = m.member_id
LEFT JOIN contact_profiles p ON p.contact_profile_id = COALESCE(m.member_profile_id, m.contact_profile_id)
LEFT JOIN contact_profiles p ON p.contact_profile_id = COALESCE(m.member_profile_id, m.contact_profile_id)
WHERE r.chat_item_id = ?
|]
(Only ciId)

View file

@ -1071,10 +1071,6 @@ Query: UPDATE connections SET smp_agent_version = ? WHERE conn_id = ?
Plan:
SEARCH connections USING PRIMARY KEY (conn_id=?)
Query: UPDATE connections SET user_id = ? WHERE conn_id = ? and user_id = ?
Plan:
SEARCH connections USING PRIMARY KEY (conn_id=?)
Query: UPDATE messages SET msg_body = x'' WHERE conn_id = ? AND internal_id = ?
Plan:
SEARCH messages USING PRIMARY KEY (conn_id=? AND internal_id=?)

View file

@ -3186,7 +3186,7 @@ Query:
SELECT r.display_name, r.member_id, m.group_member_id, m.member_role, p.display_name, p.local_alias
FROM chat_item_mentions r
LEFT JOIN group_members m ON r.group_id = m.group_id AND r.member_id = m.member_id
LEFT JOIN contact_profiles p ON p.contact_profile_id = COALESCE(m.member_profile_id, m.contact_profile_id)
LEFT JOIN contact_profiles p ON p.contact_profile_id = COALESCE(m.member_profile_id, m.contact_profile_id)
WHERE r.chat_item_id = ?
Plan:
@ -4215,14 +4215,6 @@ Query:
Plan:
SEARCH connections USING INTEGER PRIMARY KEY (rowid=?)
Query:
UPDATE connections
SET user_id = ?, custom_user_profile_id = NULL, updated_at = ?
WHERE user_id = ? AND connection_id = ?
Plan:
SEARCH connections USING INTEGER PRIMARY KEY (rowid=?)
Query:
UPDATE contact_profiles
SET contact_link = ?, updated_at = ?

View file

@ -1747,10 +1747,9 @@ viewConnectionIncognitoUpdated PendingContactConnection {pccConnId, customUserPr
| otherwise = ["connection " <> sShow pccConnId <> " changed to non incognito"]
viewConnectionUserChanged :: User -> PendingContactConnection -> User -> PendingContactConnection -> [StyledString]
viewConnectionUserChanged User {localDisplayName = n} PendingContactConnection {pccConnId, connLinkInv} User {localDisplayName = n'} PendingContactConnection {connLinkInv = connLinkInv'} =
case (connLinkInv, connLinkInv') of
(Just ccLink, Just ccLink')
| ccLink /= ccLink' -> [userChangedStr <> ", new link:"] <> newLink ccLink'
viewConnectionUserChanged User {localDisplayName = n} PendingContactConnection {pccConnId} User {localDisplayName = n'} PendingContactConnection {connLinkInv = connLinkInv'} =
case connLinkInv' of
Just ccLink' -> [userChangedStr <> ", new link:"] <> newLink ccLink'
_ -> [userChangedStr]
where
userChangedStr = "connection " <> sShow pccConnId <> " changed from user " <> plain n <> " to user " <> plain n'

View file

@ -17,6 +17,7 @@ import Control.Concurrent (forkIOWithUnmask, killThread, threadDelay)
import Control.Concurrent.Async
import Control.Concurrent.STM
import Control.Exception (bracket, bracket_)
import Control.Logger.Simple
import Control.Monad
import Control.Monad.Except
import Control.Monad.Reader
@ -519,7 +520,7 @@ smpServerCfg =
allowSMPProxy = True,
serverClientConcurrency = 16,
information = Nothing,
startOptions = StartOptions {maintenance = False, compactLog = False, skipWarnings = False, confirmMigrations = MCYesUp}
startOptions = StartOptions {maintenance = False, logLevel = LogError, compactLog = False, skipWarnings = False, confirmMigrations = MCYesUp}
}
persistentServerStoreCfg :: FilePath -> AServerStoreCfg

View file

@ -84,7 +84,10 @@ chatGroupTests = do
describe "batch send messages" $ do
it "send multiple messages api" testSendMulti
it "send multiple timed messages" testSendMultiTimed
#if !defined(dbPostgres)
-- TODO [postgres] this test hangs with PostgreSQL
it "send multiple messages (many chat batches)" testSendMultiManyBatches
#endif
xit'' "shared message body is reused" testSharedMessageBody
xit'' "shared batch body is reused" testSharedBatchBody
describe "async group connections" $ do
@ -1821,7 +1824,7 @@ testDeleteMemberWithMessages =
do
cath <## "alice updated group #team:"
cath <## "updated group preferences:"
cath <## "Full deletion: on"
cath <## "Full deletion: on"
]
threadDelay 750000
bob #> "#team hello"
@ -6496,7 +6499,7 @@ testForwardQuoteMention =
bob <## " hello @alice @cath",
do
cath <# "#team alice!> -> forwarded"
cath <## " hello @alice @cath"
cath <## " hello @alice @cath"
]
-- forward mentions
alice `send` "@bob <- #team hello"

View file

@ -1827,7 +1827,7 @@ testChangePCCUser = testChat2 aliceProfile bobProfile $
\alice bob -> do
-- Create a new invite
alice ##> "/connect"
inv <- getInvitation alice
_ <- getInvitation alice
-- Create new user and go back to original user
alice ##> "/create user alisa"
showActiveUser alice "alisa"
@ -1837,12 +1837,18 @@ testChangePCCUser = testChat2 aliceProfile bobProfile $
showActiveUser alice "alice (Alice)"
-- Change connection to newly created user
alice ##> "/_set conn user :1 2"
alice <## "connection 1 changed from user alice to user alisa"
alice <## "connection 1 changed from user alice to user alisa, new link:"
alice <## ""
_ <- getTermLine alice
alice <## ""
alice ##> "/user alisa"
showActiveUser alice "alisa"
-- Change connection back to other user
alice ##> "/_set conn user :1 3"
alice <## "connection 1 changed from user alisa to user alisa2"
alice <## "connection 1 changed from user alisa to user alisa2, new link:"
alice <## ""
inv <- getTermLine alice
alice <## ""
alice ##> "/user alisa2"
showActiveUser alice "alisa2"
-- Connect
@ -1851,13 +1857,14 @@ testChangePCCUser = testChat2 aliceProfile bobProfile $
concurrently_
(alice <## "bob (Bob): contact is connected")
(bob <## "alisa2: contact is connected")
alice <##> bob
testChangePCCUserFromIncognito :: HasCallStack => TestParams -> IO ()
testChangePCCUserFromIncognito = testChat2 aliceProfile bobProfile $
\alice bob -> do
-- Create a new invite and set as incognito
alice ##> "/connect"
inv <- getInvitation alice
_ <- getInvitation alice
alice ##> "/_set incognito :1 on"
alice <## "connection 1 changed to incognito"
-- Create new user and go back to original user
@ -1867,13 +1874,19 @@ testChangePCCUserFromIncognito = testChat2 aliceProfile bobProfile $
showActiveUser alice "alice (Alice)"
-- Change connection to newly created user
alice ##> "/_set conn user :1 2"
alice <## "connection 1 changed from user alice to user alisa"
alice <## "connection 1 changed from user alice to user alisa, new link:"
alice <## ""
_ <- getTermLine alice
alice <## ""
alice `hasContactProfiles` ["alice"]
alice ##> "/user alisa"
showActiveUser alice "alisa"
-- Change connection back to initial user
alice ##> "/_set conn user :1 1"
alice <## "connection 1 changed from user alisa to user alice"
alice <## "connection 1 changed from user alisa to user alice, new link:"
alice <## ""
inv <- getTermLine alice
alice <## ""
alice ##> "/user alice"
showActiveUser alice "alice (Alice)"
-- Connect
@ -1882,13 +1895,14 @@ testChangePCCUserFromIncognito = testChat2 aliceProfile bobProfile $
concurrently_
(alice <## "bob (Bob): contact is connected")
(bob <## "alice (Alice): contact is connected")
alice <##> bob
testChangePCCUserAndThenIncognito :: HasCallStack => TestParams -> IO ()
testChangePCCUserAndThenIncognito = testChat2 aliceProfile bobProfile $
\alice bob -> do
-- Create a new invite and set as incognito
alice ##> "/connect"
inv <- getInvitation alice
_ <- getInvitation alice
-- Create new user and go back to original user
alice ##> "/create user alisa"
showActiveUser alice "alisa"
@ -1896,7 +1910,10 @@ testChangePCCUserAndThenIncognito = testChat2 aliceProfile bobProfile $
showActiveUser alice "alice (Alice)"
-- Change connection to newly created user
alice ##> "/_set conn user :1 2"
alice <## "connection 1 changed from user alice to user alisa"
alice <## "connection 1 changed from user alice to user alisa, new link:"
alice <## ""
inv <- getTermLine alice
alice <## ""
alice ##> "/user alisa"
showActiveUser alice "alisa"
-- Change connection to incognito and make sure it's attached to the newly created user profile
@ -1911,6 +1928,10 @@ testChangePCCUserAndThenIncognito = testChat2 aliceProfile bobProfile $
alice <## ("bob (Bob): contact is connected, your incognito profile for this contact is " <> alisaIncognito)
alice <## ("use /i bob to print out this incognito profile again")
]
alice ?#> "@bob hi"
bob <# (alisaIncognito <> "> hi")
bob #> ("@" <> alisaIncognito <> " hey")
alice ?<# "bob> hey"
testChangePCCUserDiffSrv :: HasCallStack => TestParams -> IO ()
testChangePCCUserDiffSrv ps = do
@ -1951,6 +1972,7 @@ testChangePCCUserDiffSrv ps = do
concurrently_
(alice <## "bob (Bob): contact is connected")
(bob <## "alisa: contact is connected")
alice <##> bob
where
serverCfg' =
smpServerCfg

View file

@ -31,6 +31,10 @@
<img class="h-[40px] w-auto block dark:hidden" src="/img/privacy-guides-light.png" alt="Privacy Guides">
<img class="h-[40px] w-auto hidden dark:block" src="/img/privacy-guides-dark.png" alt="Privacy Guides">
</a>
<a class="block rounded overflow-hidden" title="Whonix messenger recommendations" href="https://www.whonix.org/wiki/Chat#Recommendation" target="_blank">
<img class="h-[24px] mb-[8px] w-auto block dark:hidden" src="/img/whonix-light.png" alt="Whonix">
<img class="h-[24px] mb-[8px] w-auto hidden dark:block" src="/img/whonix-dark.png" alt="Whonix">
</a>
<a class="block rounded overflow-hidden" title="publication" href="https://www.heise.de/suche/?q=simplex+chat&sort_by=date&rm=search" target="_blank">
<img class="h-[40px] w-auto block dark:hidden" src="/img/heise-light.png" alt="Heise Online">
<img class="h-[40px] w-auto hidden dark:block" src="/img/heise-dark.png" alt="Heise Online">
@ -43,7 +47,7 @@
<img class="h-[40px] w-auto" src="/img/optout.jpg" alt="Opt Out Podcast">
</a>
</div>
<div>
<p class="text-black dark:text-white hidden md:block text-center xl:text-left xl:rtl:text-right text-[16px] leading-[26px] mb-[11px] md:mt-6">{{ "get-simplex" | i18n({}, lang ) | safe }}</p>
<div class="socials flex items-center justify-center xl:justify-start gap-4 flex-wrap mt-[30px]">
@ -66,7 +70,7 @@
<video class="absolute rounded-lg top-10 w-[235px] ml-[-6px] mt-1" controls>
<source src="/video/connect.mp4" type="video/mp4">
</video>
{# <div class="absolute flex flex-col items-center gap-3">
<img src="/img/new/play-btn.svg" alt="" />
<p class="text-center text-[16px] leading-[24px] tracking-[0.04em] text-white">PLAY</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB