diff --git a/apps/ios/Shared/Views/Database/DatabaseView.swift b/apps/ios/Shared/Views/Database/DatabaseView.swift
index d5d70abaea..278893a669 100644
--- a/apps/ios/Shared/Views/Database/DatabaseView.swift
+++ b/apps/ios/Shared/Views/Database/DatabaseView.swift
@@ -110,33 +110,88 @@ struct DatabaseView: View {
}
Section {
- settingsRow(
- stopped ? "exclamationmark.octagon.fill" : "play.fill",
- color: stopped ? .red : .green
- ) {
- Toggle(
- stopped ? "Chat is stopped" : "Chat is running",
- isOn: $runChat
- )
- .onChange(of: runChat) { _ in
- if runChat {
- DatabaseView.startChat($runChat, $progressIndicator)
- } else if !stoppingChat {
- stoppingChat = false
- alert = .stopChat
- }
- }
- }
- } header: {
- Text("Run chat")
- .foregroundColor(theme.colors.secondary)
- } footer: {
- if case .documents = dbContainer {
- Text("Database will be migrated when the app restarts")
- .foregroundColor(theme.colors.secondary)
- }
+ NavigationLink("Database passphrase & export", destination: databaseManagementView)
}
+ Section {
+ Button(m.users.count > 1 ? "Delete files for all chat profiles" : "Delete all files", role: .destructive) {
+ alert = .deleteFilesAndMedia
+ }
+ .disabled(progressIndicator || appFilesCountAndSize?.0 == 0)
+ } header: {
+ Text("Files & media")
+ .foregroundColor(theme.colors.secondary)
+ } footer: {
+ if let (fileCount, size) = appFilesCountAndSize {
+ if fileCount == 0 {
+ Text("No received or sent files")
+ .foregroundColor(theme.colors.secondary)
+ } else {
+ Text("\(fileCount) file(s) with total size of \(ByteCountFormatter.string(fromByteCount: Int64(size), countStyle: .binary))")
+ .foregroundColor(theme.colors.secondary)
+ }
+ }
+ }
+ }
+ .onAppear {
+ runChat = m.chatRunning ?? true
+ appFilesCountAndSize = directoryFileCountAndSize(getAppFilesDirectory())
+ currentChatItemTTL = chatItemTTL
+ }
+ .onChange(of: chatItemTTL) { ttl in
+ if ttl < currentChatItemTTL {
+ alert = .setChatItemTTL(ttl: ttl)
+ } else if ttl != currentChatItemTTL {
+ setCiTTL(ttl)
+ }
+ }
+ .alert(item: $alert) { item in databaseAlert(item) }
+ .fileImporter(
+ isPresented: $showFileImporter,
+ allowedContentTypes: [.zip],
+ allowsMultipleSelection: false
+ ) { result in
+ if case let .success(files) = result, let fileURL = files.first {
+ importedArchivePath = fileURL
+ alert = .importArchive
+ }
+ }
+ }
+
+ private func runChatToggleView() -> some View {
+ Section {
+ let stopped = m.chatRunning == false
+ settingsRow(
+ stopped ? "exclamationmark.octagon.fill" : "play.fill",
+ color: stopped ? .red : .green
+ ) {
+ Toggle(
+ stopped ? "Chat is stopped" : "Chat is running",
+ isOn: $runChat
+ )
+ .onChange(of: runChat) { _ in
+ if runChat {
+ DatabaseView.startChat($runChat, $progressIndicator)
+ } else if !stoppingChat {
+ stoppingChat = false
+ alert = .stopChat
+ }
+ }
+ }
+ } header: {
+ Text("Run chat")
+ .foregroundColor(theme.colors.secondary)
+ } footer: {
+ if case .documents = dbContainer {
+ Text("Database will be migrated when the app restarts")
+ .foregroundColor(theme.colors.secondary)
+ }
+ }
+ }
+
+ private func databaseManagementView() -> some View {
+ List {
+ let stopped = m.chatRunning == false
Section {
let unencrypted = m.chatDbEncrypted == false
let color: Color = unencrypted ? .orange : theme.colors.secondary
@@ -194,49 +249,9 @@ struct DatabaseView: View {
}
}
- Section {
- Button(m.users.count > 1 ? "Delete files for all chat profiles" : "Delete all files", role: .destructive) {
- alert = .deleteFilesAndMedia
- }
- .disabled(progressIndicator || appFilesCountAndSize?.0 == 0)
- } header: {
- Text("Files & media")
- .foregroundColor(theme.colors.secondary)
- } footer: {
- if let (fileCount, size) = appFilesCountAndSize {
- if fileCount == 0 {
- Text("No received or sent files")
- .foregroundColor(theme.colors.secondary)
- } else {
- Text("\(fileCount) file(s) with total size of \(ByteCountFormatter.string(fromByteCount: Int64(size), countStyle: .binary))")
- .foregroundColor(theme.colors.secondary)
- }
- }
- }
- }
- .onAppear {
- runChat = m.chatRunning ?? true
- appFilesCountAndSize = directoryFileCountAndSize(getAppFilesDirectory())
- currentChatItemTTL = chatItemTTL
- }
- .onChange(of: chatItemTTL) { ttl in
- if ttl < currentChatItemTTL {
- alert = .setChatItemTTL(ttl: ttl)
- } else if ttl != currentChatItemTTL {
- setCiTTL(ttl)
- }
- }
- .alert(item: $alert) { item in databaseAlert(item) }
- .fileImporter(
- isPresented: $showFileImporter,
- allowedContentTypes: [.zip],
- allowsMultipleSelection: false
- ) { result in
- if case let .success(files) = result, let fileURL = files.first {
- importedArchivePath = fileURL
- alert = .importArchive
- }
+ runChatToggleView()
}
+ .modifier(ThemedBackground(grouped: true))
}
private func databaseAlert(_ alertItem: DatabaseAlert) -> Alert {
diff --git a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/NetworkAndServers.swift b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/NetworkAndServers.swift
index f10b945dc0..24cf088918 100644
--- a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/NetworkAndServers.swift
+++ b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/NetworkAndServers.swift
@@ -121,16 +121,6 @@ struct NetworkAndServers: View {
}
}
- Section(header: Text("Calls").foregroundColor(theme.colors.secondary)) {
- NavigationLink {
- RTCServers()
- .navigationTitle("Your ICE servers")
- .modifier(ThemedBackground(grouped: true))
- } label: {
- Text("WebRTC ICE servers")
- }
- }
-
Section(header: Text("Network connection").foregroundColor(theme.colors.secondary)) {
HStack {
Text(m.networkInfo.networkType.text)
diff --git a/apps/ios/Shared/Views/UserSettings/NotificationsView.swift b/apps/ios/Shared/Views/UserSettings/NotificationsView.swift
index c4d0588987..131eeecef7 100644
--- a/apps/ios/Shared/Views/UserSettings/NotificationsView.swift
+++ b/apps/ios/Shared/Views/UserSettings/NotificationsView.swift
@@ -63,36 +63,6 @@ struct NotificationsView: View {
}
}
- NavigationLink {
- List {
- Section {
- SelectionListView(list: NotificationPreviewMode.values, selection: $m.notificationPreview) { previewMode in
- ntfPreviewModeGroupDefault.set(previewMode)
- m.notificationPreview = previewMode
- }
- } footer: {
- VStack(alignment: .leading, spacing: 1) {
- Text("You can set lock screen notification preview via settings.")
- .foregroundColor(theme.colors.secondary)
- Button("Open Settings") {
- DispatchQueue.main.async {
- UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
- }
- }
- }
- }
- }
- .navigationTitle("Show preview")
- .modifier(ThemedBackground(grouped: true))
- .navigationBarTitleDisplayMode(.inline)
- } label: {
- HStack {
- Text("Show preview")
- Spacer()
- Text(m.notificationPreview.label)
- }
- }
-
if let server = m.notificationServer {
smpServers("Push server", [server], theme.colors.secondary)
testTokenButton(server)
diff --git a/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift b/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift
index 3ae9f0eacd..ad6b2d4454 100644
--- a/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift
+++ b/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift
@@ -81,30 +81,12 @@ struct PrivacySettings: View {
settingsRow("link", color: theme.colors.secondary) {
Toggle("Remove link tracking", isOn: $privacySanitizeLinks)
}
- settingsRow("message", color: theme.colors.secondary) {
- Toggle("Show last messages", isOn: $showChatPreviews)
- }
- settingsRow("rectangle.and.pencil.and.ellipsis", color: theme.colors.secondary) {
- Toggle("Message draft", isOn: $saveLastDraft)
- }
- .onChange(of: saveLastDraft) { saveDraft in
- if !saveDraft {
- m.draft = nil
- m.draftChatId = nil
- }
- }
} header: {
Text("Chats")
.foregroundColor(theme.colors.secondary)
}
Section {
- settingsRow("lock.doc", color: theme.colors.secondary) {
- Toggle("Encrypt local files", isOn: $encryptLocalFiles)
- .onChange(of: encryptLocalFiles) {
- setEncryptLocalFiles($0)
- }
- }
settingsRow("photo", color: theme.colors.secondary) {
Toggle("Auto-accept images", isOn: $autoAcceptImages)
.onChange(of: autoAcceptImages) {
@@ -126,20 +108,9 @@ struct PrivacySettings: View {
}
}
}
- settingsRow("network.badge.shield.half.filled", color: theme.colors.secondary) {
- Toggle("Protect IP address", isOn: $askToApproveRelays)
- }
} header: {
Text("Files")
.foregroundColor(theme.colors.secondary)
- } footer: {
- if askToApproveRelays {
- Text("The app will ask to confirm downloads from unknown file servers (except .onion).")
- .foregroundColor(theme.colors.secondary)
- } else {
- Text("Without Tor or VPN, your IP address will be visible to file servers.")
- .foregroundColor(theme.colors.secondary)
- }
}
Section {
@@ -155,45 +126,8 @@ struct PrivacySettings: View {
}
Section {
- settingsRow("person", color: theme.colors.secondary) {
- Toggle("Contacts", isOn: $contactReceipts)
- }
- settingsRow("person.2", color: theme.colors.secondary) {
- Toggle("Small groups (max 20)", isOn: $groupReceipts)
- }
- } header: {
- Text("Send delivery receipts to")
- .foregroundColor(theme.colors.secondary)
- } footer: {
- VStack(alignment: .leading) {
- Text("These settings are for your current profile **\(m.currentUser?.displayName ?? "")**.")
- Text("They can be overridden in contact and group settings.")
- }
- .foregroundColor(theme.colors.secondary)
- .frame(maxWidth: .infinity, alignment: .leading)
- }
- .confirmationDialog(contactReceiptsDialogTitle, isPresented: $contactReceiptsDialogue, titleVisibility: .visible) {
- Button(contactReceipts ? "Enable (keep overrides)" : "Disable (keep overrides)") {
- setSendReceiptsContacts(contactReceipts, clearOverrides: false)
- }
- Button(contactReceipts ? "Enable for all" : "Disable for all", role: .destructive) {
- setSendReceiptsContacts(contactReceipts, clearOverrides: true)
- }
- Button("Cancel", role: .cancel) {
- contactReceiptsReset = true
- contactReceipts.toggle()
- }
- }
- .confirmationDialog(groupReceiptsDialogTitle, isPresented: $groupReceiptsDialogue, titleVisibility: .visible) {
- Button(groupReceipts ? "Enable (keep overrides)" : "Disable (keep overrides)") {
- setSendReceiptsGroups(groupReceipts, clearOverrides: false)
- }
- Button(groupReceipts ? "Enable for all" : "Disable for all", role: .destructive) {
- setSendReceiptsGroups(groupReceipts, clearOverrides: true)
- }
- Button("Cancel", role: .cancel) {
- groupReceiptsReset = true
- groupReceipts.toggle()
+ NavigationLink(destination: morePrivacyView) {
+ settingsRow("ellipsis", color: theme.colors.secondary) { Text("More privacy") }
}
}
}
@@ -243,6 +177,132 @@ struct PrivacySettings: View {
}
}
+ @ViewBuilder
+ private func morePrivacyView() -> some View {
+ List {
+ Section {
+ settingsRow("message", color: theme.colors.secondary) {
+ Toggle("Show last messages", isOn: $showChatPreviews)
+ }
+ settingsRow("rectangle.and.pencil.and.ellipsis", color: theme.colors.secondary) {
+ Toggle("Message draft", isOn: $saveLastDraft)
+ }
+ .onChange(of: saveLastDraft) { saveDraft in
+ if !saveDraft {
+ m.draft = nil
+ m.draftChatId = nil
+ }
+ }
+ } header: {
+ Text("Chats")
+ .foregroundColor(theme.colors.secondary)
+ }
+
+ Section {
+ settingsRow("lock.doc", color: theme.colors.secondary) {
+ Toggle("Encrypt local files", isOn: $encryptLocalFiles)
+ .onChange(of: encryptLocalFiles) {
+ setEncryptLocalFiles($0)
+ }
+ }
+ settingsRow("network.badge.shield.half.filled", color: theme.colors.secondary) {
+ Toggle("Protect IP address", isOn: $askToApproveRelays)
+ }
+ } header: {
+ Text("Files")
+ .foregroundColor(theme.colors.secondary)
+ } footer: {
+ if askToApproveRelays {
+ Text("The app will ask to confirm downloads from unknown file servers (except .onion).")
+ .foregroundColor(theme.colors.secondary)
+ } else {
+ Text("Without Tor or VPN, your IP address will be visible to file servers.")
+ .foregroundColor(theme.colors.secondary)
+ }
+ }
+
+ Section {
+ NavigationLink {
+ List {
+ Section {
+ SelectionListView(list: NotificationPreviewMode.values, selection: $m.notificationPreview) { previewMode in
+ ntfPreviewModeGroupDefault.set(previewMode)
+ m.notificationPreview = previewMode
+ }
+ } footer: {
+ VStack(alignment: .leading, spacing: 1) {
+ Text("You can set lock screen notification preview via settings.")
+ .foregroundColor(theme.colors.secondary)
+ Button("Open Settings") {
+ DispatchQueue.main.async {
+ UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
+ }
+ }
+ }
+ }
+ }
+ .navigationTitle("Show preview")
+ .modifier(ThemedBackground(grouped: true))
+ .navigationBarTitleDisplayMode(.inline)
+ } label: {
+ HStack {
+ Text("Show preview")
+ Spacer()
+ Text(m.notificationPreview.label)
+ }
+ }
+ } header: {
+ Text("Notifications")
+ .foregroundColor(theme.colors.secondary)
+ }
+
+ Section {
+ settingsRow("person", color: theme.colors.secondary) {
+ Toggle("Contacts", isOn: $contactReceipts)
+ }
+ settingsRow("person.2", color: theme.colors.secondary) {
+ Toggle("Small groups (max 20)", isOn: $groupReceipts)
+ }
+ } header: {
+ Text("Send delivery receipts to")
+ .foregroundColor(theme.colors.secondary)
+ } footer: {
+ VStack(alignment: .leading) {
+ Text("These settings are for your current profile **\(m.currentUser?.displayName ?? "")**.")
+ Text("They can be overridden in contact and group settings.")
+ }
+ .foregroundColor(theme.colors.secondary)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ }
+ .confirmationDialog(contactReceiptsDialogTitle, isPresented: $contactReceiptsDialogue, titleVisibility: .visible) {
+ Button(contactReceipts ? "Enable (keep overrides)" : "Disable (keep overrides)") {
+ setSendReceiptsContacts(contactReceipts, clearOverrides: false)
+ }
+ Button(contactReceipts ? "Enable for all" : "Disable for all", role: .destructive) {
+ setSendReceiptsContacts(contactReceipts, clearOverrides: true)
+ }
+ Button("Cancel", role: .cancel) {
+ contactReceiptsReset = true
+ contactReceipts.toggle()
+ }
+ }
+ .confirmationDialog(groupReceiptsDialogTitle, isPresented: $groupReceiptsDialogue, titleVisibility: .visible) {
+ Button(groupReceipts ? "Enable (keep overrides)" : "Disable (keep overrides)") {
+ setSendReceiptsGroups(groupReceipts, clearOverrides: false)
+ }
+ Button(groupReceipts ? "Enable for all" : "Disable for all", role: .destructive) {
+ setSendReceiptsGroups(groupReceipts, clearOverrides: true)
+ }
+ Button("Cancel", role: .cancel) {
+ groupReceiptsReset = true
+ groupReceipts.toggle()
+ }
+ }
+ }
+ .navigationTitle("More privacy")
+ .modifier(ThemedBackground(grouped: true))
+ }
+
private func setEncryptLocalFiles(_ enable: Bool) {
do {
try apiSetEncryptLocalFiles(enable)
diff --git a/apps/ios/Shared/Views/UserSettings/SetDeliveryReceiptsView.swift b/apps/ios/Shared/Views/UserSettings/SetDeliveryReceiptsView.swift
index e03dace43d..e46edbc5af 100644
--- a/apps/ios/Shared/Views/UserSettings/SetDeliveryReceiptsView.swift
+++ b/apps/ios/Shared/Views/UserSettings/SetDeliveryReceiptsView.swift
@@ -69,7 +69,7 @@ struct SetDeliveryReceiptsView: View {
Button {
AlertManager.shared.showAlert(Alert(
title: Text("Delivery receipts are disabled!"),
- message: Text("You can enable them later via app Privacy & Security settings."),
+ message: Text("You can enable them later via app Your privacy settings."),
primaryButton: .default(Text("Don't show again")) {
m.setDeliveryReceipts = false
privacyDeliveryReceiptsSet.set(true)
diff --git a/apps/ios/Shared/Views/UserSettings/SettingsView.swift b/apps/ios/Shared/Views/UserSettings/SettingsView.swift
index a903329454..93f32a53a6 100644
--- a/apps/ios/Shared/Views/UserSettings/SettingsView.swift
+++ b/apps/ios/Shared/Views/UserSettings/SettingsView.swift
@@ -290,47 +290,7 @@ struct SettingsView: View {
func settingsView() -> some View {
List {
- let user = chatModel.currentUser
- Section(header: Text("Settings").foregroundColor(theme.colors.secondary)) {
- NavigationLink {
- NotificationsView()
- .navigationTitle("Notifications")
- .modifier(ThemedBackground(grouped: true))
- } label: {
- HStack {
- notificationsIcon()
- Text("Notifications")
- }
- }
- .disabled(chatModel.chatRunning != true)
-
- NavigationLink {
- NetworkAndServers()
- .navigationTitle("Network & servers")
- .modifier(ThemedBackground(grouped: true))
- } label: {
- settingsRow("externaldrive.connected.to.line.below", color: theme.colors.secondary) { Text("Network & servers") }
- }
- .disabled(chatModel.chatRunning != true)
-
- NavigationLink {
- CallSettings()
- .navigationTitle("Your calls")
- .modifier(ThemedBackground(grouped: true))
- } label: {
- settingsRow("video", color: theme.colors.secondary) { Text("Audio & video calls") }
- }
- .disabled(chatModel.chatRunning != true)
-
- NavigationLink {
- PrivacySettings()
- .navigationTitle("Your privacy")
- .modifier(ThemedBackground(grouped: true))
- } label: {
- settingsRow("lock", color: theme.colors.secondary) { Text("Privacy & security") }
- }
- .disabled(chatModel.chatRunning != true)
-
+ Section(header: Text(verbatim: "").foregroundColor(theme.colors.secondary)) {
if UIApplication.shared.supportsAlternateIcons {
NavigationLink {
AppearanceSettings()
@@ -341,10 +301,24 @@ struct SettingsView: View {
}
.disabled(chatModel.chatRunning != true)
}
- }
- Section(header: Text("Chat database").foregroundColor(theme.colors.secondary)) {
+ NavigationLink {
+ PrivacySettings()
+ .navigationTitle("Your privacy")
+ .modifier(ThemedBackground(grouped: true))
+ } label: {
+ settingsRow("lock", color: theme.colors.secondary) { Text("Your privacy") }
+ }
+ .disabled(chatModel.chatRunning != true)
+
+ NavigationLink {
+ helpAndSupportView
+ } label: {
+ settingsRow("questionmark", color: theme.colors.secondary) { Text("Help & support") }
+ }
+
chatDatabaseRow()
+
NavigationLink {
MigrateFromDevice(showProgressOnSettings: $showProgress)
.toolbar {
@@ -360,6 +334,58 @@ struct SettingsView: View {
}
}
+ Section(header: Text("Advanced settings").foregroundColor(theme.colors.secondary)) {
+ NavigationLink {
+ NetworkAndServers()
+ .navigationTitle("Network & servers")
+ .modifier(ThemedBackground(grouped: true))
+ } label: {
+ settingsRow("externaldrive.connected.to.line.below", color: theme.colors.secondary) { Text("Network & servers") }
+ }
+ .disabled(chatModel.chatRunning != true)
+
+ NavigationLink {
+ NotificationsView()
+ .navigationTitle("Notifications")
+ .modifier(ThemedBackground(grouped: true))
+ } label: {
+ HStack {
+ notificationsIcon()
+ Text("Notifications")
+ }
+ }
+ .disabled(chatModel.chatRunning != true)
+
+ NavigationLink {
+ CallSettings()
+ .navigationTitle("Your calls")
+ .modifier(ThemedBackground(grouped: true))
+ } label: {
+ settingsRow("video", color: theme.colors.secondary) { Text("Audio & video calls") }
+ }
+ .disabled(chatModel.chatRunning != true)
+
+ NavigationLink {
+ VersionView()
+ .navigationBarTitle("App version")
+ .modifier(ThemedBackground())
+ } label: {
+ Text(verbatim: "v\(appVersion ?? "?")")
+ }
+ }
+ }
+ .navigationTitle("Your settings")
+ .modifier(ThemedBackground(grouped: true))
+ .onDisappear {
+ chatModel.showingTerminal = false
+ chatModel.terminalItems = []
+ }
+ }
+
+ @ViewBuilder
+ private var helpAndSupportView: some View {
+ List {
+ let user = chatModel.currentUser
Section(header: Text("Help").foregroundColor(theme.colors.secondary)) {
if let user = user {
NavigationLink {
@@ -378,6 +404,7 @@ struct SettingsView: View {
} label: {
settingsRow("plus", color: theme.colors.secondary) { Text("What's new") }
}
+
NavigationLink {
SimpleXInfo(onboarding: false)
.navigationBarTitle("", displayMode: .inline)
@@ -386,6 +413,9 @@ struct SettingsView: View {
} label: {
settingsRow("info", color: theme.colors.secondary) { Text("About SimpleX Chat") }
}
+ }
+
+ Section(header: Text("Contact").foregroundColor(theme.colors.secondary)) {
settingsRow("number", color: theme.colors.secondary) {
Button("Send questions and ideas") {
dismiss()
@@ -398,7 +428,7 @@ struct SettingsView: View {
settingsRow("envelope", color: theme.colors.secondary) { Text("[Send us email](mailto:chat@simplex.chat)") }
}
- Section(header: Text("Support SimpleX Chat").foregroundColor(theme.colors.secondary)) {
+ Section(header: Text("Support the project").foregroundColor(theme.colors.secondary)) {
settingsRow("keyboard", color: theme.colors.secondary) {
ExternalLink("Contribute", destination: URL(string: "https://github.com/simplex-chat/simplex-chat#contribute")!)
}
@@ -421,42 +451,21 @@ struct SettingsView: View {
}
}
}
-
- Section(header: Text("Develop").foregroundColor(theme.colors.secondary)) {
- NavigationLink {
- DeveloperView()
- .navigationTitle("Developer tools")
- .modifier(ThemedBackground(grouped: true))
- } label: {
- settingsRow("chevron.left.forwardslash.chevron.right", color: theme.colors.secondary) { Text("Developer tools") }
- }
- NavigationLink {
- VersionView()
- .navigationBarTitle("App version")
- .modifier(ThemedBackground())
- } label: {
- Text("v\(appVersion ?? "?") (\(appBuild ?? "?"))")
- }
- }
}
- .navigationTitle("Your settings")
+ .navigationTitle("Help & support")
.modifier(ThemedBackground(grouped: true))
- .onDisappear {
- chatModel.showingTerminal = false
- chatModel.terminalItems = []
- }
}
-
+
private func chatDatabaseRow() -> some View {
NavigationLink {
DatabaseView(dismissSettingsSheet: dismiss, chatItemTTL: chatModel.chatItemTTL)
- .navigationTitle("Your chat database")
+ .navigationTitle("Chat data")
.modifier(ThemedBackground(grouped: true))
} label: {
let color: Color = chatModel.chatDbEncrypted == false ? .orange : theme.colors.secondary
settingsRow("internaldrive", color: color) {
HStack {
- Text("Database passphrase & export")
+ Text("Chat data")
Spacer()
if chatModel.chatRunning == false {
Image(systemName: "exclamationmark.octagon.fill").foregroundColor(.red)
diff --git a/apps/ios/Shared/Views/UserSettings/VersionView.swift b/apps/ios/Shared/Views/UserSettings/VersionView.swift
index 0fc2b4cb3e..e30c11699e 100644
--- a/apps/ios/Shared/Views/UserSettings/VersionView.swift
+++ b/apps/ios/Shared/Views/UserSettings/VersionView.swift
@@ -10,21 +10,33 @@ import SwiftUI
import SimpleXChat
struct VersionView: View {
+ @EnvironmentObject var theme: AppTheme
@State var versionInfo: CoreVersionInfo?
var body: some View {
- VStack(alignment: .leading) {
- Text("App version: v\(appVersion ?? "?")")
- Text("App build: \(appBuild ?? "?")")
- if let info = versionInfo {
- Text("Core version: v\(info.version)")
- if let v = try? AttributedString(markdown: "simplexmq: v\(info.simplexmqVersion) ([\(info.simplexmqCommit.prefix(7))](https://github.com/simplex-chat/simplexmq/commit/\(info.simplexmqCommit)))") {
- Text(v)
+ List {
+ Section {
+ Text("App version: v\(appVersion ?? "?")")
+ Text("App build: \(appBuild ?? "?")")
+ if let info = versionInfo {
+ Text("Core version: v\(info.version)")
+ if let v = try? AttributedString(markdown: "simplexmq: v\(info.simplexmqVersion) ([\(info.simplexmqCommit.prefix(7))](https://github.com/simplex-chat/simplexmq/commit/\(info.simplexmqCommit)))") {
+ Text(v)
+ }
+ }
+ }
+
+ Section {
+ NavigationLink {
+ DeveloperView()
+ .navigationTitle("Developer")
+ .modifier(ThemedBackground(grouped: true))
+ } label: {
+ Text("Developer")
}
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
- .padding()
.onAppear {
do {
versionInfo = try apiGetVersion()
diff --git a/apps/ios/SimpleX Localizations/ar.xcloc/Localized Contents/ar.xliff b/apps/ios/SimpleX Localizations/ar.xcloc/Localized Contents/ar.xliff
index 427430b833..bd8d6a17ef 100644
--- a/apps/ios/SimpleX Localizations/ar.xcloc/Localized Contents/ar.xliff
+++ b/apps/ios/SimpleX Localizations/ar.xcloc/Localized Contents/ar.xliff
@@ -1157,8 +1157,8 @@
يطور
No comment provided by engineer.
-
- Developer tools
+
+ Developer
أدوات المطور
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff
index 364cee97e5..89d5014c95 100644
--- a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff
+++ b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff
@@ -3014,8 +3014,8 @@ alert button
Developer options
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Инструменти за разработчици
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/bn.xcloc/Localized Contents/bn.xliff b/apps/ios/SimpleX Localizations/bn.xcloc/Localized Contents/bn.xliff
index fbda1abd29..bdb0c0ce24 100644
--- a/apps/ios/SimpleX Localizations/bn.xcloc/Localized Contents/bn.xliff
+++ b/apps/ios/SimpleX Localizations/bn.xcloc/Localized Contents/bn.xliff
@@ -1223,8 +1223,8 @@
Develop
No comment provided by engineer.
-
- Developer tools
+
+ Developer
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff
index 5ba29ec846..f7beecf4ba 100644
--- a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff
+++ b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff
@@ -2904,8 +2904,8 @@ alert button
Developer options
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Nástroje pro vývojáře
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff
index 797a489c92..822c13649e 100644
--- a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff
+++ b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff
@@ -3130,8 +3130,8 @@ alert button
Optionen für Entwickler
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Entwicklertools
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/el.xcloc/Localized Contents/el.xliff b/apps/ios/SimpleX Localizations/el.xcloc/Localized Contents/el.xliff
index 7a560bb41b..181f51eb99 100644
--- a/apps/ios/SimpleX Localizations/el.xcloc/Localized Contents/el.xliff
+++ b/apps/ios/SimpleX Localizations/el.xcloc/Localized Contents/el.xliff
@@ -1100,8 +1100,8 @@ Available in v5.1
Develop
No comment provided by engineer.
-
- Developer tools
+
+ Developer
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff
index c108dcc904..bd498d53e3 100644
--- a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff
+++ b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff
@@ -3140,9 +3140,9 @@ alert button
Developer options
No comment provided by engineer.
-
- Developer tools
- Developer tools
+
+ Developer
+ Developer
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff
index d93e692a63..60de758c9c 100644
--- a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff
+++ b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff
@@ -3130,8 +3130,8 @@ alert button
Opciones desarrollador
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Herramientas desarrollo
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff
index 5656516b7d..c818fdc472 100644
--- a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff
+++ b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff
@@ -2791,8 +2791,8 @@ alert button
Developer options
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Kehittäjätyökalut
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff
index 3ea0859d76..4d1616df20 100644
--- a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff
+++ b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff
@@ -3039,8 +3039,8 @@ alert button
Options pour les développeurs
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Outils du développeur
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/he.xcloc/Localized Contents/he.xliff b/apps/ios/SimpleX Localizations/he.xcloc/Localized Contents/he.xliff
index f94d6cefd8..a22d30dd73 100644
--- a/apps/ios/SimpleX Localizations/he.xcloc/Localized Contents/he.xliff
+++ b/apps/ios/SimpleX Localizations/he.xcloc/Localized Contents/he.xliff
@@ -1356,8 +1356,8 @@ Available in v5.1
לְפַתֵחַ
No comment provided by engineer.
-
- Developer tools
+
+ Developer
כלי מפתחים
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/hr.xcloc/Localized Contents/hr.xliff b/apps/ios/SimpleX Localizations/hr.xcloc/Localized Contents/hr.xliff
index 2aa945f603..33fe9a0e9c 100644
--- a/apps/ios/SimpleX Localizations/hr.xcloc/Localized Contents/hr.xliff
+++ b/apps/ios/SimpleX Localizations/hr.xcloc/Localized Contents/hr.xliff
@@ -1012,8 +1012,8 @@
Develop
No comment provided by engineer.
-
- Developer tools
+
+ Developer
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff b/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff
index 129436ecb0..11b447dc2b 100644
--- a/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff
+++ b/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff
@@ -3130,8 +3130,8 @@ alert button
Fejlesztői beállítások
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Fejlesztői eszközök
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff
index 469da88ce2..876cdb10bb 100644
--- a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff
+++ b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff
@@ -3130,8 +3130,8 @@ alert button
Opzioni sviluppatore
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Strumenti di sviluppo
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff
index 13396b13a4..ff0d085c08 100644
--- a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff
+++ b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff
@@ -2891,8 +2891,8 @@ alert button
開発者向けの設定
No comment provided by engineer.
-
- Developer tools
+
+ Developer
開発ツール
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/ko.xcloc/Localized Contents/ko.xliff b/apps/ios/SimpleX Localizations/ko.xcloc/Localized Contents/ko.xliff
index ca51a875c7..01b5e2b9a2 100644
--- a/apps/ios/SimpleX Localizations/ko.xcloc/Localized Contents/ko.xliff
+++ b/apps/ios/SimpleX Localizations/ko.xcloc/Localized Contents/ko.xliff
@@ -1141,8 +1141,8 @@
Develop
No comment provided by engineer.
-
- Developer tools
+
+ Developer
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/lt.xcloc/Localized Contents/lt.xliff b/apps/ios/SimpleX Localizations/lt.xcloc/Localized Contents/lt.xliff
index 4b51d66a34..5aa2a98854 100644
--- a/apps/ios/SimpleX Localizations/lt.xcloc/Localized Contents/lt.xliff
+++ b/apps/ios/SimpleX Localizations/lt.xcloc/Localized Contents/lt.xliff
@@ -1005,8 +1005,8 @@
Develop
No comment provided by engineer.
-
- Developer tools
+
+ Developer
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff
index 9f1818fba9..a7670a4475 100644
--- a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff
+++ b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff
@@ -3040,8 +3040,8 @@ alert button
Ontwikkelaars opties
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Ontwikkel gereedschap
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff
index 2644708927..a60b5891d4 100644
--- a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff
+++ b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff
@@ -3063,8 +3063,8 @@ alert button
Opcje deweloperskie
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Narzędzia deweloperskie
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/pt-BR.xcloc/Localized Contents/pt-BR.xliff b/apps/ios/SimpleX Localizations/pt-BR.xcloc/Localized Contents/pt-BR.xliff
index d9af0624bf..032a33ff62 100644
--- a/apps/ios/SimpleX Localizations/pt-BR.xcloc/Localized Contents/pt-BR.xliff
+++ b/apps/ios/SimpleX Localizations/pt-BR.xcloc/Localized Contents/pt-BR.xliff
@@ -1179,8 +1179,8 @@
Desenvolver
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Ferramentas de desenvolvimento
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/pt.xcloc/Localized Contents/pt.xliff b/apps/ios/SimpleX Localizations/pt.xcloc/Localized Contents/pt.xliff
index e4fac55bcb..3905130e84 100644
--- a/apps/ios/SimpleX Localizations/pt.xcloc/Localized Contents/pt.xliff
+++ b/apps/ios/SimpleX Localizations/pt.xcloc/Localized Contents/pt.xliff
@@ -1203,8 +1203,8 @@ Available in v5.1
Develop
No comment provided by engineer.
-
- Developer tools
+
+ Developer
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff
index a3971c0325..22df6680f6 100644
--- a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff
+++ b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff
@@ -3130,8 +3130,8 @@ alert button
Опции разработчика
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Инструменты разработчика
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff
index cd2e30977d..11d6b28091 100644
--- a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff
+++ b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff
@@ -2779,8 +2779,8 @@ alert button
Developer options
No comment provided by engineer.
-
- Developer tools
+
+ Developer
เครื่องมือสำหรับนักพัฒนา
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff b/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff
index 1189b53e3c..b673b609b9 100644
--- a/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff
+++ b/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff
@@ -3066,8 +3066,8 @@ alert button
Geliştirici seçenekleri
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Geliştirici araçları
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff
index 49f9e21eda..3c0c6ef8de 100644
--- a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff
+++ b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff
@@ -3050,8 +3050,8 @@ alert button
Можливості для розробників
No comment provided by engineer.
-
- Developer tools
+
+ Developer
Інструменти для розробників
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff
index 8823f17204..9001375615 100644
--- a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff
+++ b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff
@@ -3060,8 +3060,8 @@ alert button
开发者选项
No comment provided by engineer.
-
- Developer tools
+
+ Developer
开发者工具
No comment provided by engineer.
diff --git a/apps/ios/SimpleX Localizations/zh-Hant.xcloc/Localized Contents/zh-Hant.xliff b/apps/ios/SimpleX Localizations/zh-Hant.xcloc/Localized Contents/zh-Hant.xliff
index 0e4e383b52..ebd6f4da71 100644
--- a/apps/ios/SimpleX Localizations/zh-Hant.xcloc/Localized Contents/zh-Hant.xliff
+++ b/apps/ios/SimpleX Localizations/zh-Hant.xcloc/Localized Contents/zh-Hant.xliff
@@ -1148,8 +1148,8 @@
開發
No comment provided by engineer.
-
- Developer tools
+
+ Developer
開發者工具
No comment provided by engineer.
diff --git a/apps/ios/SimpleX SE/ShareModel.swift b/apps/ios/SimpleX SE/ShareModel.swift
index 18f3e2c344..9790e5944f 100644
--- a/apps/ios/SimpleX SE/ShareModel.swift
+++ b/apps/ios/SimpleX SE/ShareModel.swift
@@ -75,7 +75,7 @@ class ShareModel: ObservableObject {
func setup(context: NSExtensionContext) {
if appLocalAuthEnabledGroupDefault.get() && !allowShareExtensionGroupDefault.get() {
- errorAlert = ErrorAlert(title: "App is locked!", message: "You can allow sharing in Privacy & Security / SimpleX Lock settings.")
+ errorAlert = ErrorAlert(title: "App is locked!", message: "You can allow sharing in Your privacy / SimpleX Lock settings.")
return
}
if let item = context.inputItems.first as? NSExtensionItem,
diff --git a/apps/ios/SimpleX SE/de.lproj/Localizable.strings b/apps/ios/SimpleX SE/de.lproj/Localizable.strings
index df368686e8..1d2e5a4b01 100644
--- a/apps/ios/SimpleX SE/de.lproj/Localizable.strings
+++ b/apps/ios/SimpleX SE/de.lproj/Localizable.strings
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "Falsches Datenbank-Passwort";
/* No comment provided by engineer. */
-"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Sie können das Teilen in den Einstellungen zu Datenschutz & Sicherheit / SimpleX-Sperre erlauben.";
+"You can allow sharing in Your privacy / SimpleX Lock settings." = "Sie können das Teilen in den Einstellungen zu Datenschutz & Sicherheit / SimpleX-Sperre erlauben.";
diff --git a/apps/ios/SimpleX SE/es.lproj/Localizable.strings b/apps/ios/SimpleX SE/es.lproj/Localizable.strings
index 4cc5029537..5bb42b4f0a 100644
--- a/apps/ios/SimpleX SE/es.lproj/Localizable.strings
+++ b/apps/ios/SimpleX SE/es.lproj/Localizable.strings
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "Contraseña incorrecta de la base de datos";
/* No comment provided by engineer. */
-"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Puedes dar permiso para compartir en Privacidad y Seguridad / Bloque SimpleX.";
+"You can allow sharing in Your privacy / SimpleX Lock settings." = "Puedes dar permiso para compartir en Privacidad y Seguridad / Bloque SimpleX.";
diff --git a/apps/ios/SimpleX SE/fr.lproj/Localizable.strings b/apps/ios/SimpleX SE/fr.lproj/Localizable.strings
index 46a458b471..6b492ee882 100644
--- a/apps/ios/SimpleX SE/fr.lproj/Localizable.strings
+++ b/apps/ios/SimpleX SE/fr.lproj/Localizable.strings
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "Mauvaise phrase secrète pour la base de données";
/* No comment provided by engineer. */
-"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Vous pouvez autoriser le partage dans les paramètres Confidentialité et sécurité / SimpleX Lock.";
+"You can allow sharing in Your privacy / SimpleX Lock settings." = "Vous pouvez autoriser le partage dans les paramètres Confidentialité et sécurité / SimpleX Lock.";
diff --git a/apps/ios/SimpleX SE/hu.lproj/Localizable.strings b/apps/ios/SimpleX SE/hu.lproj/Localizable.strings
index 3aad39c5d1..dae06b1d73 100644
--- a/apps/ios/SimpleX SE/hu.lproj/Localizable.strings
+++ b/apps/ios/SimpleX SE/hu.lproj/Localizable.strings
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "Érvénytelen adatbázis-jelmondat";
/* No comment provided by engineer. */
-"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "A megosztást az Adatvédelem és biztonság / SimpleX-zár menüben engedélyezheti.";
+"You can allow sharing in Your privacy / SimpleX Lock settings." = "A megosztást az Adatvédelem és biztonság / SimpleX-zár menüben engedélyezheti.";
diff --git a/apps/ios/SimpleX SE/it.lproj/Localizable.strings b/apps/ios/SimpleX SE/it.lproj/Localizable.strings
index e3d34650a3..3b27092f24 100644
--- a/apps/ios/SimpleX SE/it.lproj/Localizable.strings
+++ b/apps/ios/SimpleX SE/it.lproj/Localizable.strings
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "Password del database sbagliata";
/* No comment provided by engineer. */
-"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Puoi consentire la condivisione in Privacy e sicurezza / impostazioni di SimpleX Lock.";
+"You can allow sharing in Your privacy / SimpleX Lock settings." = "Puoi consentire la condivisione in Privacy e sicurezza / impostazioni di SimpleX Lock.";
diff --git a/apps/ios/SimpleX SE/nl.lproj/Localizable.strings b/apps/ios/SimpleX SE/nl.lproj/Localizable.strings
index e5d2487b54..050cb1a735 100644
--- a/apps/ios/SimpleX SE/nl.lproj/Localizable.strings
+++ b/apps/ios/SimpleX SE/nl.lproj/Localizable.strings
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "Verkeerde database wachtwoord";
/* No comment provided by engineer. */
-"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "U kunt delen toestaan in de instellingen voor Privacy en beveiliging / SimpleX Lock.";
+"You can allow sharing in Your privacy / SimpleX Lock settings." = "U kunt delen toestaan in de instellingen voor Privacy en beveiliging / SimpleX Lock.";
diff --git a/apps/ios/SimpleX SE/pl.lproj/Localizable.strings b/apps/ios/SimpleX SE/pl.lproj/Localizable.strings
index c563431c28..0755e1e374 100644
--- a/apps/ios/SimpleX SE/pl.lproj/Localizable.strings
+++ b/apps/ios/SimpleX SE/pl.lproj/Localizable.strings
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "Nieprawidłowe hasło bazy danych";
/* No comment provided by engineer. */
-"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Możesz zezwolić na udostępnianie w ustawieniach Prywatność i bezpieczeństwo / Blokada SimpleX.";
+"You can allow sharing in Your privacy / SimpleX Lock settings." = "Możesz zezwolić na udostępnianie w ustawieniach Prywatność i bezpieczeństwo / Blokada SimpleX.";
diff --git a/apps/ios/SimpleX SE/ru.lproj/Localizable.strings b/apps/ios/SimpleX SE/ru.lproj/Localizable.strings
index e4c8c000d4..90a5841738 100644
--- a/apps/ios/SimpleX SE/ru.lproj/Localizable.strings
+++ b/apps/ios/SimpleX SE/ru.lproj/Localizable.strings
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "Неправильный пароль базы данных";
/* No comment provided by engineer. */
-"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Вы можете разрешить функцию Поделиться в настройках Конфиденциальности / Блокировка SimpleX.";
+"You can allow sharing in Your privacy / SimpleX Lock settings." = "Вы можете разрешить функцию Поделиться в настройках Конфиденциальности / Блокировка SimpleX.";
diff --git a/apps/ios/SimpleX SE/tr.lproj/Localizable.strings b/apps/ios/SimpleX SE/tr.lproj/Localizable.strings
index baef71c127..69b122832d 100644
--- a/apps/ios/SimpleX SE/tr.lproj/Localizable.strings
+++ b/apps/ios/SimpleX SE/tr.lproj/Localizable.strings
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "Yanlış veritabanı parolası";
/* No comment provided by engineer. */
-"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Gizlilik ve Güvenlik / SimpleX Lock ayarlarından paylaşıma izin verebilirsiniz.";
+"You can allow sharing in Your privacy / SimpleX Lock settings." = "Gizlilik ve Güvenlik / SimpleX Lock ayarlarından paylaşıma izin verebilirsiniz.";
diff --git a/apps/ios/SimpleX SE/uk.lproj/Localizable.strings b/apps/ios/SimpleX SE/uk.lproj/Localizable.strings
index a6da81185e..7574470d01 100644
--- a/apps/ios/SimpleX SE/uk.lproj/Localizable.strings
+++ b/apps/ios/SimpleX SE/uk.lproj/Localizable.strings
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "Неправильна ключова фраза до бази даних";
/* No comment provided by engineer. */
-"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Ви можете дозволити спільний доступ у налаштуваннях Конфіденційність і безпека / SimpleX Lock.";
+"You can allow sharing in Your privacy / SimpleX Lock settings." = "Ви можете дозволити спільний доступ у налаштуваннях Конфіденційність і безпека / SimpleX Lock.";
diff --git a/apps/ios/SimpleX SE/zh-Hans.lproj/Localizable.strings b/apps/ios/SimpleX SE/zh-Hans.lproj/Localizable.strings
index 362e2edb74..fc046ab087 100644
--- a/apps/ios/SimpleX SE/zh-Hans.lproj/Localizable.strings
+++ b/apps/ios/SimpleX SE/zh-Hans.lproj/Localizable.strings
@@ -107,5 +107,5 @@
"Wrong database passphrase" = "数据库密码错误";
/* No comment provided by engineer. */
-"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "您可以在 \"隐私与安全\"/\"SimpleX Lock \"设置中允许共享。";
+"You can allow sharing in Your privacy / SimpleX Lock settings." = "您可以在 \"隐私与安全\"/\"SimpleX Lock \"设置中允许共享。";
diff --git a/apps/ios/bg.lproj/Localizable.strings b/apps/ios/bg.lproj/Localizable.strings
index ec869e05b4..68f2cfe502 100644
--- a/apps/ios/bg.lproj/Localizable.strings
+++ b/apps/ios/bg.lproj/Localizable.strings
@@ -1659,7 +1659,7 @@ alert button */
"Develop" = "Разработване";
/* No comment provided by engineer. */
-"Developer tools" = "Инструменти за разработчици";
+"Developer" = "Инструменти за разработчици";
/* No comment provided by engineer. */
"Device" = "Устройство";
@@ -3217,7 +3217,7 @@ alert button */
"Preview" = "Визуализация";
/* No comment provided by engineer. */
-"Privacy & security" = "Поверителност и сигурност";
+"Your privacy" = "Поверителност и сигурност";
/* No comment provided by engineer. */
"Private filenames" = "Поверителни имена на файлове";
@@ -4452,7 +4452,7 @@ server test failure */
"You can enable later via Settings" = "Можете да активирате по-късно през Настройки";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Можете да ги активирате по-късно през настройките за \"Поверителност и сигурност\" на приложението.";
+"You can enable them later via app Your privacy settings." = "Можете да ги активирате по-късно през настройките за \"Поверителност и сигурност\" на приложението.";
/* No comment provided by engineer. */
"You can give another try." = "Можете да опитате още веднъж.";
diff --git a/apps/ios/cs.lproj/Localizable.strings b/apps/ios/cs.lproj/Localizable.strings
index fc4b3f0fc6..0b74ef9504 100644
--- a/apps/ios/cs.lproj/Localizable.strings
+++ b/apps/ios/cs.lproj/Localizable.strings
@@ -1306,7 +1306,7 @@ alert button */
"Develop" = "Vyvinout";
/* No comment provided by engineer. */
-"Developer tools" = "Nástroje pro vývojáře";
+"Developer" = "Nástroje pro vývojáře";
/* No comment provided by engineer. */
"Device" = "Zařízení";
@@ -2578,7 +2578,7 @@ alert button */
"Preview" = "Náhled";
/* No comment provided by engineer. */
-"Privacy & security" = "Ochrana osobních údajů a zabezpečení";
+"Your privacy" = "Ochrana osobních údajů a zabezpečení";
/* No comment provided by engineer. */
"Private filenames" = "Soukromé názvy souborů";
@@ -3543,7 +3543,7 @@ server test failure */
"You can enable later via Settings" = "Můžete povolit později v Nastavení";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Můžete je povolit později v nastavení Soukromí & Bezpečnosti aplikace";
+"You can enable them later via app Your privacy settings." = "Můžete je povolit později v nastavení Soukromí & Bezpečnosti aplikace";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right." = "Profil uživatele můžete skrýt nebo ztlumit - přejeďte prstem doprava.";
diff --git a/apps/ios/de.lproj/Localizable.strings b/apps/ios/de.lproj/Localizable.strings
index 2c4e37791b..80246b727b 100644
--- a/apps/ios/de.lproj/Localizable.strings
+++ b/apps/ios/de.lproj/Localizable.strings
@@ -2064,7 +2064,7 @@ alert button */
"Developer options" = "Optionen für Entwickler";
/* No comment provided by engineer. */
-"Developer tools" = "Entwicklertools";
+"Developer" = "Entwicklertools";
/* No comment provided by engineer. */
"Device" = "Gerät";
@@ -4533,7 +4533,7 @@ alert button */
"Previously connected servers" = "Bisher verbundene Server";
/* No comment provided by engineer. */
-"Privacy & security" = "Datenschutz & Sicherheit";
+"Your privacy" = "Datenschutz & Sicherheit";
/* No comment provided by engineer. */
"Privacy for your customers." = "Schutz der Privatsphäre Ihrer Kunden.";
@@ -6759,7 +6759,7 @@ server test failure */
"You can enable later via Settings" = "Sie können diese später in den Einstellungen aktivieren";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Sie können diese später in den Datenschutz & Sicherheits-Einstellungen der App aktivieren.";
+"You can enable them later via app Your privacy settings." = "Sie können diese später in den Datenschutz & Sicherheits-Einstellungen der App aktivieren.";
/* No comment provided by engineer. */
"You can give another try." = "Sie können es nochmal probieren.";
diff --git a/apps/ios/es.lproj/Localizable.strings b/apps/ios/es.lproj/Localizable.strings
index cf03ae6dbf..e0611c0afc 100644
--- a/apps/ios/es.lproj/Localizable.strings
+++ b/apps/ios/es.lproj/Localizable.strings
@@ -2064,7 +2064,7 @@ alert button */
"Developer options" = "Opciones desarrollador";
/* No comment provided by engineer. */
-"Developer tools" = "Herramientas desarrollo";
+"Developer" = "Herramientas desarrollo";
/* No comment provided by engineer. */
"Device" = "Dispositivo";
@@ -4533,7 +4533,7 @@ alert button */
"Previously connected servers" = "Servidores conectados previamente";
/* No comment provided by engineer. */
-"Privacy & security" = "Seguridad y Privacidad";
+"Your privacy" = "Seguridad y Privacidad";
/* No comment provided by engineer. */
"Privacy for your customers." = "Privacidad para tus clientes.";
@@ -6759,7 +6759,7 @@ server test failure */
"You can enable later via Settings" = "Puedes activar más tarde en Configuración";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Puedes activarlos más tarde en la configuración de Privacidad y Seguridad.";
+"You can enable them later via app Your privacy settings." = "Puedes activarlos más tarde en la configuración de Privacidad y Seguridad.";
/* No comment provided by engineer. */
"You can give another try." = "Puedes intentarlo de nuevo.";
diff --git a/apps/ios/fi.lproj/Localizable.strings b/apps/ios/fi.lproj/Localizable.strings
index 3b1bd6523c..36b516374e 100644
--- a/apps/ios/fi.lproj/Localizable.strings
+++ b/apps/ios/fi.lproj/Localizable.strings
@@ -982,7 +982,7 @@ alert button */
"Develop" = "Kehitä";
/* No comment provided by engineer. */
-"Developer tools" = "Kehittäjätyökalut";
+"Developer" = "Kehittäjätyökalut";
/* No comment provided by engineer. */
"Device" = "Laite";
@@ -2232,7 +2232,7 @@ new chat action */
"Preview" = "Esikatselu";
/* No comment provided by engineer. */
-"Privacy & security" = "Yksityisyys ja turvallisuus";
+"Your privacy" = "Yksityisyys ja turvallisuus";
/* No comment provided by engineer. */
"Private filenames" = "Yksityiset tiedostonimet";
@@ -3179,7 +3179,7 @@ server test failure */
"You can enable later via Settings" = "Voit ottaa käyttöön myöhemmin asetusten kautta";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Voit ottaa ne käyttöön myöhemmin sovelluksen Yksityisyys & Turvallisuus -asetuksista.";
+"You can enable them later via app Your privacy settings." = "Voit ottaa ne käyttöön myöhemmin sovelluksen Yksityisyys & Turvallisuus -asetuksista.";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right." = "Voit piilottaa tai mykistää käyttäjäprofiilin pyyhkäisemällä sitä oikealle.";
diff --git a/apps/ios/fr.lproj/Localizable.strings b/apps/ios/fr.lproj/Localizable.strings
index 91cd6f3078..98cdb4aec8 100644
--- a/apps/ios/fr.lproj/Localizable.strings
+++ b/apps/ios/fr.lproj/Localizable.strings
@@ -1745,7 +1745,7 @@ alert button */
"Developer options" = "Options pour les développeurs";
/* No comment provided by engineer. */
-"Developer tools" = "Outils du développeur";
+"Developer" = "Outils du développeur";
/* No comment provided by engineer. */
"Device" = "Appareil";
@@ -3742,7 +3742,7 @@ alert button */
"Previously connected servers" = "Serveurs précédemment connectés";
/* No comment provided by engineer. */
-"Privacy & security" = "Vie privée et sécurité";
+"Your privacy" = "Vie privée et sécurité";
/* No comment provided by engineer. */
"Privacy for your customers." = "Respect de la vie privée de vos clients.";
@@ -5448,7 +5448,7 @@ server test failure */
"You can enable later via Settings" = "Vous pouvez l'activer ultérieurement via Paramètres";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Vous pouvez les activer ultérieurement via les paramètres de Confidentialité et Sécurité de l'application.";
+"You can enable them later via app Your privacy settings." = "Vous pouvez les activer ultérieurement via les paramètres de Confidentialité et Sécurité de l'application.";
/* No comment provided by engineer. */
"You can give another try." = "Vous pouvez faire un nouvel essai.";
diff --git a/apps/ios/hu.lproj/Localizable.strings b/apps/ios/hu.lproj/Localizable.strings
index 029fb9edd5..362d9157fd 100644
--- a/apps/ios/hu.lproj/Localizable.strings
+++ b/apps/ios/hu.lproj/Localizable.strings
@@ -2064,7 +2064,7 @@ alert button */
"Developer options" = "Fejlesztői beállítások";
/* No comment provided by engineer. */
-"Developer tools" = "Fejlesztői eszközök";
+"Developer" = "Fejlesztői eszközök";
/* No comment provided by engineer. */
"Device" = "Eszköz";
@@ -4533,7 +4533,7 @@ alert button */
"Previously connected servers" = "Korábban kapcsolódott kiszolgálók";
/* No comment provided by engineer. */
-"Privacy & security" = "Adatvédelem és biztonság";
+"Your privacy" = "Adatvédelem és biztonság";
/* No comment provided by engineer. */
"Privacy for your customers." = "Saját ügyfeleinek adatvédelme.";
@@ -6759,7 +6759,7 @@ server test failure */
"You can enable later via Settings" = "Később engedélyezheti a beállításokban";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Később engedélyezheti őket az „Adatvédelem és biztonság” menüben.";
+"You can enable them later via app Your privacy settings." = "Később engedélyezheti őket az „Adatvédelem és biztonság” menüben.";
/* No comment provided by engineer. */
"You can give another try." = "Megpróbálhatja még egyszer.";
diff --git a/apps/ios/it.lproj/Localizable.strings b/apps/ios/it.lproj/Localizable.strings
index c882eb662c..8d4fa3532b 100644
--- a/apps/ios/it.lproj/Localizable.strings
+++ b/apps/ios/it.lproj/Localizable.strings
@@ -2064,7 +2064,7 @@ alert button */
"Developer options" = "Opzioni sviluppatore";
/* No comment provided by engineer. */
-"Developer tools" = "Strumenti di sviluppo";
+"Developer" = "Strumenti di sviluppo";
/* No comment provided by engineer. */
"Device" = "Dispositivo";
@@ -4533,7 +4533,7 @@ alert button */
"Previously connected servers" = "Server precedentemente connessi";
/* No comment provided by engineer. */
-"Privacy & security" = "Privacy e sicurezza";
+"Your privacy" = "Privacy e sicurezza";
/* No comment provided by engineer. */
"Privacy for your customers." = "Privacy per i tuoi clienti.";
@@ -6759,7 +6759,7 @@ server test failure */
"You can enable later via Settings" = "Puoi attivarle più tardi nelle impostazioni";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Puoi attivarle più tardi nelle impostazioni di privacy e sicurezza dell'app.";
+"You can enable them later via app Your privacy settings." = "Puoi attivarle più tardi nelle impostazioni di privacy e sicurezza dell'app.";
/* No comment provided by engineer. */
"You can give another try." = "Puoi fare un altro tentativo.";
diff --git a/apps/ios/ja.lproj/Localizable.strings b/apps/ios/ja.lproj/Localizable.strings
index 35d8732e3f..b88eb10414 100644
--- a/apps/ios/ja.lproj/Localizable.strings
+++ b/apps/ios/ja.lproj/Localizable.strings
@@ -1270,7 +1270,7 @@ alert button */
"Developer options" = "開発者向けの設定";
/* No comment provided by engineer. */
-"Developer tools" = "開発ツール";
+"Developer" = "開発ツール";
/* No comment provided by engineer. */
"Device" = "端末";
@@ -2533,7 +2533,7 @@ alert button */
"Preview" = "プレビュー";
/* No comment provided by engineer. */
-"Privacy & security" = "プライバシーとセキュリティ";
+"Your privacy" = "プライバシーとセキュリティ";
/* No comment provided by engineer. */
"Private filenames" = "プライベートなファイル名";
@@ -3459,7 +3459,7 @@ server test failure */
"You can enable later via Settings" = "あとで設定から有効にできます";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "あとでアプリのプライバシーとセキュリティの設定から有効にすることができます。";
+"You can enable them later via app Your privacy settings." = "あとでアプリのプライバシーとセキュリティの設定から有効にすることができます。";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right." = "ユーザープロファイルを右にスワイプすると、非表示またはミュートにすることができます。";
diff --git a/apps/ios/nl.lproj/Localizable.strings b/apps/ios/nl.lproj/Localizable.strings
index 407665bbec..1c776a7bbe 100644
--- a/apps/ios/nl.lproj/Localizable.strings
+++ b/apps/ios/nl.lproj/Localizable.strings
@@ -1773,7 +1773,7 @@ alert button */
"Developer options" = "Ontwikkelaars opties";
/* No comment provided by engineer. */
-"Developer tools" = "Ontwikkel gereedschap";
+"Developer" = "Ontwikkel gereedschap";
/* No comment provided by engineer. */
"Device" = "Apparaat";
@@ -3929,7 +3929,7 @@ alert button */
"Previously connected servers" = "Eerder verbonden servers";
/* No comment provided by engineer. */
-"Privacy & security" = "Privacy en beveiliging";
+"Your privacy" = "Privacy en beveiliging";
/* No comment provided by engineer. */
"Privacy for your customers." = "Privacy voor uw klanten.";
@@ -5777,7 +5777,7 @@ server test failure */
"You can enable later via Settings" = "U kunt later inschakelen via Instellingen";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "U kunt ze later inschakelen via de privacy- en beveiligingsinstellingen van de app.";
+"You can enable them later via app Your privacy settings." = "U kunt ze later inschakelen via de privacy- en beveiligingsinstellingen van de app.";
/* No comment provided by engineer. */
"You can give another try." = "Je kunt het nog een keer proberen.";
diff --git a/apps/ios/pl.lproj/Localizable.strings b/apps/ios/pl.lproj/Localizable.strings
index 8905300160..9cc6eca252 100644
--- a/apps/ios/pl.lproj/Localizable.strings
+++ b/apps/ios/pl.lproj/Localizable.strings
@@ -1845,7 +1845,7 @@ alert button */
"Developer options" = "Opcje deweloperskie";
/* No comment provided by engineer. */
-"Developer tools" = "Narzędzia deweloperskie";
+"Developer" = "Narzędzia deweloperskie";
/* No comment provided by engineer. */
"Device" = "Urządzenie";
@@ -4131,7 +4131,7 @@ alert button */
"Previously connected servers" = "Wcześniej połączone serwery";
/* No comment provided by engineer. */
-"Privacy & security" = "Prywatność i bezpieczeństwo";
+"Your privacy" = "Prywatność i bezpieczeństwo";
/* No comment provided by engineer. */
"Privacy for your customers." = "Prywatność dla Twoich klientów.";
@@ -6135,7 +6135,7 @@ server test failure */
"You can enable later via Settings" = "Możesz włączyć później w Ustawieniach";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Możesz je włączyć później w ustawieniach Prywatności i Bezpieczeństwa aplikacji.";
+"You can enable them later via app Your privacy settings." = "Możesz je włączyć później w ustawieniach Prywatności i Bezpieczeństwa aplikacji.";
/* No comment provided by engineer. */
"You can give another try." = "Możesz spróbować ponownie.";
diff --git a/apps/ios/product/README.md b/apps/ios/product/README.md
index 107c0e6569..fd25b09d01 100644
--- a/apps/ios/product/README.md
+++ b/apps/ios/product/README.md
@@ -101,7 +101,7 @@ End-to-end encrypted audio and video communication.
| Call history | Call events displayed as chat items | `Shared/Views/Chat/ChatItem/CICallItemView.swift` |
| Incoming call view | Dedicated UI for incoming call notifications | `Shared/Views/Call/IncomingCallView.swift` |
-### 5. Privacy & Security
+### 5. Your privacy
Encryption, authentication, and privacy controls.
diff --git a/apps/ios/product/views/settings.md b/apps/ios/product/views/settings.md
index 3cc4da5d2b..7e7f653910 100644
--- a/apps/ios/product/views/settings.md
+++ b/apps/ios/product/views/settings.md
@@ -4,7 +4,7 @@
## Purpose
-Configure all aspects of app behavior including notifications, network/servers, privacy, appearance, database management, call settings, and developer tools. Accessed from the UserPicker sheet on the chat list.
+Configure all aspects of app behavior including notifications, network/servers, privacy, appearance, database management, call settings, and Developer. Accessed from the UserPicker sheet on the chat list.
## Route / Navigation
@@ -22,7 +22,7 @@ Configure all aspects of app behavior including notifications, network/servers,
| Notifications | `bolt` (color varies by token status) | `NotificationsView` | Push notification mode and preview settings |
| Network & servers | `externaldrive.connected.to.line.below` | `NetworkAndServers` | SMP/XFTP servers, proxy, .onion hosts, advanced network |
| Audio & video calls | `video` | `CallSettings` | WebRTC relay policy, ICE servers, CallKit options |
-| Privacy & security | `lock` | `PrivacySettings` | SimpleX Lock, screen protection, delivery receipts, auto-accept |
+| Your privacy | `lock` | `PrivacySettings` | SimpleX Lock, screen protection, delivery receipts, auto-accept |
| Appearance | `sun.max` | `AppearanceSettings` | Theme, language, wallpapers, chat bubbles, toolbar opacity |
All rows disabled when `chatModel.chatRunning != true`. Appearance row only shown when `UIApplication.shared.supportsAlternateIcons`.
@@ -77,7 +77,7 @@ Adding a relay: `NewChatRelayView` form with name, address, test, and enable tog
Server validation (`validateServers_`) now returns both errors and warnings.
-#### Privacy & Security (`PrivacySettings`)
+#### Your privacy (`PrivacySettings`)
| Setting | Description |
|---|---|
@@ -152,7 +152,7 @@ Database row shows exclamation octagon icon in red when `chatRunning == false`.
| Row | Icon | Destination | Description |
|---|---|---|---|
-| Developer tools | `chevron.left.forwardslash.chevron.right` | `DeveloperView` | Chat console/terminal, log level, confirm DB upgrades |
+| Developer | `chevron.left.forwardslash.chevron.right` | `DeveloperView` | Chat console/terminal, log level, confirm DB upgrades |
| App version | (none) | `VersionView` | Shows "v{version} ({build})" |
## Loading / Error States
diff --git a/apps/ios/ru.lproj/Localizable.strings b/apps/ios/ru.lproj/Localizable.strings
index 9f79b5dea0..042359dd7e 100644
--- a/apps/ios/ru.lproj/Localizable.strings
+++ b/apps/ios/ru.lproj/Localizable.strings
@@ -2064,7 +2064,7 @@ alert button */
"Developer options" = "Опции разработчика";
/* No comment provided by engineer. */
-"Developer tools" = "Инструменты разработчика";
+"Developer" = "Разработчик";
/* No comment provided by engineer. */
"Device" = "Устройство";
@@ -4533,7 +4533,7 @@ alert button */
"Previously connected servers" = "Ранее подключенные серверы";
/* No comment provided by engineer. */
-"Privacy & security" = "Конфиденциальность";
+"Your privacy" = "Конфиденциальность";
/* No comment provided by engineer. */
"Privacy for your customers." = "Конфиденциальность для ваших покупателей.";
@@ -6759,7 +6759,7 @@ server test failure */
"You can enable later via Settings" = "Вы можете включить их позже в Настройках";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Вы можете включить их позже в настройках Конфиденциальности.";
+"You can enable them later via app Your privacy settings." = "Вы можете включить их позже в настройках Конфиденциальности.";
/* No comment provided by engineer. */
"You can give another try." = "Вы можете попробовать ещё раз.";
diff --git a/apps/ios/th.lproj/Localizable.strings b/apps/ios/th.lproj/Localizable.strings
index cc3abea189..62bf4d3d59 100644
--- a/apps/ios/th.lproj/Localizable.strings
+++ b/apps/ios/th.lproj/Localizable.strings
@@ -946,7 +946,7 @@ alert button */
"Develop" = "พัฒนา";
/* No comment provided by engineer. */
-"Developer tools" = "เครื่องมือสำหรับนักพัฒนา";
+"Developer" = "เครื่องมือสำหรับนักพัฒนา";
/* No comment provided by engineer. */
"Device" = "อุปกรณ์";
@@ -2172,7 +2172,7 @@ new chat action */
"Preview" = "ดูตัวอย่าง";
/* No comment provided by engineer. */
-"Privacy & security" = "ความเป็นส่วนตัวและความปลอดภัย";
+"Your privacy" = "ความเป็นส่วนตัวและความปลอดภัย";
/* No comment provided by engineer. */
"Private filenames" = "ชื่อไฟล์ส่วนตัว";
@@ -3089,7 +3089,7 @@ server test failure */
"You can enable later via Settings" = "คุณสามารถเปิดใช้งานในภายหลังผ่านการตั้งค่า";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "คุณสามารถเปิดใช้งานได้ในภายหลังผ่านการตั้งค่าความเป็นส่วนตัวและความปลอดภัยของแอป";
+"You can enable them later via app Your privacy settings." = "คุณสามารถเปิดใช้งานได้ในภายหลังผ่านการตั้งค่าความเป็นส่วนตัวและความปลอดภัยของแอป";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right." = "คุณสามารถซ่อนหรือปิดเสียงโปรไฟล์ผู้ใช้ - ปัดไปทางขวา";
diff --git a/apps/ios/tr.lproj/Localizable.strings b/apps/ios/tr.lproj/Localizable.strings
index e06989afee..8dfc23078c 100644
--- a/apps/ios/tr.lproj/Localizable.strings
+++ b/apps/ios/tr.lproj/Localizable.strings
@@ -1859,7 +1859,7 @@ alert button */
"Developer options" = "Geliştirici seçenekleri";
/* No comment provided by engineer. */
-"Developer tools" = "Geliştirici araçları";
+"Developer" = "Geliştirici araçları";
/* No comment provided by engineer. */
"Device" = "Cihaz";
@@ -4099,7 +4099,7 @@ alert button */
"Previously connected servers" = "Önceden bağlanılmış sunucular";
/* No comment provided by engineer. */
-"Privacy & security" = "Gizlilik & güvenlik";
+"Your privacy" = "Gizlilik & güvenlik";
/* No comment provided by engineer. */
"Privacy for your customers." = "Müşterileriniz için gizlilik.";
@@ -6064,7 +6064,7 @@ server test failure */
"You can enable later via Settings" = "Daha sonra Ayarlardan etkinleştirebilirsin";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Daha sonra uygulamanın Gizlilik ve Güvenlik ayarlarından etkinleştirebilirsiniz.";
+"You can enable them later via app Your privacy settings." = "Daha sonra uygulamanın Gizlilik ve Güvenlik ayarlarından etkinleştirebilirsiniz.";
/* No comment provided by engineer. */
"You can give another try." = "Bir kez daha deneyebilirsiniz.";
diff --git a/apps/ios/uk.lproj/Localizable.strings b/apps/ios/uk.lproj/Localizable.strings
index 4a21eb4ae8..ff2f64e2ed 100644
--- a/apps/ios/uk.lproj/Localizable.strings
+++ b/apps/ios/uk.lproj/Localizable.strings
@@ -1806,7 +1806,7 @@ alert button */
"Developer options" = "Можливості для розробників";
/* No comment provided by engineer. */
-"Developer tools" = "Інструменти для розробників";
+"Developer" = "Інструменти для розробників";
/* No comment provided by engineer. */
"Device" = "Пристрій";
@@ -4019,7 +4019,7 @@ alert button */
"Previously connected servers" = "Раніше підключені сервери";
/* No comment provided by engineer. */
-"Privacy & security" = "Конфіденційність і безпека";
+"Your privacy" = "Конфіденційність і безпека";
/* No comment provided by engineer. */
"Privacy for your customers." = "Конфіденційність для ваших клієнтів.";
@@ -5966,7 +5966,7 @@ server test failure */
"You can enable later via Settings" = "Ви можете увімкнути пізніше в Налаштуваннях";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "Ви можете увімкнути їх пізніше в налаштуваннях конфіденційності та безпеки програми.";
+"You can enable them later via app Your privacy settings." = "Ви можете увімкнути їх пізніше в налаштуваннях конфіденційності та безпеки програми.";
/* No comment provided by engineer. */
"You can give another try." = "Ви можете спробувати ще раз.";
diff --git a/apps/ios/zh-Hans.lproj/Localizable.strings b/apps/ios/zh-Hans.lproj/Localizable.strings
index 13be5125ea..f3138230f9 100644
--- a/apps/ios/zh-Hans.lproj/Localizable.strings
+++ b/apps/ios/zh-Hans.lproj/Localizable.strings
@@ -1836,7 +1836,7 @@ alert button */
"Developer options" = "开发者选项";
/* No comment provided by engineer. */
-"Developer tools" = "开发者工具";
+"Developer" = "开发者工具";
/* No comment provided by engineer. */
"Device" = "设备";
@@ -4107,7 +4107,7 @@ alert button */
"Previously connected servers" = "以前连接的服务器";
/* No comment provided by engineer. */
-"Privacy & security" = "隐私和安全";
+"Your privacy" = "隐私和安全";
/* No comment provided by engineer. */
"Privacy for your customers." = "客户隐私。";
@@ -6093,7 +6093,7 @@ server test failure */
"You can enable later via Settings" = "您可以稍后在设置中启用它";
/* No comment provided by engineer. */
-"You can enable them later via app Privacy & Security settings." = "您可以稍后通过应用程序的 \"隐私与安全 \"设置启用它们。";
+"You can enable them later via app Your privacy settings." = "您可以稍后通过应用程序的 \"隐私与安全 \"设置启用它们。";
/* No comment provided by engineer. */
"You can give another try." = "你可以再试一次。";
diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.android.kt
index 04b59732dd..5e9706d713 100644
--- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.android.kt
+++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.android.kt
@@ -1,7 +1,15 @@
package chat.simplex.common.views.usersettings
+import SectionItemView
import SectionView
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.style.TextAlign
import chat.simplex.common.model.ChatModel
import chat.simplex.common.platform.*
import chat.simplex.common.views.helpers.*
@@ -11,19 +19,19 @@ import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource
@Composable
-actual fun SettingsSectionApp(
+actual fun AdvancedSettingsAppSection(
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
- showVersion: () -> Unit,
- withAuth: (title: String, desc: String, block: () -> Unit) -> Unit
+ withAuth: (title: String, desc: String, block: () -> Unit) -> Unit,
) {
- SectionView(stringResource(MR.strings.settings_section_title_app)) {
- SettingsActionItem(painterResource(MR.images.ic_restart_alt), stringResource(MR.strings.settings_restart_app), ::restartApp)
- SettingsActionItem(painterResource(MR.images.ic_power_settings_new), stringResource(MR.strings.settings_shutdown), { shutdownAppAlert(::shutdownApp) })
+ SectionView {
SettingsActionItem(painterResource(MR.images.ic_code), stringResource(MR.strings.settings_developer_tools), showSettingsModal { DeveloperView(withAuth) })
- AppVersionItem(showVersion)
}
}
+@Composable
+actual fun AppShutdownItem() {
+ SettingsActionItem(painterResource(MR.images.ic_power_settings_new), stringResource(MR.strings.settings_shutdown), ::shutdownAppAlert)
+}
fun restartApp() {
ProcessPhoenix.triggerRebirth(androidAppContext)
@@ -36,11 +44,28 @@ private fun shutdownApp() {
Runtime.getRuntime().exit(0)
}
-private fun shutdownAppAlert(onConfirm: () -> Unit) {
- AlertManager.shared.showAlertDialog(
+private fun shutdownAppAlert() {
+ AlertManager.shared.showAlertDialogButtonsColumn(
title = generalGetString(MR.strings.shutdown_alert_question),
text = generalGetString(MR.strings.shutdown_alert_desc),
- destructive = true,
- onConfirm = onConfirm
+ buttons = {
+ Column {
+ SectionItemView({ AlertManager.shared.hideAlert() }) {
+ Text(stringResource(MR.strings.cancel_verb), Modifier.fillMaxWidth(), textAlign = TextAlign.Center)
+ }
+ SectionItemView({
+ AlertManager.shared.hideAlert()
+ restartApp()
+ }) {
+ Text(stringResource(MR.strings.settings_restart_app), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
+ }
+ SectionItemView({
+ AlertManager.shared.hideAlert()
+ shutdownApp()
+ }) {
+ Text(stringResource(MR.strings.settings_shutdown), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = Color.Red)
+ }
+ }
+ }
)
}
diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt
index 648a0eb8e7..80f97d1caf 100644
--- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt
+++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt
@@ -44,29 +44,8 @@ fun DatabaseView() {
val prefs = m.controller.appPrefs
val useKeychain = remember { mutableStateOf(prefs.storeDBPassphrase.get()) }
val chatLastStart = remember { mutableStateOf(prefs.chatLastStart.get()) }
- val chatArchiveFile = remember { mutableStateOf(null) }
val stopped = remember { m.chatRunning }.value == false
- val saveArchiveLauncher = rememberFileChooserLauncher(false) { to: URI? ->
- val archive = chatArchiveFile.value
- if (archive != null && to != null) {
- copyFileToFile(File(archive), to) {}
- }
- // delete no matter the database was exported or canceled the export process
- if (archive != null) {
- File(archive).delete()
- chatArchiveFile.value = null
- }
- }
val appFilesCountAndSize = remember { mutableStateOf(directoryFileCountAndSize(appFilesDir.absolutePath)) }
- val importArchiveLauncher = rememberFileChooserLauncher(true) { to: URI? ->
- if (to != null) {
- importArchiveAlert {
- stopChatRunBlockStartChat(stopped, chatLastStart, progressIndicator) {
- importArchive(to, appFilesCountAndSize, progressIndicator, false)
- }
- }
- }
- }
val chatItemTTL = remember { mutableStateOf(m.chatItemTTL.value) }
Box(
Modifier.fillMaxSize(),
@@ -79,27 +58,10 @@ fun DatabaseView() {
useKeychain.value,
m.chatDbEncrypted.value,
m.controller.appPrefs.storeDBPassphrase.state.value,
- m.controller.appPrefs.initialRandomDBPassphrase,
- importArchiveLauncher,
appFilesCountAndSize,
chatItemTTL,
user,
m.users,
- startChat = { startChat(m, chatLastStart, m.chatDbChanged, progressIndicator) },
- stopChatAlert = { stopChatAlert(m, progressIndicator) },
- exportArchive = {
- stopChatRunBlockStartChat(stopped, chatLastStart, progressIndicator) {
- exportArchive(m, progressIndicator, chatArchiveFile, saveArchiveLauncher)
- }
- },
- deleteChatAlert = {
- deleteChatAlert {
- stopChatRunBlockStartChat(stopped, chatLastStart, progressIndicator) {
- deleteChat(m, progressIndicator)
- true
- }
- }
- },
deleteAppFilesAndMedia = {
deleteFilesAndMediaAlert {
stopChatRunBlockStartChat(stopped, chatLastStart, progressIndicator) {
@@ -120,12 +82,9 @@ fun DatabaseView() {
setCiTTL(m, rhId, chatItemTTL, progressIndicator, appFilesCountAndSize)
}
},
- disconnectAllHosts = {
- val connected = chatModel.remoteHosts.filter { it.sessionState is RemoteHostSessionState.Connected }
- connected.forEachIndexed { index, h ->
- controller.stopRemoteHostAndReloadHosts(h, index == connected.lastIndex && chatModel.connectedToRemote())
- }
- }
+ showDatabaseManagement = {
+ ModalManager.start.showModal(cardScreen = true) { DatabaseManagementView() }
+ },
)
if (progressIndicator.value) {
Box(
@@ -151,24 +110,18 @@ fun DatabaseLayout(
useKeyChain: Boolean,
chatDbEncrypted: Boolean?,
passphraseSaved: Boolean,
- initialRandomDBPassphrase: SharedPreference,
- importArchiveLauncher: FileChooserLauncher,
appFilesCountAndSize: MutableState>,
chatItemTTL: MutableState,
currentUser: User?,
users: List,
- startChat: () -> Unit,
- stopChatAlert: () -> Unit,
- exportArchive: () -> Unit,
- deleteChatAlert: () -> Unit,
deleteAppFilesAndMedia: () -> Unit,
onChatItemTTLSelected: (ChatItemTTL?) -> Unit,
- disconnectAllHosts: () -> Unit,
+ showDatabaseManagement: () -> Unit,
) {
val operationsDisabled = progressIndicator && !chatModel.desktopNoUserNoRemote
ColumnWithScrollBar {
- AppBarTitle(stringResource(MR.strings.your_chat_database))
+ AppBarTitle(stringResource(MR.strings.chat_data))
if (!chatModel.desktopNoUserNoRemote) {
SectionView(stringResource(MR.strings.messages_section_title)) {
@@ -187,79 +140,17 @@ fun DatabaseLayout(
)
SectionDividerSpaced()
}
- val toggleEnabled = remember { chatModel.remoteHosts }.none { it.sessionState is RemoteHostSessionState.Connected }
- if (chatModel.localUserCreated.value == true) {
- // still show the toggle in case database was stopped when the user opened this screen because it can be in the following situations:
- // - database was stopped after migration and the app relaunched
- // - something wrong happened with database operations and the database couldn't be launched when it should
- SectionView(stringResource(MR.strings.run_chat_section)) {
- if (!toggleEnabled) {
- SectionItemView(disconnectAllHosts) {
- Text(generalGetString(MR.strings.disconnect_remote_hosts), Modifier.fillMaxWidth(), color = WarningOrange)
- }
- }
- RunChatSetting(stopped, toggleEnabled && !progressIndicator, startChat, stopChatAlert)
- }
- if (stopped) SectionTextFooter(stringResource(MR.strings.you_must_use_the_most_recent_version_of_database))
- SectionDividerSpaced()
- }
- SectionView(stringResource(MR.strings.chat_database_section)) {
- if (chatModel.localUserCreated.value != true && !toggleEnabled) {
- SectionItemView(disconnectAllHosts) {
- Text(generalGetString(MR.strings.disconnect_remote_hosts), Modifier.fillMaxWidth(), color = WarningOrange)
- }
- }
+ SectionView {
val unencrypted = chatDbEncrypted == false
SettingsActionItem(
if (unencrypted) painterResource(MR.images.ic_lock_open_right) else if (useKeyChain) painterResource(MR.images.ic_vpn_key_filled)
else painterResource(MR.images.ic_lock),
- stringResource(MR.strings.database_passphrase),
- click = { ModalManager.start.showModal(cardScreen = true) { DatabaseEncryptionView(chatModel, false) } },
+ stringResource(MR.strings.database_passphrase_and_export),
+ click = showDatabaseManagement,
iconColor = if (unencrypted || (appPlatform.isDesktop && passphraseSaved)) WarningOrange else MaterialTheme.colors.secondary,
disabled = operationsDisabled
)
- if (appPlatform.isDesktop) {
- SettingsActionItem(
- painterResource(MR.images.ic_folder_open),
- stringResource(MR.strings.open_database_folder),
- ::desktopOpenDatabaseDir,
- disabled = operationsDisabled
- )
- }
- SettingsActionItem(
- painterResource(MR.images.ic_ios_share),
- stringResource(MR.strings.export_database),
- click = {
- if (initialRandomDBPassphrase.get()) {
- exportProhibitedAlert()
- ModalManager.start.showModal {
- DatabaseEncryptionView(chatModel, false)
- }
- } else {
- exportArchive()
- }
- },
- textColor = MaterialTheme.colors.primary,
- iconColor = MaterialTheme.colors.primary,
- disabled = operationsDisabled
- )
- SettingsActionItem(
- painterResource(MR.images.ic_download),
- stringResource(MR.strings.import_database),
- { withLongRunningApi { importArchiveLauncher.launch("application/zip") } },
- textColor = Color.Red,
- iconColor = Color.Red,
- disabled = operationsDisabled
- )
- SettingsActionItem(
- painterResource(MR.images.ic_delete_forever),
- stringResource(MR.strings.delete_database),
- deleteChatAlert,
- textColor = Color.Red,
- iconColor = Color.Red,
- disabled = operationsDisabled
- )
}
SectionDividerSpaced()
@@ -287,6 +178,155 @@ fun DatabaseLayout(
}
}
+@Composable
+fun DatabaseManagementView() {
+ val m = chatModel
+ val progressIndicator = remember { mutableStateOf(false) }
+ val prefs = m.controller.appPrefs
+ val useKeychain = remember { mutableStateOf(prefs.storeDBPassphrase.get()) }
+ val chatLastStart = remember { mutableStateOf(prefs.chatLastStart.get()) }
+ val chatArchiveFile = remember { mutableStateOf(null) }
+ val stopped = remember { m.chatRunning }.value == false
+ val saveArchiveLauncher = rememberFileChooserLauncher(false) { to: URI? ->
+ val archive = chatArchiveFile.value
+ if (archive != null && to != null) {
+ copyFileToFile(File(archive), to) {}
+ }
+ // delete no matter the database was exported or canceled the export process
+ if (archive != null) {
+ File(archive).delete()
+ chatArchiveFile.value = null
+ }
+ }
+ val appFilesCountAndSize = remember { mutableStateOf(directoryFileCountAndSize(appFilesDir.absolutePath)) }
+ val importArchiveLauncher = rememberFileChooserLauncher(true) { to: URI? ->
+ if (to != null) {
+ importArchiveAlert {
+ stopChatRunBlockStartChat(stopped, chatLastStart, progressIndicator) {
+ importArchive(to, appFilesCountAndSize, progressIndicator, false)
+ }
+ }
+ }
+ }
+ val operationsDisabled = progressIndicator.value && !m.desktopNoUserNoRemote
+
+ Box(Modifier.fillMaxSize()) {
+ ColumnWithScrollBar {
+ AppBarTitle(stringResource(MR.strings.database_passphrase_and_export))
+
+ val toggleEnabled = remember { chatModel.remoteHosts }.none { it.sessionState is RemoteHostSessionState.Connected }
+ val disconnectAllHosts = {
+ val connected = chatModel.remoteHosts.filter { it.sessionState is RemoteHostSessionState.Connected }
+ connected.forEachIndexed { index, h ->
+ controller.stopRemoteHostAndReloadHosts(h, index == connected.lastIndex && chatModel.connectedToRemote())
+ }
+ }
+ SectionView(stringResource(MR.strings.chat_database_section)) {
+ if (chatModel.localUserCreated.value != true && !toggleEnabled) {
+ SectionItemView(disconnectAllHosts) {
+ Text(generalGetString(MR.strings.disconnect_remote_hosts), Modifier.fillMaxWidth(), color = WarningOrange)
+ }
+ }
+ val unencrypted = m.chatDbEncrypted.value == false
+ SettingsActionItem(
+ if (unencrypted) painterResource(MR.images.ic_lock_open_right) else if (useKeychain.value) painterResource(MR.images.ic_vpn_key_filled)
+ else painterResource(MR.images.ic_lock),
+ stringResource(MR.strings.database_passphrase),
+ click = { ModalManager.start.showModal(cardScreen = true) { DatabaseEncryptionView(chatModel, false) } },
+ iconColor = if (unencrypted || (appPlatform.isDesktop && prefs.storeDBPassphrase.state.value)) WarningOrange else MaterialTheme.colors.secondary,
+ disabled = operationsDisabled
+ )
+ if (appPlatform.isDesktop) {
+ SettingsActionItem(
+ painterResource(MR.images.ic_folder_open),
+ stringResource(MR.strings.open_database_folder),
+ ::desktopOpenDatabaseDir,
+ disabled = operationsDisabled
+ )
+ }
+ SettingsActionItem(
+ painterResource(MR.images.ic_ios_share),
+ stringResource(MR.strings.export_database),
+ click = {
+ if (prefs.initialRandomDBPassphrase.get()) {
+ exportProhibitedAlert()
+ ModalManager.start.showModal {
+ DatabaseEncryptionView(chatModel, false)
+ }
+ } else {
+ stopChatRunBlockStartChat(stopped, chatLastStart, progressIndicator) {
+ exportArchive(m, progressIndicator, chatArchiveFile, saveArchiveLauncher)
+ }
+ }
+ },
+ textColor = MaterialTheme.colors.primary,
+ iconColor = MaterialTheme.colors.primary,
+ disabled = operationsDisabled
+ )
+ SettingsActionItem(
+ painterResource(MR.images.ic_download),
+ stringResource(MR.strings.import_database),
+ { withLongRunningApi { importArchiveLauncher.launch("application/zip") } },
+ textColor = Color.Red,
+ iconColor = Color.Red,
+ disabled = operationsDisabled
+ )
+ SettingsActionItem(
+ painterResource(MR.images.ic_delete_forever),
+ stringResource(MR.strings.delete_database),
+ {
+ deleteChatAlert {
+ stopChatRunBlockStartChat(stopped, chatLastStart, progressIndicator) {
+ deleteChat(m, progressIndicator)
+ true
+ }
+ }
+ },
+ textColor = Color.Red,
+ iconColor = Color.Red,
+ disabled = operationsDisabled
+ )
+ }
+
+ if (chatModel.localUserCreated.value == true) {
+ SectionDividerSpaced()
+ // still show the toggle in case database was stopped when the user opened this screen because it can be in the following situations:
+ // - database was stopped after migration and the app relaunched
+ // - something wrong happened with database operations and the database couldn't be launched when it should
+ SectionView(stringResource(MR.strings.run_chat_section)) {
+ if (!toggleEnabled) {
+ SectionItemView(disconnectAllHosts) {
+ Text(generalGetString(MR.strings.disconnect_remote_hosts), Modifier.fillMaxWidth(), color = WarningOrange)
+ }
+ }
+ RunChatSetting(
+ stopped,
+ toggleEnabled && !progressIndicator.value,
+ startChat = { startChat(m, chatLastStart, m.chatDbChanged, progressIndicator) },
+ stopChatAlert = { stopChatAlert(m, progressIndicator) }
+ )
+ }
+ if (stopped) SectionTextFooter(stringResource(MR.strings.you_must_use_the_most_recent_version_of_database))
+ }
+ SectionBottomSpacer()
+ }
+ if (progressIndicator.value) {
+ Box(
+ Modifier.fillMaxSize(),
+ contentAlignment = Alignment.Center
+ ) {
+ CircularProgressIndicator(
+ Modifier
+ .padding(horizontal = 2.dp)
+ .size(30.dp),
+ color = MaterialTheme.colors.secondary,
+ strokeWidth = 2.5.dp
+ )
+ }
+ }
+ }
+}
+
private fun setChatItemTTLAlert(
m: ChatModel, rhId: Long?, selectedChatItemTTL: MutableState,
progressIndicator: MutableState,
@@ -832,19 +872,13 @@ fun PreviewDatabaseLayout() {
useKeyChain = false,
chatDbEncrypted = false,
passphraseSaved = false,
- initialRandomDBPassphrase = SharedPreference({ true }, {}),
- importArchiveLauncher = rememberFileChooserLauncher(true) {},
appFilesCountAndSize = remember { mutableStateOf(0 to 0L) },
chatItemTTL = remember { mutableStateOf(ChatItemTTL.None) },
currentUser = User.sampleData,
users = listOf(UserInfo.sampleData),
- startChat = {},
- stopChatAlert = {},
- exportArchive = {},
- deleteChatAlert = {},
deleteAppFilesAndMedia = {},
onChatItemTTLSelected = {},
- disconnectAllHosts = {},
+ showDatabaseManagement = {},
)
}
}
diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt
index 150b2a38e0..91324bb39a 100644
--- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt
+++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt
@@ -24,43 +24,28 @@ import kotlin.collections.ArrayList
fun NotificationsSettingsView(
chatModel: ChatModel,
) {
- val onNotificationPreviewModeSelected = { mode: NotificationPreviewMode ->
- chatModel.controller.appPrefs.notificationPreviewMode.set(mode.name)
- chatModel.notificationPreviewMode.value = mode
- }
-
NotificationsSettingsLayout(
notificationsMode = remember { chatModel.controller.appPrefs.notificationsMode.state },
- notificationPreviewMode = chatModel.notificationPreviewMode,
- showPage = { page ->
+ showNotificationsMode = {
ModalManager.start.showModalCloseable(true) {
- when (page) {
- CurrentPage.NOTIFICATIONS_MODE -> NotificationsModeView(chatModel.controller.appPrefs.notificationsMode.state) { changeNotificationsMode(it, chatModel) }
- CurrentPage.NOTIFICATION_PREVIEW_MODE -> NotificationPreviewView(chatModel.notificationPreviewMode, onNotificationPreviewModeSelected)
- }
+ NotificationsModeView(chatModel.controller.appPrefs.notificationsMode.state) { changeNotificationsMode(it, chatModel) }
}
},
)
}
-enum class CurrentPage {
- NOTIFICATIONS_MODE, NOTIFICATION_PREVIEW_MODE
-}
-
@Composable
fun NotificationsSettingsLayout(
notificationsMode: State,
- notificationPreviewMode: State,
- showPage: (CurrentPage) -> Unit,
+ showNotificationsMode: () -> Unit,
) {
val modes = remember { notificationModes() }
- val previewModes = remember { notificationPreviewModes() }
ColumnWithScrollBar {
AppBarTitle(stringResource(MR.strings.notifications))
SectionView(null) {
if (appPlatform == AppPlatform.ANDROID) {
- SettingsActionItemWithContent(null, stringResource(MR.strings.settings_notifications_mode_title), { showPage(CurrentPage.NOTIFICATIONS_MODE) }) {
+ SettingsActionItemWithContent(null, stringResource(MR.strings.settings_notifications_mode_title), showNotificationsMode) {
Text(
modes.firstOrNull { it.value == notificationsMode.value }?.title ?: "",
maxLines = 1,
@@ -69,14 +54,6 @@ fun NotificationsSettingsLayout(
)
}
}
- SettingsActionItemWithContent(null, stringResource(MR.strings.settings_notification_preview_mode_title), { showPage(CurrentPage.NOTIFICATION_PREVIEW_MODE) }) {
- Text(
- previewModes.firstOrNull { it.value == notificationPreviewMode.value }?.title ?: "",
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
- color = MaterialTheme.colors.secondary
- )
- }
}
if (platform.androidIsXiaomiDevice() && (notificationsMode.value == NotificationsMode.PERIODIC || notificationsMode.value == NotificationsMode.SERVICE)) {
SectionTextFooter(annotatedStringResource(MR.strings.xiaomi_ignore_battery_optimization))
diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt
index 7316c9bd82..cf34fd5a44 100644
--- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt
+++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt
@@ -15,6 +15,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.*
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.style.TextOverflow
import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource
import androidx.compose.ui.unit.dp
@@ -73,6 +74,48 @@ fun PrivacySettingsView(
stringResource(MR.strings.sanitize_links_toggle),
chatModel.controller.appPrefs.privacySanitizeLinks
)
+ }
+ SectionDividerSpaced()
+
+ SectionView(stringResource(MR.strings.settings_section_title_files)) {
+ SettingsPreferenceItem(painterResource(MR.images.ic_image), stringResource(MR.strings.auto_accept_images), chatModel.controller.appPrefs.privacyAcceptImages)
+ BlurRadiusOptions(remember { appPrefs.privacyMediaBlurRadius.state }) {
+ appPrefs.privacyMediaBlurRadius.set(it)
+ }
+ }
+
+ val currentUser = chatModel.currentUser.value
+ if (currentUser != null && !chatModel.desktopNoUserNoRemote) {
+ SectionDividerSpaced()
+ ContacRequestsFromGroupsSection(
+ currentUser = currentUser,
+ setAutoAcceptGrpDirectInvs = { enable ->
+ withApi {
+ chatModel.controller.apiSetUserAutoAcceptMemberContacts(currentUser, enable)
+ chatModel.currentUser.value = currentUser.copy(autoAcceptMemberContacts = enable)
+ }
+ }
+ )
+ }
+
+ SectionDividerSpaced()
+ SectionView {
+ SettingsActionItem(
+ painterResource(MR.images.ic_more_horiz),
+ stringResource(MR.strings.more_privacy),
+ showSettingsModal { MorePrivacyView(it) }
+ )
+ }
+ SectionBottomSpacer()
+ }
+}
+
+@Composable
+fun MorePrivacyView(chatModel: ChatModel) {
+ ColumnWithScrollBar {
+ AppBarTitle(stringResource(MR.strings.more_privacy))
+
+ SectionView(stringResource(MR.strings.settings_section_title_chats)) {
SettingsPreferenceItem(
painterResource(MR.images.ic_chat_bubble),
stringResource(MR.strings.privacy_show_last_messages),
@@ -98,10 +141,6 @@ fun PrivacySettingsView(
SettingsPreferenceItem(painterResource(MR.images.ic_lock), stringResource(MR.strings.encrypt_local_files), chatModel.controller.appPrefs.privacyEncryptLocalFiles, onChange = { enable ->
withBGApi { chatModel.controller.apiSetEncryptLocalFiles(enable) }
})
- SettingsPreferenceItem(painterResource(MR.images.ic_image), stringResource(MR.strings.auto_accept_images), chatModel.controller.appPrefs.privacyAcceptImages)
- BlurRadiusOptions(remember { appPrefs.privacyMediaBlurRadius.state }) {
- appPrefs.privacyMediaBlurRadius.set(it)
- }
SettingsPreferenceItem(painterResource(MR.images.ic_security), stringResource(MR.strings.protect_ip_address), chatModel.controller.appPrefs.privacyAskToApproveRelays)
}
SectionTextFooter(
@@ -111,9 +150,34 @@ fun PrivacySettingsView(
stringResource(MR.strings.without_tor_or_vpn_ip_address_will_be_visible_to_file_servers)
}
)
+ SectionDividerSpaced()
+
+ SectionView(stringResource(MR.strings.notifications)) {
+ val previewModes = remember { notificationPreviewModes() }
+ val notificationPreviewMode = remember { chatModel.notificationPreviewMode }
+ SettingsActionItemWithContent(
+ painterResource(MR.images.ic_visibility_off),
+ stringResource(MR.strings.settings_notification_preview_mode_title),
+ click = {
+ ModalManager.start.showModalCloseable(true) {
+ NotificationPreviewView(notificationPreviewMode) { mode ->
+ chatModel.controller.appPrefs.notificationPreviewMode.set(mode.name)
+ chatModel.notificationPreviewMode.value = mode
+ }
+ }
+ }
+ ) {
+ Text(
+ previewModes.firstOrNull { it.value == notificationPreviewMode.value }?.title ?: "",
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ color = MaterialTheme.colors.secondary
+ )
+ }
+ }
val currentUser = chatModel.currentUser.value
- if (currentUser != null) {
+ if (currentUser != null && !chatModel.desktopNoUserNoRemote) {
fun setSendReceiptsContacts(enable: Boolean, clearOverrides: Boolean) {
withLongRunningApi(slow = 60_000) {
val mrs = UserMsgReceiptSettings(enable, clearOverrides)
@@ -164,57 +228,40 @@ fun PrivacySettingsView(
}
}
- fun setAutoAcceptGrpDirectInvs(enable: Boolean) {
- withApi {
- chatModel.controller.apiSetUserAutoAcceptMemberContacts(currentUser, enable)
- chatModel.currentUser.value = currentUser.copy(autoAcceptMemberContacts = enable)
+ SectionDividerSpaced()
+ DeliveryReceiptsSection(
+ currentUser = currentUser,
+ setOrAskSendReceiptsContacts = { enable ->
+ val contactReceiptsOverrides = chatModel.chats.value.fold(0) { count, chat ->
+ if (chat.chatInfo is ChatInfo.Direct) {
+ val sendRcpts = chat.chatInfo.contact.chatSettings.sendRcpts
+ count + (if (sendRcpts == null || sendRcpts == enable) 0 else 1)
+ } else {
+ count
+ }
+ }
+ if (contactReceiptsOverrides == 0) {
+ setSendReceiptsContacts(enable, clearOverrides = false)
+ } else {
+ showUserContactsReceiptsAlert(enable, contactReceiptsOverrides, ::setSendReceiptsContacts)
+ }
+ },
+ setOrAskSendReceiptsGroups = { enable ->
+ val groupReceiptsOverrides = chatModel.chats.value.fold(0) { count, chat ->
+ if (chat.chatInfo is ChatInfo.Group) {
+ val sendRcpts = chat.chatInfo.groupInfo.chatSettings.sendRcpts
+ count + (if (sendRcpts == null || sendRcpts == enable) 0 else 1)
+ } else {
+ count
+ }
+ }
+ if (groupReceiptsOverrides == 0) {
+ setSendReceiptsGroups(enable, clearOverrides = false)
+ } else {
+ showUserGroupsReceiptsAlert(enable, groupReceiptsOverrides, ::setSendReceiptsGroups)
+ }
}
- }
-
- if (!chatModel.desktopNoUserNoRemote) {
- SectionDividerSpaced()
- ContacRequestsFromGroupsSection(
- currentUser = currentUser,
- setAutoAcceptGrpDirectInvs = { enable ->
- setAutoAcceptGrpDirectInvs(enable)
- }
- )
-
- SectionDividerSpaced()
- DeliveryReceiptsSection(
- currentUser = currentUser,
- setOrAskSendReceiptsContacts = { enable ->
- val contactReceiptsOverrides = chatModel.chats.value.fold(0) { count, chat ->
- if (chat.chatInfo is ChatInfo.Direct) {
- val sendRcpts = chat.chatInfo.contact.chatSettings.sendRcpts
- count + (if (sendRcpts == null || sendRcpts == enable) 0 else 1)
- } else {
- count
- }
- }
- if (contactReceiptsOverrides == 0) {
- setSendReceiptsContacts(enable, clearOverrides = false)
- } else {
- showUserContactsReceiptsAlert(enable, contactReceiptsOverrides, ::setSendReceiptsContacts)
- }
- },
- setOrAskSendReceiptsGroups = { enable ->
- val groupReceiptsOverrides = chatModel.chats.value.fold(0) { count, chat ->
- if (chat.chatInfo is ChatInfo.Group) {
- val sendRcpts = chat.chatInfo.groupInfo.chatSettings.sendRcpts
- count + (if (sendRcpts == null || sendRcpts == enable) 0 else 1)
- } else {
- count
- }
- }
- if (groupReceiptsOverrides == 0) {
- setSendReceiptsGroups(enable, clearOverrides = false)
- } else {
- showUserGroupsReceiptsAlert(enable, groupReceiptsOverrides, ::setSendReceiptsGroups)
- }
- }
- )
- }
+ )
}
SectionBottomSpacer()
}
diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt
index f17d3a6e4b..c0b822dbb4 100644
--- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt
+++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt
@@ -37,17 +37,15 @@ import chat.simplex.res.MR
@Composable
fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit, close: () -> Unit) {
- val user = chatModel.currentUser.value
val stopped = chatModel.chatRunning.value == false
+ val showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit) = { modalView -> { ModalManager.start.showModal(settings = true, cardScreen = true) { modalView(chatModel) } } }
SettingsLayout(
stopped,
chatModel.chatDbEncrypted.value == true,
remember { chatModel.controller.appPrefs.storeDBPassphrase.state }.value,
- remember { chatModel.controller.appPrefs.notificationsMode.state },
- user?.displayName,
setPerformLA = setPerformLA,
showModal = { modalView -> { ModalManager.start.showModal { modalView(chatModel) } } },
- showSettingsModal = { modalView -> { ModalManager.start.showModal(settings = true, cardScreen = true) { modalView(chatModel) } } },
+ showSettingsModal = showSettingsModal,
showSettingsModalWithSearch = { modalView ->
ModalManager.start.showCustomModal { close ->
val search = rememberSaveable { mutableStateOf("") }
@@ -62,12 +60,7 @@ fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit, close: (
},
showCustomModal = { modalView -> { ModalManager.start.showCustomModal { close -> modalView(chatModel, close) } } },
showVersion = {
- withBGApi {
- val info = chatModel.controller.apiGetVersion()
- if (info != null) {
- ModalManager.start.showModal { VersionInfoView(info) }
- }
- }
+ ModalManager.start.showModal(cardScreen = true) { VersionInfoView(showSettingsModal, ::doWithAuth) }
},
withAuth = ::doWithAuth,
)
@@ -84,8 +77,6 @@ fun SettingsLayout(
stopped: Boolean,
encrypted: Boolean,
passphraseSaved: Boolean,
- notificationsMode: State,
- userDisplayName: String?,
setPerformLA: (Boolean) -> Unit,
showModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
@@ -98,30 +89,52 @@ fun SettingsLayout(
LaunchedEffect(Unit) {
hideKeyboard(view)
}
- val uriHandler = LocalUriHandler.current
+ val notificationsMode = remember { chatModel.controller.appPrefs.notificationsMode.state }
ColumnWithScrollBar {
AppBarTitle(stringResource(MR.strings.your_settings))
- SectionView(stringResource(MR.strings.settings_section_title_settings)) {
- SettingsActionItem(painterResource(if (notificationsMode.value == NotificationsMode.OFF) MR.images.ic_bolt_off else MR.images.ic_bolt), stringResource(MR.strings.notifications), showSettingsModal { NotificationsSettingsView(it) }, disabled = stopped)
- SettingsActionItem(painterResource(MR.images.ic_wifi_tethering), stringResource(MR.strings.network_and_servers), showCustomModal { _, close -> NetworkAndServersView(close) }, disabled = stopped)
- SettingsActionItem(painterResource(MR.images.ic_videocam), stringResource(MR.strings.settings_audio_video_calls), showSettingsModal { CallSettingsView(it, showModal) }, disabled = stopped)
- SettingsActionItem(painterResource(MR.images.ic_lock), stringResource(MR.strings.privacy_and_security), showSettingsModal { PrivacySettingsView(it, showSettingsModal, setPerformLA) }, disabled = stopped)
+ SectionView {
SettingsActionItem(painterResource(MR.images.ic_light_mode), stringResource(MR.strings.appearance_settings), showSettingsModal { AppearanceView(it) })
- }
- SectionDividerSpaced()
-
- SectionView(stringResource(MR.strings.settings_section_title_chat_database)) {
+ SettingsActionItem(painterResource(MR.images.ic_lock), stringResource(MR.strings.your_privacy), showSettingsModal { PrivacySettingsView(it, showSettingsModal, setPerformLA) }, disabled = stopped)
+ SettingsActionItem(painterResource(MR.images.ic_help), stringResource(MR.strings.help_and_support), showSettingsModal { HelpAndSupportView(it, showModal, showCustomModal) })
DatabaseItem(encrypted, passphraseSaved, showSettingsModal { DatabaseView() }, stopped)
SettingsActionItem(painterResource(MR.images.ic_ios_share), stringResource(MR.strings.migrate_from_device_to_another_device), { withAuth(generalGetString(MR.strings.auth_open_migration_to_another_device), generalGetString(MR.strings.auth_log_in_using_credential)) { ModalManager.fullscreen.showCustomModal { close -> MigrateFromDeviceView(close) } } }, disabled = stopped)
}
-
SectionDividerSpaced()
+ SectionView(stringResource(MR.strings.advanced_settings)) {
+ SettingsActionItem(painterResource(MR.images.ic_wifi_tethering), stringResource(MR.strings.network_and_servers), showCustomModal { _, close -> NetworkAndServersView(close) }, disabled = stopped)
+ if (appPlatform == AppPlatform.ANDROID) {
+ SettingsActionItem(painterResource(if (notificationsMode.value == NotificationsMode.OFF) MR.images.ic_bolt_off else MR.images.ic_bolt), stringResource(MR.strings.notifications), showSettingsModal { NotificationsSettingsView(it) }, disabled = stopped)
+ }
+ SettingsActionItem(painterResource(MR.images.ic_videocam), stringResource(MR.strings.settings_audio_video_calls), showSettingsModal { CallSettingsView(it, showModal) }, disabled = stopped)
+ AppShutdownItem()
+ AppVersionItem(showVersion)
+ }
+ SectionBottomSpacer()
+ }
+}
+
+@Composable
+fun HelpAndSupportView(
+ chatModel: ChatModel,
+ showModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
+ showCustomModal: (@Composable ModalData.(ChatModel, () -> Unit) -> Unit) -> (() -> Unit),
+) {
+ val uriHandler = LocalUriHandler.current
+ val stopped = chatModel.chatRunning.value == false
+ val userDisplayName = chatModel.currentUser.value?.displayName ?: ""
+ ColumnWithScrollBar {
+ AppBarTitle(stringResource(MR.strings.help_and_support))
+
SectionView(stringResource(MR.strings.settings_section_title_help)) {
- SettingsActionItem(painterResource(MR.images.ic_help), stringResource(MR.strings.how_to_use_simplex_chat), showModal { HelpView(userDisplayName ?: "") }, disabled = stopped)
+ SettingsActionItem(painterResource(MR.images.ic_help), stringResource(MR.strings.how_to_use_simplex_chat), showModal { HelpView(userDisplayName) }, disabled = stopped)
SettingsActionItem(painterResource(MR.images.ic_add), stringResource(MR.strings.whats_new), showCustomModal { _, close -> WhatsNewView(viaSettings = true, close = close) }, disabled = stopped)
SettingsActionItem(painterResource(MR.images.ic_info), stringResource(MR.strings.about_simplex_chat), showModal { SimpleXInfo(it, onboarding = false) })
+ }
+ SectionDividerSpaced()
+
+ SectionView(stringResource(MR.strings.settings_section_title_contact)) {
if (!chatModel.desktopNoUserNoRemote) {
SettingsActionItem(painterResource(MR.images.ic_tag), stringResource(MR.strings.chat_with_the_founder), { uriHandler.openVerifiedSimplexUri(simplexTeamUri) }, textColor = MaterialTheme.colors.primary, disabled = stopped)
}
@@ -129,27 +142,29 @@ fun SettingsLayout(
}
SectionDividerSpaced()
- SectionView(stringResource(MR.strings.settings_section_title_support)) {
+ SectionView(stringResource(MR.strings.settings_section_title_support_project)) {
if (!BuildConfigCommon.ANDROID_BUNDLE) {
ContributeItem(uriHandler)
}
- RateAppItem(uriHandler)
+ if (appPlatform.isAndroid) {
+ RateAppItem(uriHandler)
+ }
StarOnGithubItem(uriHandler)
}
- SectionDividerSpaced()
-
- SettingsSectionApp(showSettingsModal, showVersion, withAuth)
SectionBottomSpacer()
}
}
@Composable
-expect fun SettingsSectionApp(
+expect fun AdvancedSettingsAppSection(
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
- showVersion: () -> Unit,
- withAuth: (title: String, desc: String, block: () -> Unit) -> Unit
+ withAuth: (title: String, desc: String, block: () -> Unit) -> Unit,
)
+// Shutdown is only available on Android; on desktop the app is closed via the window.
+@Composable
+expect fun AppShutdownItem()
+
@Composable private fun DatabaseItem(encrypted: Boolean, saved: Boolean, openDatabaseView: () -> Unit, stopped: Boolean) {
SectionItemView(openDatabaseView) {
Row(
@@ -160,11 +175,11 @@ expect fun SettingsSectionApp(
Row(Modifier.weight(1f), verticalAlignment = Alignment.CenterVertically) {
Icon(
painterResource(MR.images.ic_database),
- contentDescription = stringResource(MR.strings.database_passphrase_and_export),
+ contentDescription = stringResource(MR.strings.chat_data),
tint = if (encrypted && (appPlatform.isAndroid || !saved)) MaterialTheme.colors.secondary else WarningOrange,
)
TextIconSpaced(false)
- Text(stringResource(MR.strings.database_passphrase_and_export))
+ Text(stringResource(MR.strings.chat_data))
}
if (stopped) {
Icon(
@@ -208,7 +223,7 @@ fun ChatLockItem(
}
}
-@Composable private fun ContributeItem(uriHandler: UriHandler) {
+@Composable fun ContributeItem(uriHandler: UriHandler) {
SectionItemView({ uriHandler.openExternalLink("https://github.com/simplex-chat/simplex-chat#contribute") }) {
Icon(
painterResource(MR.images.ic_keyboard),
@@ -220,7 +235,7 @@ fun ChatLockItem(
}
}
-@Composable private fun RateAppItem(uriHandler: UriHandler) {
+@Composable fun RateAppItem(uriHandler: UriHandler) {
SectionItemView({
runCatching { uriHandler.openUriCatching("market://details?id=chat.simplex.app") }
.onFailure { uriHandler.openUriCatching("https://play.google.com/store/apps/details?id=chat.simplex.app") }
@@ -236,7 +251,7 @@ fun ChatLockItem(
}
}
-@Composable private fun StarOnGithubItem(uriHandler: UriHandler) {
+@Composable fun StarOnGithubItem(uriHandler: UriHandler) {
SectionItemView({ uriHandler.openExternalLink("https://github.com/simplex-chat/simplex-chat") }) {
Icon(
painter = painterResource(MR.images.ic_github),
@@ -486,8 +501,6 @@ fun PreviewSettingsLayout() {
stopped = false,
encrypted = false,
passphraseSaved = false,
- notificationsMode = remember { mutableStateOf(NotificationsMode.OFF) },
- userDisplayName = "Alice",
setPerformLA = { _ -> },
showModal = { {} },
showSettingsModal = { {} },
diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/VersionInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/VersionInfoView.kt
index 52addd146b..5070c3c0aa 100644
--- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/VersionInfoView.kt
+++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/VersionInfoView.kt
@@ -1,33 +1,55 @@
package chat.simplex.common.views.usersettings
+import SectionBottomSpacer
+import SectionDividerSpaced
+import SectionView
+import itemHPadding
+import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
-import androidx.compose.runtime.Composable
+import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import dev.icerock.moko.resources.compose.stringResource
import chat.simplex.common.BuildConfigCommon
+import chat.simplex.common.model.ChatModel
import chat.simplex.common.model.CoreVersionInfo
import chat.simplex.common.platform.ColumnWithScrollBar
import chat.simplex.common.platform.appPlatform
-import chat.simplex.common.ui.theme.DEFAULT_PADDING
+import chat.simplex.common.platform.chatModel
+import chat.simplex.common.ui.theme.DEFAULT_PADDING_HALF
import chat.simplex.common.views.helpers.AppBarTitle
import chat.simplex.res.MR
@Composable
-fun VersionInfoView(info: CoreVersionInfo) {
- ColumnWithScrollBar(
- Modifier.padding(horizontal = DEFAULT_PADDING),
- ) {
- AppBarTitle(stringResource(MR.strings.app_version_title), withPadding = false)
- if (appPlatform.isAndroid) {
- Text(String.format(stringResource(MR.strings.app_version_name), BuildConfigCommon.ANDROID_VERSION_NAME))
- Text(String.format(stringResource(MR.strings.app_version_code), BuildConfigCommon.ANDROID_VERSION_CODE))
- } else {
- Text(String.format(stringResource(MR.strings.app_version_name), BuildConfigCommon.DESKTOP_VERSION_NAME))
- Text(String.format(stringResource(MR.strings.app_version_code), BuildConfigCommon.DESKTOP_VERSION_CODE))
+fun VersionInfoView(
+ showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
+ withAuth: (title: String, desc: String, block: () -> Unit) -> Unit,
+) {
+ val versionInfo = remember { mutableStateOf(null) }
+ LaunchedEffect(Unit) {
+ versionInfo.value = chatModel.controller.apiGetVersion()
+ }
+ ColumnWithScrollBar {
+ AppBarTitle(stringResource(MR.strings.app_version_title))
+ SectionView {
+ Column(Modifier.padding(horizontal = itemHPadding, vertical = DEFAULT_PADDING_HALF)) {
+ if (appPlatform.isAndroid) {
+ Text(String.format(stringResource(MR.strings.app_version_name), BuildConfigCommon.ANDROID_VERSION_NAME))
+ Text(String.format(stringResource(MR.strings.app_version_code), BuildConfigCommon.ANDROID_VERSION_CODE))
+ } else {
+ Text(String.format(stringResource(MR.strings.app_version_name), BuildConfigCommon.DESKTOP_VERSION_NAME))
+ Text(String.format(stringResource(MR.strings.app_version_code), BuildConfigCommon.DESKTOP_VERSION_CODE))
+ }
+ versionInfo.value?.let { info ->
+ Text(String.format(stringResource(MR.strings.core_version), info.version))
+ val simplexmqCommit = if (info.simplexmqCommit.length >= 7) info.simplexmqCommit.substring(startIndex = 0, endIndex = 7) else info.simplexmqCommit
+ Text(String.format(stringResource(MR.strings.core_simplexmq_version), info.simplexmqVersion, simplexmqCommit))
+ }
+ }
}
- Text(String.format(stringResource(MR.strings.core_version), info.version))
- val simplexmqCommit = if (info.simplexmqCommit.length >= 7) info.simplexmqCommit.substring(startIndex = 0, endIndex = 7) else info.simplexmqCommit
- Text(String.format(stringResource(MR.strings.core_simplexmq_version), info.simplexmqVersion, simplexmqCommit))
+ SectionDividerSpaced()
+
+ AdvancedSettingsAppSection(showSettingsModal, withAuth)
+ SectionBottomSpacer()
}
}
diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml
index ee79fc0af0..5bca9402a8 100644
--- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml
+++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml
@@ -1555,6 +1555,13 @@
Files
Send delivery receipts to
Contact requests from groups
+ About
+ Contact
+ Support the project
+ Chat data
+ Help & support
+ More privacy
+ Advanced settings
Restart
Shutdown
Developer tools
@@ -2681,7 +2688,7 @@
Don\'t enable
You can enable later via Settings
Delivery receipts are disabled!
- You can enable them later via app Privacy & Security settings.
+ You can enable them later via app Your privacy settings.
Error enabling delivery receipts!
diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.desktop.kt
index 5b4a044df3..174ad63c7a 100644
--- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.desktop.kt
+++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.desktop.kt
@@ -1,27 +1,21 @@
package chat.simplex.common.views.usersettings
import SectionView
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.padding
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
+import androidx.compose.runtime.*
import chat.simplex.common.model.ChatController.appPrefs
import chat.simplex.common.model.ChatModel
-import chat.simplex.common.platform.AppUpdatesChannel
-import chat.simplex.common.ui.theme.DEFAULT_PADDING_HALF
+import chat.simplex.common.platform.*
import chat.simplex.common.views.helpers.*
import chat.simplex.res.MR
import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource
@Composable
-actual fun SettingsSectionApp(
+actual fun AdvancedSettingsAppSection(
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
- showVersion: () -> Unit,
- withAuth: (title: String, desc: String, block: () -> Unit) -> Unit
+ withAuth: (title: String, desc: String, block: () -> Unit) -> Unit,
) {
- SectionView(stringResource(MR.strings.settings_section_title_app)) {
+ SectionView {
SettingsActionItem(painterResource(MR.images.ic_code), stringResource(MR.strings.settings_developer_tools), showSettingsModal { DeveloperView(withAuth) })
val selectedChannel = remember { appPrefs.appUpdateChannel.state }
val values = AppUpdatesChannel.entries.map { it to it.text }
@@ -29,6 +23,8 @@ actual fun SettingsSectionApp(
appPrefs.appUpdateChannel.set(it)
setupUpdateChecker()
}
- AppVersionItem(showVersion)
}
}
+
+@Composable
+actual fun AppShutdownItem() {}