diff --git a/.github/workflows/chat-lib-tests.yml b/.github/workflows/chat-lib-tests.yml
new file mode 100644
index 000000000..077d53721
--- /dev/null
+++ b/.github/workflows/chat-lib-tests.yml
@@ -0,0 +1,17 @@
+name: Chat Lib Tests
+
+on: [push]
+
+jobs:
+ test:
+
+ runs-on: ubuntu-18.04
+
+ steps:
+ - uses: actions/checkout@v1
+ - name: Test
+ run: cd packages/chat;
+ cmake . -Bbuild;
+ cd build;
+ cmake --build .;
+ ctest --verbose
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 2d0711a4a..c7babd89f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,3 +49,9 @@ stack.yaml.lock
# chat database
*.db
*.db.bak
+packages/android/.idea
+packages/chat/.idea
+packages/chat/build
+packages/chat/Testing
+packages/ios/SimpleX Chat.xcodeproj/project.xcworkspace/xcuserdata
+packages/ios/SimpleX Chat.xcodeproj/xcuserdata
diff --git a/packages/android/.idea/gradle.xml b/packages/android/.idea/gradle.xml
deleted file mode 100644
index 939f082ff..000000000
--- a/packages/android/.idea/gradle.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/packages/android/.idea/misc.xml b/packages/android/.idea/misc.xml
deleted file mode 100644
index 2a4d5b521..000000000
--- a/packages/android/.idea/misc.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/packages/android/app/build.gradle b/packages/android/app/build.gradle
index 11a522ca9..c273b87fe 100644
--- a/packages/android/app/build.gradle
+++ b/packages/android/app/build.gradle
@@ -41,17 +41,29 @@ android {
}
}
buildFeatures {
- viewBinding true
+ compose true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion "1.0.4"
+ kotlinCompilerVersion "1.5.31"
}
}
dependencies {
- implementation 'androidx.core:core-ktx:1.3.2'
- implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation 'com.google.android.material:material:1.3.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
- testImplementation 'junit:junit:4.+'
- androidTestImplementation 'androidx.test.ext:junit:1.1.2'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+ implementation 'androidx.core:core-ktx:1.6.0'
+ implementation 'androidx.appcompat:appcompat:1.3.1'
+ implementation "androidx.compose.ui:ui:1.0.4"
+ implementation "androidx.compose.runtime:runtime-livedata:1.0.4"
+ implementation "androidx.compose.material:material:1.0.4"
+ implementation "androidx.compose.animation:animation:1.0.4"
+ implementation "androidx.compose.animation:animation-core:1.0.4"
+ implementation 'androidx.activity:activity-compose:1.4.0-rc01'
+
+ implementation 'com.google.android.material:material:1.4.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
+ implementation 'androidx.compose.ui:ui-tooling-preview:1.0.4'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
\ No newline at end of file
diff --git a/packages/android/app/src/main/AndroidManifest.xml b/packages/android/app/src/main/AndroidManifest.xml
index cded1e033..db937e59c 100644
--- a/packages/android/app/src/main/AndroidManifest.xml
+++ b/packages/android/app/src/main/AndroidManifest.xml
@@ -11,6 +11,7 @@
android:theme="@style/Theme.SimpleXChat">
diff --git a/packages/android/app/src/main/cpp/CMakeLists.txt b/packages/android/app/src/main/cpp/CMakeLists.txt
index 362916c26..7c5377e46 100644
--- a/packages/android/app/src/main/cpp/CMakeLists.txt
+++ b/packages/android/app/src/main/cpp/CMakeLists.txt
@@ -9,6 +9,10 @@ cmake_minimum_required(VERSION 3.10.2)
project("app")
+include_directories(include)
+
+add_subdirectory( ../../../../../chat/src build/src )
+
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
@@ -45,4 +49,6 @@ target_link_libraries( # Specifies the target library.
# Links the target library to the log library
# included in the NDK.
- ${log-lib})
\ No newline at end of file
+ ${log-lib}
+
+ SimpleXChatLib)
\ No newline at end of file
diff --git a/packages/android/app/src/main/cpp/native-lib.cpp b/packages/android/app/src/main/cpp/native-lib.cpp
index 4c78ae521..2546d931b 100644
--- a/packages/android/app/src/main/cpp/native-lib.cpp
+++ b/packages/android/app/src/main/cpp/native-lib.cpp
@@ -1,10 +1,15 @@
#include
#include
+#include "../../../../../chat/include/protocol.h"
+
extern "C" JNIEXPORT jstring JNICALL
-Java_chat_simplex_app_MainActivity_stringFromJNI(
+Java_chat_simplex_app_Protocol_executeCommand(
JNIEnv* env,
- jobject /* this */) {
- std::string hello = "Hello from C++";
- return env->NewStringUTF(hello.c_str());
+ jclass clazz,
+ jstring command) {
+ const char *utf8command = env->GetStringUTFChars(command, JNI_FALSE);
+ jstring result = env->NewStringUTF(executeCommand(utf8command));
+ env->ReleaseStringUTFChars(command, utf8command);
+ return result;
}
\ No newline at end of file
diff --git a/packages/android/app/src/main/java/chat/simplex/app/MainActivity.kt b/packages/android/app/src/main/java/chat/simplex/app/MainActivity.kt
index bb4a523b4..a9a85d58e 100644
--- a/packages/android/app/src/main/java/chat/simplex/app/MainActivity.kt
+++ b/packages/android/app/src/main/java/chat/simplex/app/MainActivity.kt
@@ -1,34 +1,91 @@
package chat.simplex.app
-import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
-import android.widget.TextView
-import chat.simplex.app.databinding.ActivityMainBinding
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.foundation.lazy.rememberLazyListState
+import androidx.compose.foundation.text.KeyboardActions
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material.*
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Send
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment.Companion.Center
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
-class MainActivity : AppCompatActivity() {
-
- private lateinit var binding: ActivityMainBinding
+class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- binding = ActivityMainBinding.inflate(layoutInflater)
- setContentView(binding.root)
+ setContent {
+ var history by remember { mutableStateOf(mutableListOf("Session started:")) }
+ var inputValue by remember { mutableStateOf("") }
+ var inProgress by remember { mutableStateOf(false) }
- // Example of a call to a native method
- binding.sampleText.text = stringFromJNI()
- }
+ fun sendMessage() {
+ CoroutineScope(Dispatchers.IO).launch {
+ inProgress = true
+ val str = Protocol.executeCommand(inputValue)
+ inputValue = ""
+ val newList = mutableListOf()
+ newList.addAll(history)
+ newList.add(str)
+ Thread.sleep(1000); // emulate work
+ history = newList
+ inProgress = false
+ }
+ }
- /**
- * A native method that is implemented by the 'app' native library,
- * which is packaged with this application.
- */
- external fun stringFromJNI(): String
-
- companion object {
- // Used to load the 'app' library on application startup.
- init {
- System.loadLibrary("app")
+ MaterialTheme(colors = lightColors()) {
+ Surface(color = Color.White) {
+ Column {
+ LazyColumn(Modifier.weight(1.0f).fillMaxWidth()) {
+ itemsIndexed(history) { index: Int, message: String ->
+ if (index == 0) {
+ Spacer(modifier = Modifier.height(8.dp))
+ }
+ MessageView(message = message)
+ }
+ }
+ Row {
+ TextField(
+ modifier = Modifier.weight(1f),
+ value = inputValue,
+ onValueChange = { inputValue = it },
+ keyboardOptions = KeyboardOptions(imeAction = androidx.compose.ui.text.input.ImeAction.Send),
+ keyboardActions = KeyboardActions { sendMessage() },
+ singleLine = true
+ )
+ if (inProgress) {
+ Box(Modifier.height(56.dp).width(56.dp)) {
+ CircularProgressIndicator(modifier = Modifier.align(Center))
+ }
+ }
+ else {
+ Button(
+ modifier = Modifier.height(56.dp),
+ onClick = { sendMessage() },
+ enabled = inputValue.isNotBlank(),
+ ) {
+ Icon(
+ imageVector = Icons.Default.Send,
+ contentDescription = "Send"
+ )
+ }
+ }
+ }
+ }
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/packages/android/app/src/main/java/chat/simplex/app/MessageView.kt b/packages/android/app/src/main/java/chat/simplex/app/MessageView.kt
new file mode 100644
index 000000000..c578bc128
--- /dev/null
+++ b/packages/android/app/src/main/java/chat/simplex/app/MessageView.kt
@@ -0,0 +1,35 @@
+package chat.simplex.app
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+
+@Composable
+fun MessageView(message: String) {
+ Box(Modifier.padding(4.dp)) {
+ Surface(color = Color.LightGray, modifier = Modifier.clip(shape = RoundedCornerShape(8.dp))) {
+ Box(Modifier.padding(8.dp)) {
+ Text(text = message)
+ }
+ }
+ }
+}
+
+@Preview(showBackground = true,
+ widthDp = 200,
+ heightDp = 50,
+ backgroundColor = android.graphics.Color.BLACK.toLong())
+@Composable
+fun DefaultMessageView() {
+ // A surface container using the 'background' color from the theme
+ Surface(color = Color.White, modifier = Modifier.padding(16.dp)) {
+ MessageView(message = "Hello world!")
+ }
+}
\ No newline at end of file
diff --git a/packages/android/app/src/main/java/chat/simplex/app/Protocol.kt b/packages/android/app/src/main/java/chat/simplex/app/Protocol.kt
new file mode 100644
index 000000000..6191ead68
--- /dev/null
+++ b/packages/android/app/src/main/java/chat/simplex/app/Protocol.kt
@@ -0,0 +1,18 @@
+package chat.simplex.app
+
+class Protocol {
+
+ companion object {
+ // Used to load the 'app' library on application startup.
+ init {
+ System.loadLibrary("app")
+ }
+
+ /**
+ * A native method that is implemented by the 'app' native library,
+ * which is packaged with this application.
+ */
+ @JvmStatic
+ external fun executeCommand(command: String): String
+ }
+}
\ No newline at end of file
diff --git a/packages/android/build.gradle b/packages/android/build.gradle
index 9db2bf12c..d4efb6264 100644
--- a/packages/android/build.gradle
+++ b/packages/android/build.gradle
@@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath "com.android.tools.build:gradle:7.0.2"
+ classpath "com.android.tools.build:gradle:7.0.3"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31"
// NOTE: Do not place your application dependencies here; they belong
diff --git a/packages/chat/CMakeLists.txt b/packages/chat/CMakeLists.txt
new file mode 100644
index 000000000..5022b0bec
--- /dev/null
+++ b/packages/chat/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.11) # set min version of cmake
+
+project(SimpleXChat)
+
+enable_testing()
+
+include_directories(include)
+
+add_subdirectory( src build/src )
+add_subdirectory( test build/test )
\ No newline at end of file
diff --git a/packages/chat/include/protocol.h b/packages/chat/include/protocol.h
new file mode 100644
index 000000000..1ef9547c9
--- /dev/null
+++ b/packages/chat/include/protocol.h
@@ -0,0 +1,17 @@
+// Public API: Protocol.h
+
+#ifndef protocol_h
+#define protocol_h
+
+#ifdef __cplusplus
+extern "C" { // only need to export C interface if
+// used by C++ source code
+#endif
+
+const char* executeCommand(const char* command);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* protocol_h */
diff --git a/packages/chat/src/CMakeLists.txt b/packages/chat/src/CMakeLists.txt
new file mode 100644
index 000000000..e8aa463cd
--- /dev/null
+++ b/packages/chat/src/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.10) # set min version of cmake
+
+project(SimpleXChatLib) # create chat lib
+
+set(CMAKE_CXX_STANDARD 17)
+# set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-header-filter=../include;-checks=*;")
+
+include_directories ("${PROJECT_SOURCE_DIR}/../include")
+file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/*.cpp)
+add_library(SimpleXChatLib STATIC ${SRC_FILES})
diff --git a/packages/chat/src/protocol.c b/packages/chat/src/protocol.c
deleted file mode 100644
index d6c0aa46d..000000000
--- a/packages/chat/src/protocol.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "protocol.h"
-
-extern void commandSend(Message m) {
-
-}
-
-Message getMessage() {
- Message m;
- m.message = "123";
- m.date = 1000;
- return m;
-}
-
diff --git a/packages/chat/src/protocol.cpp b/packages/chat/src/protocol.cpp
new file mode 100644
index 000000000..17eb1d636
--- /dev/null
+++ b/packages/chat/src/protocol.cpp
@@ -0,0 +1,16 @@
+#include "protocol.h"
+
+#include
+
+using ::std::string;
+
+const char* executeCommand(const char *command) {
+ if (command == nullptr) {
+ auto *output = new string("> \nFailed");
+ return output->c_str();
+ }
+ string cmd(command);
+ string result = "Successful";
+ auto *output = new string("> " + cmd + "\n" + result);
+ return output->c_str();
+}
\ No newline at end of file
diff --git a/packages/chat/src/protocol.h b/packages/chat/src/protocol.h
deleted file mode 100644
index 8fc093f82..000000000
--- a/packages/chat/src/protocol.h
+++ /dev/null
@@ -1,9 +0,0 @@
-
-struct Message {
- char* message;
- long date;
-}
-
-void commandSend(Message m);
-
-Message getMessage();
diff --git a/packages/chat/test/CMakeLists.txt b/packages/chat/test/CMakeLists.txt
new file mode 100644
index 000000000..45768cb43
--- /dev/null
+++ b/packages/chat/test/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.11)
+project(SimpleXChatTest)
+
+include(FetchContent)
+FetchContent_Declare(
+ googletest
+ # Specify the commit you depend on and update it regularly.
+ URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
+)
+FetchContent_MakeAvailable(googletest)
+
+# Now simply link against gtest or gtest_main as needed. Eg
+file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/*.cpp)
+add_executable(SimpleXChatTest ${SRC_FILES})
+
+target_link_libraries(SimpleXChatTest gtest_main SimpleXChatLib)
+add_test(NAME SimpleXChatTest COMMAND SimpleXChatTest)
diff --git a/packages/chat/test/protocol_test.cpp b/packages/chat/test/protocol_test.cpp
new file mode 100644
index 000000000..6b252ce73
--- /dev/null
+++ b/packages/chat/test/protocol_test.cpp
@@ -0,0 +1,18 @@
+
+#include "protocol.h"
+#include "gtest/gtest.h"
+
+namespace {
+
+TEST(ProtocolTest, SuccessfulCommand) {
+
+ EXPECT_STREQ(executeCommand("Test1"), "> Test1\nSuccessful");
+ EXPECT_STREQ(executeCommand("Test2"), "> Test2\nSuccessful");
+ EXPECT_STREQ(executeCommand("Test3"), "> Test3\nSuccessful");
+}
+
+TEST(ProtocolTest, NullCommand) {
+ EXPECT_STREQ(executeCommand(nullptr), "> \nFailed");
+}
+
+} // namespace
\ No newline at end of file
diff --git a/packages/ios/SimpleX Chat.xcodeproj/project.pbxproj b/packages/ios/SimpleX Chat.xcodeproj/project.pbxproj
index 5676eb78c..d5c52cdaa 100644
--- a/packages/ios/SimpleX Chat.xcodeproj/project.pbxproj
+++ b/packages/ios/SimpleX Chat.xcodeproj/project.pbxproj
@@ -14,8 +14,9 @@
5CBF96BA272D9CAA0021E76D /* SimpleX_ChatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBF96B9272D9CAA0021E76D /* SimpleX_ChatTests.swift */; };
5CBF96C4272D9CAA0021E76D /* SimpleX_ChatUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBF96C3272D9CAA0021E76D /* SimpleX_ChatUITests.swift */; };
5CBF96C6272D9CAA0021E76D /* SimpleX_ChatUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBF96C5272D9CAA0021E76D /* SimpleX_ChatUITestsLaunchTests.swift */; };
- 5CBF96D3272DA0520021E76D /* Messages.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBF96D2272DA0520021E76D /* Messages.swift */; };
- 5CBF96D9272DA0CD0021E76D /* protocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 5CBF96D8272DA0CD0021E76D /* protocol.c */; };
+ 843E324A272EB3B800348BAB /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843E3249272EB3B800348BAB /* MessageView.swift */; };
+ 843E324C272F04F100348BAB /* protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 843E324B272F04F100348BAB /* protocol.h */; };
+ 843E324E272F04FA00348BAB /* protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 843E324D272F04FA00348BAB /* protocol.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -46,9 +47,10 @@
5CBF96BF272D9CAA0021E76D /* SimpleX ChatUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SimpleX ChatUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
5CBF96C3272D9CAA0021E76D /* SimpleX_ChatUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleX_ChatUITests.swift; sourceTree = ""; };
5CBF96C5272D9CAA0021E76D /* SimpleX_ChatUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleX_ChatUITestsLaunchTests.swift; sourceTree = ""; };
- 5CBF96D2272DA0520021E76D /* Messages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Messages.swift; sourceTree = ""; };
- 5CBF96D7272DA0CD0021E76D /* protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = protocol.h; sourceTree = ""; };
- 5CBF96D8272DA0CD0021E76D /* protocol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = protocol.c; sourceTree = ""; };
+ 843E3243272EADA200348BAB /* SimpleX Chat-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SimpleX Chat-Bridging-Header.h"; sourceTree = ""; };
+ 843E3249272EB3B800348BAB /* MessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageView.swift; sourceTree = ""; };
+ 843E324B272F04F100348BAB /* protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = protocol.h; path = ../../../chat/include/protocol.h; sourceTree = ""; };
+ 843E324D272F04FA00348BAB /* protocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = protocol.cpp; path = ../../../chat/src/protocol.cpp; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -83,6 +85,7 @@
5CBF96B8272D9CAA0021E76D /* SimpleX ChatTests */,
5CBF96C2272D9CAA0021E76D /* SimpleX ChatUITests */,
5CBF96A6272D9CA60021E76D /* Products */,
+ 843E3205272EA78D00348BAB /* Frameworks */,
);
sourceTree = "";
};
@@ -101,10 +104,11 @@
children = (
5CBF96A8272D9CA60021E76D /* SimpleX_ChatApp.swift */,
5CBF96AA272D9CA60021E76D /* ContentView.swift */,
+ 843E3249272EB3B800348BAB /* MessageView.swift */,
5CBF96AC272D9CA90021E76D /* Assets.xcassets */,
5CBF96AE272D9CA90021E76D /* Preview Content */,
- 5CBF96D2272DA0520021E76D /* Messages.swift */,
- 5CBF96D4272DA0CD0021E76D /* chat */,
+ 843E3246272EAEA900348BAB /* ChatLib */,
+ 843E3243272EADA200348BAB /* SimpleX Chat-Bridging-Header.h */,
);
path = "SimpleX Chat";
sourceTree = "";
@@ -134,39 +138,41 @@
path = "SimpleX ChatUITests";
sourceTree = "";
};
- 5CBF96D4272DA0CD0021E76D /* chat */ = {
+ 843E3205272EA78D00348BAB /* Frameworks */ = {
isa = PBXGroup;
children = (
- 5CBF96D5272DA0CD0021E76D /* tests */,
- 5CBF96D6272DA0CD0021E76D /* src */,
);
- name = chat;
- path = ../../chat;
+ name = Frameworks;
sourceTree = "";
};
- 5CBF96D5272DA0CD0021E76D /* tests */ = {
+ 843E3246272EAEA900348BAB /* ChatLib */ = {
isa = PBXGroup;
children = (
+ 843E324B272F04F100348BAB /* protocol.h */,
+ 843E324D272F04FA00348BAB /* protocol.cpp */,
);
- path = tests;
- sourceTree = "";
- };
- 5CBF96D6272DA0CD0021E76D /* src */ = {
- isa = PBXGroup;
- children = (
- 5CBF96D7272DA0CD0021E76D /* protocol.h */,
- 5CBF96D8272DA0CD0021E76D /* protocol.c */,
- );
- path = src;
+ path = ChatLib;
sourceTree = "";
};
/* End PBXGroup section */
+/* Begin PBXHeadersBuildPhase section */
+ 843E31EA272DA43500348BAB /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 843E324C272F04F100348BAB /* protocol.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
/* Begin PBXNativeTarget section */
5CBF96A4272D9CA60021E76D /* SimpleX Chat */ = {
isa = PBXNativeTarget;
buildConfigurationList = 5CBF96C9272D9CAA0021E76D /* Build configuration list for PBXNativeTarget "SimpleX Chat" */;
buildPhases = (
+ 843E31EA272DA43500348BAB /* Headers */,
5CBF96A1272D9CA60021E76D /* Sources */,
5CBF96A2272D9CA60021E76D /* Frameworks */,
5CBF96A3272D9CA60021E76D /* Resources */,
@@ -223,11 +229,12 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
- LastSwiftUpdateCheck = 1310;
+ LastSwiftUpdateCheck = 1300;
LastUpgradeCheck = 1310;
TargetAttributes = {
5CBF96A4272D9CA60021E76D = {
CreatedOnToolsVersion = 13.1;
+ LastSwiftMigration = 1300;
};
5CBF96B4272D9CAA0021E76D = {
CreatedOnToolsVersion = 13.1;
@@ -290,10 +297,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 843E324A272EB3B800348BAB /* MessageView.swift in Sources */,
5CBF96AB272D9CA60021E76D /* ContentView.swift in Sources */,
- 5CBF96D9272DA0CD0021E76D /* protocol.c in Sources */,
- 5CBF96D3272DA0520021E76D /* Messages.swift in Sources */,
5CBF96A9272D9CA60021E76D /* SimpleX_ChatApp.swift in Sources */,
+ 843E324E272F04FA00348BAB /* protocol.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -451,6 +458,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"SimpleX Chat/Preview Content\"";
@@ -470,6 +478,8 @@
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.SimpleX-Chat";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_OBJC_BRIDGING_HEADER = "SimpleX Chat/SimpleX Chat-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -480,6 +490,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"SimpleX Chat/Preview Content\"";
@@ -499,6 +510,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.SimpleX-Chat";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_OBJC_BRIDGING_HEADER = "SimpleX Chat/SimpleX Chat-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
diff --git a/packages/ios/SimpleX Chat/ContentView.swift b/packages/ios/SimpleX Chat/ContentView.swift
index b46c92edd..d58705c55 100644
--- a/packages/ios/SimpleX Chat/ContentView.swift
+++ b/packages/ios/SimpleX Chat/ContentView.swift
@@ -8,9 +8,56 @@
import SwiftUI
struct ContentView: View {
+ @State var history: [String] = ["Start session:"]
+ @State var text: String = ""
+ @State var inProgress: Bool = false
+
+ func sendMessage() {
+ DispatchQueue.global().async {
+ let string: String = self.$text.wrappedValue
+ inProgress = true
+ text = ""
+ if let result = executeCommand(string),
+ let stringResult = String(utf8String: result) {
+ sleep(1) // emulate work
+ history += [stringResult]
+ }
+ inProgress = false
+ }
+ }
+
var body: some View {
- Text("Hello, world!")
- .padding()
+ VStack {
+ ScrollView {
+ LazyVStack {
+ ForEach(history, id: \.self) { msg in
+ MessageView(message: msg, isCurrentUser: false)
+ }
+ }
+ .padding(10)
+ }
+ .frame(minWidth: 0,
+ maxWidth: .infinity,
+ minHeight: 0,
+ maxHeight: .infinity,
+ alignment: .topLeading)
+ HStack {
+ TextField("Message...", text: $text)
+ .textFieldStyle(RoundedBorderTextFieldStyle())
+ .frame(minHeight: CGFloat(30))
+ if (inProgress) {
+ ProgressView()
+ .frame(width: 40,
+ height: 20,
+ alignment: .center)
+ }
+ else {
+ Button(action: sendMessage) {
+ Text("Send")
+ }.disabled(text.isEmpty)
+ }
+ }.frame(minHeight: CGFloat(30)).padding()
+ }
}
}
@@ -19,3 +66,4 @@ struct ContentView_Previews: PreviewProvider {
ContentView()
}
}
+
diff --git a/packages/ios/SimpleX Chat/MessageView.swift b/packages/ios/SimpleX Chat/MessageView.swift
new file mode 100644
index 000000000..1fb38c0bb
--- /dev/null
+++ b/packages/ios/SimpleX Chat/MessageView.swift
@@ -0,0 +1,32 @@
+//
+// ContentView.swift
+// SimpleX Chat
+//
+// Created by Evgeny on 30/10/2021.
+//
+
+import SwiftUI
+
+struct MessageView: View {
+ var message: String
+ var isCurrentUser: Bool
+
+ var body: some View {
+ Text(message)
+ .padding(10)
+ .foregroundColor(isCurrentUser ? Color.white : Color.black)
+ .background(isCurrentUser ? Color.blue : Color(UIColor(red: 240/255, green: 240/255, blue: 240/255, alpha: 1.0)))
+ .cornerRadius(10)
+ .frame(minWidth: 100,
+ maxWidth: .infinity,
+ minHeight: 0,
+ maxHeight: .infinity,
+ alignment: .leading)
+ }
+}
+
+struct MessageView_Previews: PreviewProvider {
+ static var previews: some View {
+ MessageView(message: "> Send message: \"Hello world!\"\nSuccessful", isCurrentUser: false)
+ }
+}
diff --git a/packages/ios/SimpleX Chat/SimpleX Chat-Bridging-Header.h b/packages/ios/SimpleX Chat/SimpleX Chat-Bridging-Header.h
new file mode 100644
index 000000000..e79d01431
--- /dev/null
+++ b/packages/ios/SimpleX Chat/SimpleX Chat-Bridging-Header.h
@@ -0,0 +1,5 @@
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
+#import "protocol.h"