From 4b0046a60b7caca2625b5252287cd9f53041ef29 Mon Sep 17 00:00:00 2001
From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
Date: Sun, 22 Jan 2023 18:34:01 +0000
Subject: [PATCH] mobile: show version information (#1820)
* mobile: show version information
* export localizations
---
.../java/chat/simplex/app/model/SimpleXAPI.kt | 23 ++++++++++
.../app/views/usersettings/SettingsView.kt | 20 ++++++---
.../app/views/usersettings/VersionInfoView.kt | 29 ++++++++++++
.../app/src/main/res/values/strings.xml | 6 +++
apps/ios/Shared/Model/SimpleXAPI.swift | 6 +++
.../Views/UserSettings/SettingsView.swift | 7 ++-
.../Views/UserSettings/VersionView.swift | 43 ++++++++++++++++++
.../de.xcloc/Localized Contents/de.xliff | 20 +++++++++
.../en.xcloc/Localized Contents/en.xliff | 25 +++++++++++
.../fr.xcloc/Localized Contents/fr.xliff | 20 +++++++++
.../it.xcloc/Localized Contents/it.xliff | 20 +++++++++
.../ru.xcloc/Localized Contents/ru.xliff | 21 ++++++++-
apps/ios/SimpleX.xcodeproj/project.pbxproj | 44 ++++++++++---------
.../xcschemes/SimpleX (iOS).xcscheme | 1 -
apps/ios/SimpleXChat/APITypes.swift | 13 ++++++
15 files changed, 269 insertions(+), 29 deletions(-)
create mode 100644 apps/android/app/src/main/java/chat/simplex/app/views/usersettings/VersionInfoView.kt
create mode 100644 apps/ios/Shared/Views/UserSettings/VersionView.swift
diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt
index d65489149f..bd49ec5bdf 100644
--- a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt
+++ b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt
@@ -995,6 +995,16 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
}
}
+ suspend fun apiGetVersion(): CoreVersionInfo? {
+ val r = sendCmd(CC.ShowVersion())
+ return if (r is CR.VersionInfo) {
+ r.versionInfo
+ } else {
+ Log.e(TAG, "apiGetVersion bad response: ${r.responseType} ${r.details}")
+ null
+ }
+ }
+
private fun networkErrorAlert(r: CR): Boolean {
return when {
r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorAgent
@@ -1612,6 +1622,7 @@ sealed class CC {
class ApiChatRead(val type: ChatType, val id: Long, val range: ItemRange): CC()
class ApiChatUnread(val type: ChatType, val id: Long, val unreadChat: Boolean): CC()
class ReceiveFile(val fileId: Long, val inline: Boolean): CC()
+ class ShowVersion(): CC()
val cmdString: String get() = when (this) {
is Console -> cmd
@@ -1683,6 +1694,7 @@ sealed class CC {
is ApiChatRead -> "/_read chat ${chatRef(type, id)} from=${range.from} to=${range.to}"
is ApiChatUnread -> "/_unread chat ${chatRef(type, id)} ${onOff(unreadChat)}"
is ReceiveFile -> "/freceive $fileId inline=${onOff(inline)}"
+ is ShowVersion -> "/version"
}
val cmdType: String get() = when (this) {
@@ -1755,6 +1767,7 @@ sealed class CC {
is ApiChatRead -> "apiChatRead"
is ApiChatUnread -> "apiChatUnread"
is ReceiveFile -> "receiveFile"
+ is ShowVersion -> "showVersion"
}
class ItemRange(val from: Long, val to: Long)
@@ -2733,6 +2746,7 @@ sealed class CR {
@Serializable @SerialName("callEnded") class CallEnded(val contact: Contact): CR()
@Serializable @SerialName("newContactConnection") class NewContactConnection(val connection: PendingContactConnection): CR()
@Serializable @SerialName("contactConnectionDeleted") class ContactConnectionDeleted(val connection: PendingContactConnection): CR()
+ @Serializable @SerialName("versionInfo") class VersionInfo(val versionInfo: CoreVersionInfo): CR()
@Serializable @SerialName("cmdOk") class CmdOk: CR()
@Serializable @SerialName("chatCmdError") class ChatCmdError(val chatError: ChatError): CR()
@Serializable @SerialName("chatError") class ChatRespError(val chatError: ChatError): CR()
@@ -2831,6 +2845,7 @@ sealed class CR {
is CallEnded -> "callEnded"
is NewContactConnection -> "newContactConnection"
is ContactConnectionDeleted -> "contactConnectionDeleted"
+ is VersionInfo -> "versionInfo"
is CmdOk -> "cmdOk"
is ChatCmdError -> "chatCmdError"
is ChatRespError -> "chatError"
@@ -2930,6 +2945,7 @@ sealed class CR {
is CallEnded -> "contact: ${contact.id}"
is NewContactConnection -> json.encodeToString(connection)
is ContactConnectionDeleted -> json.encodeToString(connection)
+ is VersionInfo -> json.encodeToString(versionInfo)
is CmdOk -> noDetails()
is ChatCmdError -> chatError.string
is ChatRespError -> chatError.string
@@ -2987,6 +3003,13 @@ class AutoAccept(val acceptIncognito: Boolean, val autoReply: MsgContent?) {
}
}
+@Serializable
+data class CoreVersionInfo(
+ val version: String,
+ val buildTimestamp: String,
+ val simplexmqVersion: String,
+ val simplexmqCommit: String
+)
@Serializable
sealed class ChatError {
diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt
index c64bb12b11..f2c9446187 100644
--- a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt
+++ b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt
@@ -5,6 +5,7 @@ import SectionItemView
import SectionSpacer
import SectionView
import android.content.res.Configuration
+import android.icu.util.VersionInfo
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
@@ -57,7 +58,14 @@ fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit) {
showSettingsModal = { modalView -> { ModalManager.shared.showModal(true) { modalView(chatModel) } } },
showCustomModal = { modalView -> { ModalManager.shared.showCustomModal { close -> modalView(chatModel, close) } } },
showTerminal = { ModalManager.shared.showCustomModal { close -> TerminalView(chatModel, close) } },
-// showVideoChatPrototype = { ModalManager.shared.showCustomModal { close -> CallViewDebug(close) } },
+ showVersion = {
+ withApi {
+ val info = chatModel.controller.apiGetVersion()
+ if (info != null) {
+ ModalManager.shared.showModal { VersionInfoView(info) }
+ }
+ }
+ }
)
}
}
@@ -89,7 +97,7 @@ fun SettingsLayout(
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
showCustomModal: (@Composable (ChatModel, () -> Unit) -> Unit) -> (() -> Unit),
showTerminal: () -> Unit,
-// showVideoChatPrototype: () -> Unit
+ showVersion: () -> Unit
) {
val uriHandler = LocalUriHandler.current
Surface(Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
@@ -170,7 +178,7 @@ fun SettingsLayout(
}
// SettingsActionItem(Icons.Outlined.Science, stringResource(R.string.settings_experimental_features), showSettingsModal { ExperimentalFeaturesView(it, enableCalls) })
// SectionDivider()
- AppVersionItem()
+ AppVersionItem(showVersion)
}
}
}
@@ -345,8 +353,8 @@ fun MaintainIncognitoState(chatModel: ChatModel) {
}
}
-@Composable private fun AppVersionItem() {
- SectionItemView() {
+@Composable private fun AppVersionItem(showVersion: () -> Unit) {
+ SectionItemView(showVersion) {
Text("v${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})")
}
}
@@ -491,7 +499,7 @@ fun PreviewSettingsLayout() {
showSettingsModal = { {} },
showCustomModal = { {} },
showTerminal = {},
-// showVideoChatPrototype = {}
+ showVersion = {}
)
}
}
diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/VersionInfoView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/VersionInfoView.kt
new file mode 100644
index 0000000000..80a32c0858
--- /dev/null
+++ b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/VersionInfoView.kt
@@ -0,0 +1,29 @@
+package chat.simplex.app.views.usersettings
+
+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.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import chat.simplex.app.BuildConfig
+import chat.simplex.app.R
+import chat.simplex.app.model.CoreVersionInfo
+import chat.simplex.app.ui.theme.DEFAULT_PADDING
+import chat.simplex.app.views.helpers.AppBarTitle
+
+@Composable
+fun VersionInfoView(info: CoreVersionInfo) {
+ Column(
+ Modifier.padding(horizontal = DEFAULT_PADDING),
+ horizontalAlignment = Alignment.Start
+ ) {
+ AppBarTitle(stringResource(R.string.app_version_title), false)
+ Text(String.format(stringResource(R.string.app_version_name), BuildConfig.VERSION_NAME))
+ Text(String.format(stringResource(R.string.app_version_code), BuildConfig.VERSION_CODE))
+ Text(String.format(stringResource(R.string.core_version), info.version))
+ Text(String.format(stringResource(R.string.core_build_timestamp), info.buildTimestamp))
+ Text(String.format(stringResource(R.string.core_simplexmq_version), info.simplexmqVersion, info.simplexmqCommit.substring(startIndex = 0, endIndex = 7)))
+ }
+}
diff --git a/apps/android/app/src/main/res/values/strings.xml b/apps/android/app/src/main/res/values/strings.xml
index f6f3a605f8..6e73a07e20 100644
--- a/apps/android/app/src/main/res/values/strings.xml
+++ b/apps/android/app/src/main/res/values/strings.xml
@@ -479,6 +479,12 @@
Onion hosts will not be used.
Onion hosts will be required for connection.
Appearance
+ App version
+ App version: v%s
+ App build: %s
+ Core version: v%s
+ Core built at: %s
+ simplexmq: v%s (%2s)
Create address
diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift
index 8cf06ba065..0af9c0d6c7 100644
--- a/apps/ios/Shared/Model/SimpleXAPI.swift
+++ b/apps/ios/Shared/Model/SimpleXAPI.swift
@@ -851,6 +851,12 @@ func apiGetGroupLink(_ groupId: Int64) throws -> String? {
}
}
+func apiGetVersion() throws -> CoreVersionInfo {
+ let r = chatSendCmdSync(.showVersion)
+ if case let .versionInfo(info) = r { return info }
+ throw r
+}
+
func initializeChat(start: Bool, dbKey: String? = nil) throws {
logger.debug("initializeChat")
let m = ChatModel.shared
diff --git a/apps/ios/Shared/Views/UserSettings/SettingsView.swift b/apps/ios/Shared/Views/UserSettings/SettingsView.swift
index f41c022dc3..2180a36c7d 100644
--- a/apps/ios/Shared/Views/UserSettings/SettingsView.swift
+++ b/apps/ios/Shared/Views/UserSettings/SettingsView.swift
@@ -271,7 +271,12 @@ struct SettingsView: View {
// } label: {
// settingsRow("gauge") { Text("Experimental features") }
// }
- Text("v\(appVersion ?? "?") (\(appBuild ?? "?"))")
+ NavigationLink {
+ VersionView()
+ .navigationBarTitle("App version")
+ } label: {
+ Text("v\(appVersion ?? "?") (\(appBuild ?? "?"))")
+ }
}
}
.navigationTitle("Your settings")
diff --git a/apps/ios/Shared/Views/UserSettings/VersionView.swift b/apps/ios/Shared/Views/UserSettings/VersionView.swift
new file mode 100644
index 0000000000..9f13e4a95b
--- /dev/null
+++ b/apps/ios/Shared/Views/UserSettings/VersionView.swift
@@ -0,0 +1,43 @@
+//
+// VersionView.swift
+// SimpleXChat
+//
+// Created by Evgeny on 22/01/2023.
+// Copyright © 2023 SimpleX Chat. All rights reserved.
+//
+
+import SwiftUI
+import SimpleXChat
+
+struct VersionView: View {
+ @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)")
+ Text("Core built at: \(info.buildTimestamp)")
+ 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)
+ }
+ }
+ }
+ .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
+ .padding()
+ .onAppear {
+ do {
+ versionInfo = try apiGetVersion()
+ } catch let error {
+ logger.error("apiGetVersion error: \(responseError(error))")
+ }
+ }
+ }
+}
+
+struct VersionView_Previews: PreviewProvider {
+ static var previews: some View {
+ VersionView()
+ }
+}
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 f359101580..fb5e7947dc 100644
--- a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff
+++ b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff
@@ -463,11 +463,23 @@
Anruf annehmen
No comment provided by engineer.
+
+ App build: %@
+ No comment provided by engineer.
+
App icon
App Icon
No comment provided by engineer.
+
+ App version
+ No comment provided by engineer.
+
+
+ App version: v%@
+ No comment provided by engineer.
+
Appearance
Design
@@ -828,6 +840,14 @@
Kopieren
chat item action
+
+ Core built at: %@
+ No comment provided by engineer.
+
+
+ Core version: v%@
+ No comment provided by engineer.
+
Create
Erstellen
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 847b3e2878..1e707f082e 100644
--- a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff
+++ b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff
@@ -463,11 +463,26 @@
Answer call
No comment provided by engineer.
+
+ App build: %@
+ App build: %@
+ No comment provided by engineer.
+
App icon
App icon
No comment provided by engineer.
+
+ App version
+ App version
+ No comment provided by engineer.
+
+
+ App version: v%@
+ App version: v%@
+ No comment provided by engineer.
+
Appearance
Appearance
@@ -828,6 +843,16 @@
Copy
chat item action
+
+ Core built at: %@
+ Core built at: %@
+ No comment provided by engineer.
+
+
+ Core version: v%@
+ Core version: v%@
+ No comment provided by engineer.
+
Create
Create
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 f35a16ed3a..573377773c 100644
--- a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff
+++ b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff
@@ -463,11 +463,23 @@
Répondre à l'appel
No comment provided by engineer.
+
+ App build: %@
+ No comment provided by engineer.
+
App icon
Icône de l'app
No comment provided by engineer.
+
+ App version
+ No comment provided by engineer.
+
+
+ App version: v%@
+ No comment provided by engineer.
+
Appearance
Apparence
@@ -828,6 +840,14 @@
Copier
chat item action
+
+ Core built at: %@
+ No comment provided by engineer.
+
+
+ Core version: v%@
+ No comment provided by engineer.
+
Create
Créer
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 5841619864..290beb8a9a 100644
--- a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff
+++ b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff
@@ -463,11 +463,23 @@
Rispondi alla chiamata
No comment provided by engineer.
+
+ App build: %@
+ No comment provided by engineer.
+
App icon
Icona app
No comment provided by engineer.
+
+ App version
+ No comment provided by engineer.
+
+
+ App version: v%@
+ No comment provided by engineer.
+
Appearance
Aspetto
@@ -828,6 +840,14 @@
Copia
chat item action
+
+ Core built at: %@
+ No comment provided by engineer.
+
+
+ Core version: v%@
+ No comment provided by engineer.
+
Create
Crea
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 af7aa75f75..133021d01c 100644
--- a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff
+++ b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff
@@ -463,11 +463,23 @@
Принять звонок
No comment provided by engineer.
+
+ App build: %@
+ No comment provided by engineer.
+
App icon
Иконка
No comment provided by engineer.
+
+ App version
+ No comment provided by engineer.
+
+
+ App version: v%@
+ No comment provided by engineer.
+
Appearance
Интерфейс
@@ -828,6 +840,14 @@
Скопировать
chat item action
+
+ Core built at: %@
+ No comment provided by engineer.
+
+
+ Core version: v%@
+ No comment provided by engineer.
+
Create
Создать
@@ -2275,7 +2295,6 @@ We will be adding server redundancy to prevent lost messages.
PING count
- Количество PING
No comment provided by engineer.
diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj
index 4f000ced74..3268cc17c7 100644
--- a/apps/ios/SimpleX.xcodeproj/project.pbxproj
+++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj
@@ -48,6 +48,12 @@
5C5E5D3B2824468B00B0488A /* ActiveCallView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5E5D3A2824468B00B0488A /* ActiveCallView.swift */; };
5C5F2B6D27EBC3FE006A9D5F /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5F2B6C27EBC3FE006A9D5F /* ImagePicker.swift */; };
5C5F2B7027EBC704006A9D5F /* ProfileImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5F2B6F27EBC704006A9D5F /* ProfileImage.swift */; };
+ 5C65F33C297D3D9700B67AF3 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65F337297D3D9700B67AF3 /* libgmpxx.a */; };
+ 5C65F33D297D3D9700B67AF3 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65F338297D3D9700B67AF3 /* libgmp.a */; };
+ 5C65F33E297D3D9700B67AF3 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65F339297D3D9700B67AF3 /* libffi.a */; };
+ 5C65F33F297D3D9700B67AF3 /* libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65F33A297D3D9700B67AF3 /* libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r-ghc8.10.7.a */; };
+ 5C65F340297D3D9700B67AF3 /* libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C65F33B297D3D9700B67AF3 /* libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r.a */; };
+ 5C65F343297D45E100B67AF3 /* VersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C65F341297D3F3600B67AF3 /* VersionView.swift */; };
5C6AD81327A834E300348BD7 /* NewChatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6AD81227A834E300348BD7 /* NewChatButton.swift */; };
5C6BA667289BD954009B8ECC /* DismissSheets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6BA666289BD954009B8ECC /* DismissSheets.swift */; };
5C7031162953C97F00150A12 /* CIFeaturePreferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7031152953C97F00150A12 /* CIFeaturePreferenceView.swift */; };
@@ -97,11 +103,6 @@
5CB9250D27A9432000ACCCDD /* ChatListNavLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB9250C27A9432000ACCCDD /* ChatListNavLink.swift */; };
5CBD285A295711D700EC2CF4 /* ImageUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBD2859295711D700EC2CF4 /* ImageUtils.swift */; };
5CBD285C29575B8E00EC2CF4 /* WhatsNewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBD285B29575B8E00EC2CF4 /* WhatsNewView.swift */; };
- 5CBDFB57297A883C00E723C8 /* libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CBDFB52297A883C00E723C8 /* libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca.a */; };
- 5CBDFB58297A883C00E723C8 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CBDFB53297A883C00E723C8 /* libgmpxx.a */; };
- 5CBDFB59297A883C00E723C8 /* libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CBDFB54297A883C00E723C8 /* libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca-ghc8.10.7.a */; };
- 5CBDFB5A297A883C00E723C8 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CBDFB55297A883C00E723C8 /* libffi.a */; };
- 5CBDFB5B297A883C00E723C8 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CBDFB56297A883C00E723C8 /* libgmp.a */; };
5CBE6C12294487F7002D9531 /* VerifyCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBE6C11294487F7002D9531 /* VerifyCodeView.swift */; };
5CBE6C142944CC12002D9531 /* ScanCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBE6C132944CC12002D9531 /* ScanCodeView.swift */; };
5CC1C99227A6C7F5000D9FF6 /* QRCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CC1C99127A6C7F5000D9FF6 /* QRCode.swift */; };
@@ -265,6 +266,12 @@
5C5E5D3C282447AB00B0488A /* CallTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallTypes.swift; sourceTree = ""; };
5C5F2B6C27EBC3FE006A9D5F /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = ""; };
5C5F2B6F27EBC704006A9D5F /* ProfileImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileImage.swift; sourceTree = ""; };
+ 5C65F337297D3D9700B67AF3 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; };
+ 5C65F338297D3D9700B67AF3 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; };
+ 5C65F339297D3D9700B67AF3 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; };
+ 5C65F33A297D3D9700B67AF3 /* libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r-ghc8.10.7.a"; sourceTree = ""; };
+ 5C65F33B297D3D9700B67AF3 /* libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r.a"; sourceTree = ""; };
+ 5C65F341297D3F3600B67AF3 /* VersionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionView.swift; sourceTree = ""; };
5C6AD81227A834E300348BD7 /* NewChatButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewChatButton.swift; sourceTree = ""; };
5C6BA666289BD954009B8ECC /* DismissSheets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissSheets.swift; sourceTree = ""; };
5C7031152953C97F00150A12 /* CIFeaturePreferenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIFeaturePreferenceView.swift; sourceTree = ""; };
@@ -327,11 +334,6 @@
5CBD285829565D2600EC2CF4 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; };
5CBD2859295711D700EC2CF4 /* ImageUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageUtils.swift; sourceTree = ""; };
5CBD285B29575B8E00EC2CF4 /* WhatsNewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhatsNewView.swift; sourceTree = ""; };
- 5CBDFB52297A883C00E723C8 /* libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca.a"; sourceTree = ""; };
- 5CBDFB53297A883C00E723C8 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; };
- 5CBDFB54297A883C00E723C8 /* libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca-ghc8.10.7.a"; sourceTree = ""; };
- 5CBDFB55297A883C00E723C8 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; };
- 5CBDFB56297A883C00E723C8 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; };
5CBE6C11294487F7002D9531 /* VerifyCodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifyCodeView.swift; sourceTree = ""; };
5CBE6C132944CC12002D9531 /* ScanCodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanCodeView.swift; sourceTree = ""; };
5CC1C99127A6C7F5000D9FF6 /* QRCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCode.swift; sourceTree = ""; };
@@ -424,12 +426,12 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 5CBDFB58297A883C00E723C8 /* libgmpxx.a in Frameworks */,
- 5CBDFB5B297A883C00E723C8 /* libgmp.a in Frameworks */,
- 5CBDFB5A297A883C00E723C8 /* libffi.a in Frameworks */,
+ 5C65F33C297D3D9700B67AF3 /* libgmpxx.a in Frameworks */,
+ 5C65F340297D3D9700B67AF3 /* libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r.a in Frameworks */,
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
- 5CBDFB59297A883C00E723C8 /* libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca-ghc8.10.7.a in Frameworks */,
- 5CBDFB57297A883C00E723C8 /* libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca.a in Frameworks */,
+ 5C65F33D297D3D9700B67AF3 /* libgmp.a in Frameworks */,
+ 5C65F33F297D3D9700B67AF3 /* libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r-ghc8.10.7.a in Frameworks */,
+ 5C65F33E297D3D9700B67AF3 /* libffi.a in Frameworks */,
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -488,11 +490,11 @@
5C764E5C279C70B7000C6508 /* Libraries */ = {
isa = PBXGroup;
children = (
- 5CBDFB55297A883C00E723C8 /* libffi.a */,
- 5CBDFB56297A883C00E723C8 /* libgmp.a */,
- 5CBDFB53297A883C00E723C8 /* libgmpxx.a */,
- 5CBDFB54297A883C00E723C8 /* libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca-ghc8.10.7.a */,
- 5CBDFB52297A883C00E723C8 /* libHSsimplex-chat-4.4.4-GH5mduSQmlJ14EbWq6Ljca.a */,
+ 5C65F339297D3D9700B67AF3 /* libffi.a */,
+ 5C65F338297D3D9700B67AF3 /* libgmp.a */,
+ 5C65F337297D3D9700B67AF3 /* libgmpxx.a */,
+ 5C65F33A297D3D9700B67AF3 /* libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r-ghc8.10.7.a */,
+ 5C65F33B297D3D9700B67AF3 /* libHSsimplex-chat-4.4.4-696z0wvJHN7Hvtog9MKb6r.a */,
);
path = Libraries;
sourceTree = "";
@@ -642,6 +644,7 @@
5CB2084E28DA4B4800D024EC /* RTCServers.swift */,
5C3F1D592844B4DE00EC8A82 /* ExperimentalFeaturesView.swift */,
64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */,
+ 5C65F341297D3F3600B67AF3 /* VersionView.swift */,
);
path = UserSettings;
sourceTree = "";
@@ -993,6 +996,7 @@
5C00164428A26FBC0094D739 /* ContextMenu.swift in Sources */,
5C3A88D127DF57800060F1C2 /* FramedItemView.swift in Sources */,
5CB924E427A8683A00ACCCDD /* UserAddress.swift in Sources */,
+ 5C65F343297D45E100B67AF3 /* VersionView.swift in Sources */,
64F1CC3B28B39D8600CD1FB1 /* IncognitoHelp.swift in Sources */,
5CB0BA90282713D900B3292C /* SimpleXInfo.swift in Sources */,
5C063D2727A4564100AEC577 /* ChatPreviewView.swift in Sources */,
diff --git a/apps/ios/SimpleX.xcodeproj/xcshareddata/xcschemes/SimpleX (iOS).xcscheme b/apps/ios/SimpleX.xcodeproj/xcshareddata/xcschemes/SimpleX (iOS).xcscheme
index 8b60dc4fae..6a1d4192e6 100644
--- a/apps/ios/SimpleX.xcodeproj/xcshareddata/xcschemes/SimpleX (iOS).xcscheme
+++ b/apps/ios/SimpleX.xcodeproj/xcshareddata/xcschemes/SimpleX (iOS).xcscheme
@@ -44,7 +44,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- enableAddressSanitizer = "YES"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift
index fc1576dec5..66d3cd138b 100644
--- a/apps/ios/SimpleXChat/APITypes.swift
+++ b/apps/ios/SimpleXChat/APITypes.swift
@@ -89,6 +89,7 @@ public enum ChatCommand {
case apiChatRead(type: ChatType, id: Int64, itemRange: (Int64, Int64))
case apiChatUnread(type: ChatType, id: Int64, unreadChat: Bool)
case receiveFile(fileId: Int64, inline: Bool)
+ case showVersion
case string(String)
public var cmdString: String {
@@ -174,6 +175,7 @@ public enum ChatCommand {
case let .apiChatRead(type, id, itemRange: (from, to)): return "/_read chat \(ref(type, id)) from=\(from) to=\(to)"
case let .apiChatUnread(type, id, unreadChat): return "/_unread chat \(ref(type, id)) \(onOff(unreadChat))"
case let .receiveFile(fileId, inline): return "/freceive \(fileId) inline=\(onOff(inline))"
+ case .showVersion: return "/version"
case let .string(str): return str
}
}
@@ -257,6 +259,7 @@ public enum ChatCommand {
case .apiChatRead: return "apiChatRead"
case .apiChatUnread: return "apiChatUnread"
case .receiveFile: return "receiveFile"
+ case .showVersion: return "showVersion"
case .string: return "console command"
}
}
@@ -399,6 +402,7 @@ public enum ChatResponse: Decodable, Error {
case ntfMessages(connEntity: ConnectionEntity?, msgTs: Date?, ntfMessages: [NtfMsgInfo])
case newContactConnection(connection: PendingContactConnection)
case contactConnectionDeleted(connection: PendingContactConnection)
+ case versionInfo(versionInfo: CoreVersionInfo)
case cmdOk
case chatCmdError(chatError: ChatError)
case chatError(chatError: ChatError)
@@ -502,6 +506,7 @@ public enum ChatResponse: Decodable, Error {
case .ntfMessages: return "ntfMessages"
case .newContactConnection: return "newContactConnection"
case .contactConnectionDeleted: return "contactConnectionDeleted"
+ case .versionInfo: return "versionInfo"
case .cmdOk: return "cmdOk"
case .chatCmdError: return "chatCmdError"
case .chatError: return "chatError"
@@ -608,6 +613,7 @@ public enum ChatResponse: Decodable, Error {
case let .ntfMessages(connEntity, msgTs, ntfMessages): return "connEntity: \(String(describing: connEntity))\nmsgTs: \(String(describing: msgTs))\nntfMessages: \(String(describing: ntfMessages))"
case let .newContactConnection(connection): return String(describing: connection)
case let .contactConnectionDeleted(connection): return String(describing: connection)
+ case let .versionInfo(versionInfo): return String(describing: versionInfo)
case .cmdOk: return noDetails
case let .chatCmdError(chatError): return String(describing: chatError)
case let .chatError(chatError): return String(describing: chatError)
@@ -1001,6 +1007,13 @@ public enum NotificationPreviewMode: String, SelectableItem {
public static var values: [NotificationPreviewMode] = [.message, .contact, .hidden]
}
+public struct CoreVersionInfo: Decodable {
+ public var version: String
+ public var buildTimestamp: String
+ public var simplexmqVersion: String
+ public var simplexmqCommit: String
+}
+
public func decodeJSON(_ json: String) -> T? {
if let data = json.data(using: .utf8) {
return try? jsonDecoder.decode(T.self, from: data)