Compare commits

..

6 Commits

Author SHA1 Message Date
Avently 4c4794fe33 lib path 2024-12-13 10:31:34 -08:00
Avently f179db9545 package 2024-12-13 10:19:43 -08:00
Avently 52160f2602 change lib name 2024-12-13 10:14:37 -08:00
Avently 2a99a5235b changes 2024-12-13 19:57:06 +07:00
Avently 4fe7b674e6 rename 2024-12-13 16:50:22 +07:00
Avently a5e7fa2f9f nodejs: addon 2024-12-12 22:11:42 +07:00
27 changed files with 423 additions and 201 deletions
+3
View File
@@ -79,3 +79,6 @@ website/package-lock.json
website/.cache website/.cache
website/test/stubs-layout-cache/_includes/*.js website/test/stubs-layout-cache/_includes/*.js
apps/android/app/release apps/android/app/release
packages/simplex-chat-nodejs/build
packages/simplex-chat-nodejs/.vscode
packages/simplex-chat-nodejs/libs
+21 -39
View File
@@ -440,7 +440,6 @@ struct ChatView: View {
maxWidth: maxWidth, maxWidth: maxWidth,
composeState: $composeState, composeState: $composeState,
selectedMember: $selectedMember, selectedMember: $selectedMember,
showChatInfoSheet: $showChatInfoSheet,
revealedChatItem: $revealedChatItem, revealedChatItem: $revealedChatItem,
selectedChatItems: $selectedChatItems, selectedChatItems: $selectedChatItems,
forwardedChatItems: $forwardedChatItems forwardedChatItems: $forwardedChatItems
@@ -894,14 +893,12 @@ struct ChatView: View {
private struct ChatItemWithMenu: View { private struct ChatItemWithMenu: View {
@EnvironmentObject var m: ChatModel @EnvironmentObject var m: ChatModel
@EnvironmentObject var theme: AppTheme @EnvironmentObject var theme: AppTheme
@AppStorage(DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) private var profileRadius = defaultProfileImageCorner
@Binding @ObservedObject var chat: Chat @Binding @ObservedObject var chat: Chat
@ObservedObject var dummyModel: ChatItemDummyModel = .shared @ObservedObject var dummyModel: ChatItemDummyModel = .shared
let chatItem: ChatItem let chatItem: ChatItem
let maxWidth: CGFloat let maxWidth: CGFloat
@Binding var composeState: ComposeState @Binding var composeState: ComposeState
@Binding var selectedMember: GMember? @Binding var selectedMember: GMember?
@Binding var showChatInfoSheet: Bool
@Binding var revealedChatItem: ChatItem? @Binding var revealedChatItem: ChatItem?
@State private var deletingItem: ChatItem? = nil @State private var deletingItem: ChatItem? = nil
@@ -1258,22 +1255,16 @@ struct ChatView: View {
setReaction(ci, add: !r.userReacted, reaction: r.reaction) setReaction(ci, add: !r.userReacted, reaction: r.reaction)
} }
} }
switch chat.chatInfo { if case let .group(groupInfo) = chat.chatInfo {
case let .group(groupInfo):
v.contextMenu { v.contextMenu {
ReactionContextMenu( ReactionContextMenu(
groupInfo: groupInfo, groupInfo: groupInfo,
itemId: ci.id, itemId: ci.id,
reactionCount: r, reactionCount: r,
selectedMember: $selectedMember, selectedMember: $selectedMember
profileRadius: profileRadius
) )
} }
case let .direct(contact): } else {
v.contextMenu {
contactReactionMenu(contact, r)
}
default:
v v
} }
} }
@@ -1776,20 +1767,6 @@ struct ChatView: View {
} }
} }
} }
@ViewBuilder private func contactReactionMenu(_ contact: Contact, _ r: CIReactionCount) -> some View {
if !r.userReacted || r.totalReacted > 1 {
Button { showChatInfoSheet = true } label: {
profileMenuItem(Text(contact.displayName), contact.image, radius: profileRadius)
}
}
if r.userReacted {
Button {} label: {
profileMenuItem(Text("you"), m.currentUser?.profile.image, radius: profileRadius)
}
.disabled(true)
}
}
private struct SelectedChatItem: View { private struct SelectedChatItem: View {
@EnvironmentObject var theme: AppTheme @EnvironmentObject var theme: AppTheme
@@ -1882,12 +1859,13 @@ struct ReactionContextMenu: View {
var itemId: Int64 var itemId: Int64
var reactionCount: CIReactionCount var reactionCount: CIReactionCount
@Binding var selectedMember: GMember? @Binding var selectedMember: GMember?
var profileRadius: CGFloat
@State private var memberReactions: [MemberReaction] = [] @State private var memberReactions: [MemberReaction] = []
@AppStorage(DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) private var radius = defaultProfileImageCorner
var body: some View { var body: some View {
groupMemberReactionList() groupMemberReactionList()
.task { .task {
logger.debug("ReactionContextMenu task \(radius)")
await loadChatItemReaction() await loadChatItemReaction()
} }
} }
@@ -1911,12 +1889,27 @@ struct ReactionContextMenu: View {
selectedMember = member selectedMember = member
} }
} label: { } label: {
profileMenuItem(Text(mem.displayName), mem.image, radius: profileRadius) HStack {
Text(mem.displayName)
if let img = cropImage(mem.image) {
Image(uiImage: img)
} else {
Image(systemName: "person.crop.circle")
}
}
} }
.disabled(userMember) .disabled(userMember)
} }
} }
} }
private func cropImage(_ img: String?) -> UIImage? {
return if let originalImage = imageFromBase64(img) {
maskToCustomShape(originalImage, size: 30, radius: radius)
} else {
nil
}
}
private func loadChatItemReaction() async { private func loadChatItemReaction() async {
do { do {
@@ -1934,17 +1927,6 @@ struct ReactionContextMenu: View {
} }
} }
func profileMenuItem(_ nameText: Text, _ image: String?, radius: CGFloat) -> some View {
HStack {
nameText
if let image, let img = imageFromBase64(image) {
Image(uiImage: maskToCustomShape(img, size: 30, radius: radius))
} else {
Image(systemName: "person.crop.circle")
}
}
}
func maskToCustomShape(_ image: UIImage, size: CGFloat, radius: CGFloat) -> UIImage { func maskToCustomShape(_ image: UIImage, size: CGFloat, radius: CGFloat) -> UIImage {
let path = Path { path in let path = Path { path in
if radius >= 50 { if radius >= 50 {
+20 -20
View File
@@ -1931,7 +1931,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 255; CURRENT_PROJECT_VERSION = 254;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@@ -1956,7 +1956,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
LLVM_LTO = YES_THIN; LLVM_LTO = YES_THIN;
MARKETING_VERSION = 6.2.1; MARKETING_VERSION = 6.2;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX; PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@@ -1980,7 +1980,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 255; CURRENT_PROJECT_VERSION = 254;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@@ -2005,7 +2005,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
LLVM_LTO = YES; LLVM_LTO = YES;
MARKETING_VERSION = 6.2.1; MARKETING_VERSION = 6.2;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX; PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@@ -2021,11 +2021,11 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 255; CURRENT_PROJECT_VERSION = 254;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 6.2.1; MARKETING_VERSION = 6.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@@ -2041,11 +2041,11 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 255; CURRENT_PROJECT_VERSION = 254;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 6.2.1; MARKETING_VERSION = 6.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@@ -2066,7 +2066,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 255; CURRENT_PROJECT_VERSION = 254;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = s; GCC_OPTIMIZATION_LEVEL = s;
@@ -2081,7 +2081,7 @@
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
LLVM_LTO = YES; LLVM_LTO = YES;
MARKETING_VERSION = 6.2.1; MARKETING_VERSION = 6.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2103,7 +2103,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 255; CURRENT_PROJECT_VERSION = 254;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
ENABLE_CODE_COVERAGE = NO; ENABLE_CODE_COVERAGE = NO;
@@ -2118,7 +2118,7 @@
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
LLVM_LTO = YES; LLVM_LTO = YES;
MARKETING_VERSION = 6.2.1; MARKETING_VERSION = 6.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2140,7 +2140,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 255; CURRENT_PROJECT_VERSION = 254;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2166,7 +2166,7 @@
"$(PROJECT_DIR)/Libraries/sim", "$(PROJECT_DIR)/Libraries/sim",
); );
LLVM_LTO = YES; LLVM_LTO = YES;
MARKETING_VERSION = 6.2.1; MARKETING_VERSION = 6.2;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@@ -2191,7 +2191,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 255; CURRENT_PROJECT_VERSION = 254;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2217,7 +2217,7 @@
"$(PROJECT_DIR)/Libraries/sim", "$(PROJECT_DIR)/Libraries/sim",
); );
LLVM_LTO = YES; LLVM_LTO = YES;
MARKETING_VERSION = 6.2.1; MARKETING_VERSION = 6.2;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@@ -2242,7 +2242,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 255; CURRENT_PROJECT_VERSION = 254;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17; GCC_C_LANGUAGE_STANDARD = gnu17;
@@ -2257,7 +2257,7 @@
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
LOCALIZATION_PREFERS_STRING_CATALOGS = YES; LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.2.1; MARKETING_VERSION = 6.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@@ -2276,7 +2276,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 255; CURRENT_PROJECT_VERSION = 254;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17; GCC_C_LANGUAGE_STANDARD = gnu17;
@@ -2291,7 +2291,7 @@
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
LOCALIZATION_PREFERS_STRING_CATALOGS = YES; LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.2.1; MARKETING_VERSION = 6.2;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@@ -1,11 +1,10 @@
package chat.simplex.common.platform package chat.simplex.common.platform
import android.util.Log import android.util.Log
import chat.simplex.common.model.ChatController.appPrefs
actual object Log { actual object Log {
actual fun d(tag: String, text: String) { if (appPrefs.logLevel.get() <= LogLevel.DEBUG && appPrefs.developerTools.get()) Log.d(tag, text) } actual fun d(tag: String, text: String) = Log.d(tag, text).run{}
actual fun e(tag: String, text: String) { if (appPrefs.logLevel.get() <= LogLevel.ERROR || !appPrefs.developerTools.get()) Log.e(tag, text) } actual fun e(tag: String, text: String) = Log.e(tag, text).run{}
actual fun i(tag: String, text: String) { if (appPrefs.logLevel.get() <= LogLevel.INFO && appPrefs.developerTools.get()) Log.i(tag, text) } actual fun i(tag: String, text: String) = Log.i(tag, text).run{}
actual fun w(tag: String, text: String) { if (appPrefs.logLevel.get() <= LogLevel.WARNING || !appPrefs.developerTools.get()) Log.w(tag, text) } actual fun w(tag: String, text: String) = Log.w(tag, text).run{}
} }
@@ -54,11 +54,10 @@ add_library( # Sets the name of the library.
simplex-api.c) simplex-api.c)
add_library( simplex SHARED IMPORTED ) add_library( simplex SHARED IMPORTED )
FILE(GLOB SIMPLEXLIB ${CMAKE_SOURCE_DIR}/libs/${OS_LIB_PATH}-${OS_LIB_ARCH}/libsimplex.${OS_LIB_EXT})
if(WIN32) if(WIN32)
FILE(GLOB SIMPLEXLIB ${CMAKE_SOURCE_DIR}/libs/${OS_LIB_PATH}-${OS_LIB_ARCH}/lib*simplex*.${OS_LIB_EXT})
set_target_properties( simplex PROPERTIES IMPORTED_IMPLIB ${SIMPLEXLIB}) set_target_properties( simplex PROPERTIES IMPORTED_IMPLIB ${SIMPLEXLIB})
else() else()
FILE(GLOB SIMPLEXLIB ${CMAKE_SOURCE_DIR}/libs/${OS_LIB_PATH}-${OS_LIB_ARCH}/lib*simplex-chat*.${OS_LIB_EXT})
set_target_properties( simplex PROPERTIES IMPORTED_LOCATION ${SIMPLEXLIB}) set_target_properties( simplex PROPERTIES IMPORTED_LOCATION ${SIMPLEXLIB})
endif() endif()
@@ -132,7 +132,6 @@ class AppPreferences {
val chatLastStart = mkDatePreference(SHARED_PREFS_CHAT_LAST_START, null) val chatLastStart = mkDatePreference(SHARED_PREFS_CHAT_LAST_START, null)
val chatStopped = mkBoolPreference(SHARED_PREFS_CHAT_STOPPED, false) val chatStopped = mkBoolPreference(SHARED_PREFS_CHAT_STOPPED, false)
val developerTools = mkBoolPreference(SHARED_PREFS_DEVELOPER_TOOLS, false) val developerTools = mkBoolPreference(SHARED_PREFS_DEVELOPER_TOOLS, false)
val logLevel = mkEnumPreference(SHARED_PREFS_LOG_LEVEL, LogLevel.WARNING) { LogLevel.entries.firstOrNull { it.name == this } }
val showInternalErrors = mkBoolPreference(SHARED_PREFS_SHOW_INTERNAL_ERRORS, false) val showInternalErrors = mkBoolPreference(SHARED_PREFS_SHOW_INTERNAL_ERRORS, false)
val showSlowApiCalls = mkBoolPreference(SHARED_PREFS_SHOW_SLOW_API_CALLS, false) val showSlowApiCalls = mkBoolPreference(SHARED_PREFS_SHOW_SLOW_API_CALLS, false)
val terminalAlwaysVisible = mkBoolPreference(SHARED_PREFS_TERMINAL_ALWAYS_VISIBLE, false) val terminalAlwaysVisible = mkBoolPreference(SHARED_PREFS_TERMINAL_ALWAYS_VISIBLE, false)
@@ -394,7 +393,6 @@ class AppPreferences {
private const val SHARED_PREFS_CHAT_LAST_START = "ChatLastStart" private const val SHARED_PREFS_CHAT_LAST_START = "ChatLastStart"
private const val SHARED_PREFS_CHAT_STOPPED = "ChatStopped" private const val SHARED_PREFS_CHAT_STOPPED = "ChatStopped"
private const val SHARED_PREFS_DEVELOPER_TOOLS = "DeveloperTools" private const val SHARED_PREFS_DEVELOPER_TOOLS = "DeveloperTools"
private const val SHARED_PREFS_LOG_LEVEL = "LogLevel"
private const val SHARED_PREFS_SHOW_INTERNAL_ERRORS = "ShowInternalErrors" private const val SHARED_PREFS_SHOW_INTERNAL_ERRORS = "ShowInternalErrors"
private const val SHARED_PREFS_SHOW_SLOW_API_CALLS = "ShowSlowApiCalls" private const val SHARED_PREFS_SHOW_SLOW_API_CALLS = "ShowSlowApiCalls"
private const val SHARED_PREFS_TERMINAL_ALWAYS_VISIBLE = "TerminalAlwaysVisible" private const val SHARED_PREFS_TERMINAL_ALWAYS_VISIBLE = "TerminalAlwaysVisible"
@@ -2,10 +2,6 @@ package chat.simplex.common.platform
const val TAG = "SIMPLEX" const val TAG = "SIMPLEX"
enum class LogLevel {
DEBUG, INFO, WARNING, ERROR
}
expect object Log { expect object Log {
fun d(tag: String, text: String) fun d(tag: String, text: String)
fun e(tag: String, text: String) fun e(tag: String, text: String)
@@ -296,7 +296,6 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools
} }
} }
SectionBottomSpacer() SectionBottomSpacer()
SectionBottomSpacer()
} }
} }
@@ -310,7 +309,6 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools
QuotedMsgView(qi) QuotedMsgView(qi)
} }
SectionBottomSpacer() SectionBottomSpacer()
SectionBottomSpacer()
} }
} }
@@ -326,7 +324,6 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools
ForwardedFromView(forwardedFromItem) ForwardedFromView(forwardedFromItem)
} }
SectionBottomSpacer() SectionBottomSpacer()
SectionBottomSpacer()
} }
} }
@@ -398,7 +395,6 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools
} }
} }
SectionBottomSpacer() SectionBottomSpacer()
SectionBottomSpacer()
} }
} }
@@ -437,11 +433,12 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools
Column { Column {
if (numTabs() > 1) { if (numTabs() > 1) {
Box( Column(
Modifier Modifier
.fillMaxHeight() .fillMaxHeight(),
verticalArrangement = Arrangement.SpaceBetween
) { ) {
Column { Column(Modifier.weight(1f)) {
when (val sel = selection.value) { when (val sel = selection.value) {
is CIInfoTab.Delivery -> { is CIInfoTab.Delivery -> {
DeliveryTab(sel.memberDeliveryStatuses) DeliveryTab(sel.memberDeliveryStatuses)
@@ -482,7 +479,7 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools
} }
} }
val oneHandUI = remember { appPrefs.oneHandUI.state } val oneHandUI = remember { appPrefs.oneHandUI.state }
Box(Modifier.align(Alignment.BottomCenter).navigationBarsPadding().offset(x = 0.dp, y = if (oneHandUI.value) -AppBarHeight * fontSizeSqrtMultiplier else 0.dp)) { Box(Modifier.offset(x = 0.dp, y = if (oneHandUI.value) -AppBarHeight * fontSizeSqrtMultiplier else 0.dp)) {
TabRow( TabRow(
selectedTabIndex = availableTabs.indexOfFirst { it::class == selection.value::class }, selectedTabIndex = availableTabs.indexOfFirst { it::class == selection.value::class },
Modifier.height(AppBarHeight * fontSizeSqrtMultiplier), Modifier.height(AppBarHeight * fontSizeSqrtMultiplier),
@@ -665,18 +665,13 @@ fun ChatLayout(
AdaptingBottomPaddingLayout(Modifier, CHAT_COMPOSE_LAYOUT_ID, composeViewHeight) { AdaptingBottomPaddingLayout(Modifier, CHAT_COMPOSE_LAYOUT_ID, composeViewHeight) {
if (chatInfo != null) { if (chatInfo != null) {
Box(Modifier.fillMaxSize()) { Box(Modifier.fillMaxSize()) {
// disables scrolling to top of chat item on click inside the bubble ChatItemsList(
CompositionLocalProvider(LocalBringIntoViewSpec provides object : BringIntoViewSpec { remoteHostId, chatInfo, unreadCount, composeState, composeViewHeight, searchValue,
override fun calculateScrollDistance(offset: Float, size: Float, containerSize: Float): Float = 0f useLinkPreviews, linkMode, selectedChatItems, showMemberInfo, loadMessages, deleteMessage, deleteMessages,
}) { receiveFile, cancelFile, joinGroup, acceptCall, acceptFeature, openDirectChat, forwardItem,
ChatItemsList( updateContactStats, updateMemberStats, syncContactConnection, syncMemberConnection, findModelChat, findModelMember,
remoteHostId, chatInfo, unreadCount, composeState, composeViewHeight, searchValue, setReaction, showItemDetails, markItemsRead, markChatRead, remember { { onComposed(it) } }, developerTools, showViaProxy,
useLinkPreviews, linkMode, selectedChatItems, showMemberInfo, showChatInfo = info, loadMessages, deleteMessage, deleteMessages, )
receiveFile, cancelFile, joinGroup, acceptCall, acceptFeature, openDirectChat, forwardItem,
updateContactStats, updateMemberStats, syncContactConnection, syncMemberConnection, findModelChat, findModelMember,
setReaction, showItemDetails, markItemsRead, markChatRead, remember { { onComposed(it) } }, developerTools, showViaProxy,
)
}
} }
} }
Box( Box(
@@ -944,7 +939,6 @@ fun BoxScope.ChatItemsList(
linkMode: SimplexLinkMode, linkMode: SimplexLinkMode,
selectedChatItems: MutableState<Set<Long>?>, selectedChatItems: MutableState<Set<Long>?>,
showMemberInfo: (GroupInfo, GroupMember) -> Unit, showMemberInfo: (GroupInfo, GroupMember) -> Unit,
showChatInfo: () -> Unit,
loadMessages: suspend (ChatId, ChatPagination, ActiveChatState, visibleItemIndexesNonReversed: () -> IntRange) -> Unit, loadMessages: suspend (ChatId, ChatPagination, ActiveChatState, visibleItemIndexesNonReversed: () -> IntRange) -> Unit,
deleteMessage: (Long, CIDeleteMode) -> Unit, deleteMessage: (Long, CIDeleteMode) -> Unit,
deleteMessages: (List<Long>) -> Unit, deleteMessages: (List<Long>) -> Unit,
@@ -1072,7 +1066,7 @@ fun BoxScope.ChatItemsList(
highlightedItems.value = setOf() highlightedItems.value = setOf()
} }
} }
ChatItemView(remoteHostId, chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, revealed = revealed, highlighted = highlighted, range = range, fillMaxWidth = fillMaxWidth, selectedChatItems = selectedChatItems, selectChatItem = { selectUnselectChatItem(true, cItem, revealed, selectedChatItems) }, deleteMessage = deleteMessage, deleteMessages = deleteMessages, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = joinGroup, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, forwardItem = forwardItem, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, scrollToQuotedItemFromItem = scrollToQuotedItemFromItem, setReaction = setReaction, showItemDetails = showItemDetails, reveal = reveal, showMemberInfo = showMemberInfo, showChatInfo = showChatInfo, developerTools = developerTools, showViaProxy = showViaProxy, itemSeparation = itemSeparation, showTimestamp = itemSeparation.timestamp) ChatItemView(remoteHostId, chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, revealed = revealed, highlighted = highlighted, range = range, fillMaxWidth = fillMaxWidth, selectedChatItems = selectedChatItems, selectChatItem = { selectUnselectChatItem(true, cItem, revealed, selectedChatItems) }, deleteMessage = deleteMessage, deleteMessages = deleteMessages, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = joinGroup, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, forwardItem = forwardItem, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, scrollToQuotedItemFromItem = scrollToQuotedItemFromItem, setReaction = setReaction, showItemDetails = showItemDetails, reveal = reveal, showMemberInfo = showMemberInfo, developerTools = developerTools, showViaProxy = showViaProxy, itemSeparation = itemSeparation, showTimestamp = itemSeparation.timestamp)
} }
} }
@@ -24,12 +24,12 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.* import androidx.compose.ui.unit.*
import chat.simplex.common.model.* import chat.simplex.common.model.*
import chat.simplex.common.model.ChatModel.controller import chat.simplex.common.model.ChatModel.controller
import chat.simplex.common.model.ChatModel.currentUser
import chat.simplex.common.platform.* import chat.simplex.common.platform.*
import chat.simplex.common.ui.theme.* import chat.simplex.common.ui.theme.*
import chat.simplex.common.views.chat.* import chat.simplex.common.views.chat.*
import chat.simplex.common.views.helpers.* import chat.simplex.common.views.helpers.*
import chat.simplex.res.MR import chat.simplex.res.MR
import kotlinx.coroutines.launch
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
import kotlin.math.* import kotlin.math.*
@@ -51,12 +51,6 @@ fun chatEventText(eventText: String, ts: String): AnnotatedString =
withStyle(chatEventStyle) { append("$eventText $ts") } withStyle(chatEventStyle) { append("$eventText $ts") }
} }
data class ChatItemReactionMenuItem (
val name: String,
val image: String?,
val onClick: (() -> Unit)?
)
@Composable @Composable
fun ChatItemView( fun ChatItemView(
rhId: Long?, rhId: Long?,
@@ -93,7 +87,6 @@ fun ChatItemView(
showItemDetails: (ChatInfo, ChatItem) -> Unit, showItemDetails: (ChatInfo, ChatItem) -> Unit,
reveal: (Boolean) -> Unit, reveal: (Boolean) -> Unit,
showMemberInfo: (GroupInfo, GroupMember) -> Unit, showMemberInfo: (GroupInfo, GroupMember) -> Unit,
showChatInfo: () -> Unit,
developerTools: Boolean, developerTools: Boolean,
showViaProxy: Boolean, showViaProxy: Boolean,
showTimestamp: Boolean, showTimestamp: Boolean,
@@ -127,7 +120,7 @@ fun ChatItemView(
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.chatItemOffset(cItem, itemSeparation.largeGap, inverted = true, revealed = true)) { Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.chatItemOffset(cItem, itemSeparation.largeGap, inverted = true, revealed = true)) {
cItem.reactions.forEach { r -> cItem.reactions.forEach { r ->
val showReactionMenu = remember { mutableStateOf(false) } val showReactionMenu = remember { mutableStateOf(false) }
val reactionMenuItems = remember { mutableStateOf(emptyList<ChatItemReactionMenuItem>()) } val reactionMembers = remember { mutableStateOf(emptyList<MemberReaction>()) }
val interactionSource = remember { MutableInteractionSource() } val interactionSource = remember { MutableInteractionSource() }
val enterInteraction = remember { HoverInteraction.Enter() } val enterInteraction = remember { HoverInteraction.Enter() }
KeyChangeEffect(highlighted.value) { KeyChangeEffect(highlighted.value) {
@@ -141,39 +134,18 @@ fun ChatItemView(
var modifier = Modifier.padding(horizontal = 5.dp, vertical = 2.dp).clip(RoundedCornerShape(8.dp)) var modifier = Modifier.padding(horizontal = 5.dp, vertical = 2.dp).clip(RoundedCornerShape(8.dp))
if (cInfo.featureEnabled(ChatFeature.Reactions)) { if (cInfo.featureEnabled(ChatFeature.Reactions)) {
fun showReactionsMenu() { fun showReactionsMenu() {
when (cInfo) { if (cInfo is ChatInfo.Group) {
is ChatInfo.Group -> { withBGApi {
withBGApi { try {
try { val members = controller.apiGetReactionMembers(rhId, cInfo.groupInfo.groupId, cItem.id, r.reaction)
val members = controller.apiGetReactionMembers(rhId, cInfo.groupInfo.groupId, cItem.id, r.reaction) if (members != null) {
if (members != null) { showReactionMenu.value = true
showReactionMenu.value = true reactionMembers.value = members
reactionMenuItems.value = members.map {
val enabled = cInfo.groupInfo.membership.groupMemberId != it.groupMember.groupMemberId
val click = if (enabled) ({ showMemberInfo(cInfo.groupInfo, it.groupMember) }) else null
ChatItemReactionMenuItem(it.groupMember.displayName, it.groupMember.image, click)
}
}
} catch (e: Exception) {
Log.d(TAG, "chatItemView ChatItemReactions onLongClick: unexpected exception: ${e.stackTraceToString()}")
} }
} catch (e: Exception) {
Log.d(TAG, "hatItemView ChatItemReactions onLongClick: unexpected exception: ${e.stackTraceToString()}")
} }
} }
is ChatInfo.Direct -> {
showReactionMenu.value = true
val reactions = mutableListOf<ChatItemReactionMenuItem>()
if (!r.userReacted || r.totalReacted > 1) {
val contact = cInfo.contact
reactions.add(ChatItemReactionMenuItem(contact.displayName, contact.image, showChatInfo))
}
if (r.userReacted) {
reactions.add(ChatItemReactionMenuItem(generalGetString(MR.strings.sender_you_pronoun), currentUser.value?.image, null))
}
reactionMenuItems.value = reactions
}
else -> {}
} }
} }
modifier = modifier modifier = modifier
@@ -194,19 +166,19 @@ fun ChatItemView(
Row(modifier.padding(2.dp), verticalAlignment = Alignment.CenterVertically) { Row(modifier.padding(2.dp), verticalAlignment = Alignment.CenterVertically) {
ReactionIcon(r.reaction.text, fontSize = 12.sp) ReactionIcon(r.reaction.text, fontSize = 12.sp)
DefaultDropdownMenu(showMenu = showReactionMenu) { DefaultDropdownMenu(showMenu = showReactionMenu) {
reactionMenuItems.value.forEach { m -> reactionMembers.value.forEach { m ->
ItemAction( ItemAction(
text = m.name, text = m.groupMember.displayName,
composable = { ProfileImage(44.dp, m.image) }, composable = { ProfileImage(44.dp, m.groupMember.image) },
onClick = { onClick = {
val click = m.onClick if (cInfo is ChatInfo.Group && cInfo.groupInfo.membership.groupMemberId != m.groupMember.groupMemberId) {
if (click != null) { showMemberInfo(cInfo.groupInfo, m.groupMember)
click() showReactionMenu.value = false
} else {
showReactionMenu.value = false showReactionMenu.value = false
} }
}, },
lineLimit = 1, lineLimit = 1
color = if (m.onClick == null) MaterialTheme.colors.secondary else MenuTextColor
) )
} }
} }
@@ -1216,7 +1188,6 @@ fun PreviewChatItemView(
showItemDetails = { _, _ -> }, showItemDetails = { _, _ -> },
reveal = {}, reveal = {},
showMemberInfo = { _, _ ->}, showMemberInfo = { _, _ ->},
showChatInfo = {},
developerTools = false, developerTools = false,
showViaProxy = false, showViaProxy = false,
showTimestamp = true, showTimestamp = true,
@@ -1262,7 +1233,6 @@ fun PreviewChatItemViewDeletedContent() {
showItemDetails = { _, _ -> }, showItemDetails = { _, _ -> },
reveal = {}, reveal = {},
showMemberInfo = { _, _ ->}, showMemberInfo = { _, _ ->},
showChatInfo = {},
developerTools = false, developerTools = false,
showViaProxy = false, showViaProxy = false,
preview = true, preview = true,
@@ -30,7 +30,6 @@ import kotlinx.datetime.*
import java.io.* import java.io.*
import java.net.URI import java.net.URI
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.StandardCopyOption
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
@@ -45,14 +44,11 @@ fun DatabaseView() {
val chatArchiveFile = remember { mutableStateOf<String?>(null) } val chatArchiveFile = remember { mutableStateOf<String?>(null) }
val stopped = remember { m.chatRunning }.value == false val stopped = remember { m.chatRunning }.value == false
val saveArchiveLauncher = rememberFileChooserLauncher(false) { to: URI? -> val saveArchiveLauncher = rememberFileChooserLauncher(false) { to: URI? ->
val archive = chatArchiveFile.value val file = chatArchiveFile.value
if (archive != null && to != null) { if (file != null && to != null) {
copyFileToFile(File(archive), to) {} copyFileToFile(File(file), to) {
} chatArchiveFile.value = null
// 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 appFilesCountAndSize = remember { mutableStateOf(directoryFileCountAndSize(appFilesDir.absolutePath)) }
@@ -684,8 +680,6 @@ suspend fun importArchive(
} finally { } finally {
File(archivePath).delete() File(archivePath).delete()
} }
} else {
progressIndicator.value = false
} }
return false return false
} }
@@ -697,15 +691,14 @@ private fun saveArchiveFromURI(importedArchiveURI: URI): String? {
if (inputStream != null && archiveName != null) { if (inputStream != null && archiveName != null) {
val archivePath = "$databaseExportDir${File.separator}$archiveName" val archivePath = "$databaseExportDir${File.separator}$archiveName"
val destFile = File(archivePath) val destFile = File(archivePath)
Files.copy(inputStream, destFile.toPath(), StandardCopyOption.REPLACE_EXISTING) Files.copy(inputStream, destFile.toPath())
archivePath archivePath
} else { } else {
Log.e(TAG, "saveArchiveFromURI null inputStream") Log.e(TAG, "saveArchiveFromURI null inputStream")
null null
} }
} catch (e: Exception) { } catch (e: Exception) {
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_saving_database), e.stackTraceToString()) Log.e(TAG, "saveArchiveFromURI error: ${e.message}")
Log.e(TAG, "saveArchiveFromURI error: ${e.stackTraceToString()}")
null null
} }
} }
@@ -14,7 +14,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import chat.simplex.common.model.* import chat.simplex.common.model.*
import chat.simplex.common.model.ChatController.appPrefs
import chat.simplex.common.platform.* import chat.simplex.common.platform.*
import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource import dev.icerock.moko.resources.compose.stringResource
@@ -45,12 +44,6 @@ fun DeveloperView(withAuth: (title: String, desc: String, block: () -> Unit) ->
if (devTools.value) { if (devTools.value) {
SectionDividerSpaced(maxTopPadding = true) SectionDividerSpaced(maxTopPadding = true)
SectionView(stringResource(MR.strings.developer_options_section).uppercase()) { SectionView(stringResource(MR.strings.developer_options_section).uppercase()) {
SettingsActionItemWithContent(painterResource(MR.images.ic_breaking_news), stringResource(MR.strings.debug_logs)) {
DefaultSwitch(
checked = remember { appPrefs.logLevel.state }.value <= LogLevel.DEBUG,
onCheckedChange = { appPrefs.logLevel.set(if (it) LogLevel.DEBUG else LogLevel.WARNING) }
)
}
SettingsPreferenceItem(painterResource(MR.images.ic_drive_folder_upload), stringResource(MR.strings.confirm_database_upgrades), m.controller.appPrefs.confirmDBUpgrades) SettingsPreferenceItem(painterResource(MR.images.ic_drive_folder_upload), stringResource(MR.strings.confirm_database_upgrades), m.controller.appPrefs.confirmDBUpgrades)
if (appPlatform.isDesktop) { if (appPlatform.isDesktop) {
TerminalAlwaysVisibleItem(m.controller.appPrefs.terminalAlwaysVisible) { checked -> TerminalAlwaysVisibleItem(m.controller.appPrefs.terminalAlwaysVisible) { checked ->
@@ -907,7 +907,6 @@
<string name="show_dev_options">Show:</string> <string name="show_dev_options">Show:</string>
<string name="hide_dev_options">Hide:</string> <string name="hide_dev_options">Hide:</string>
<string name="show_developer_options">Show developer options</string> <string name="show_developer_options">Show developer options</string>
<string name="debug_logs">Enable logs</string>
<string name="developer_options">Database IDs and Transport isolation option.</string> <string name="developer_options">Database IDs and Transport isolation option.</string>
<string name="developer_options_section">Developer options</string> <string name="developer_options_section">Developer options</string>
<string name="show_internal_errors">Show internal errors</string> <string name="show_internal_errors">Show internal errors</string>
@@ -1339,7 +1338,6 @@
<string name="chat_database_exported_migrate">You may migrate the exported database.</string> <string name="chat_database_exported_migrate">You may migrate the exported database.</string>
<string name="chat_database_exported_not_all_files">Some file(s) were not exported</string> <string name="chat_database_exported_not_all_files">Some file(s) were not exported</string>
<string name="chat_database_exported_continue">Continue</string> <string name="chat_database_exported_continue">Continue</string>
<string name="error_saving_database">Error saving database</string>
<!-- DatabaseEncryptionView.kt --> <!-- DatabaseEncryptionView.kt -->
<string name="save_passphrase_in_keychain">Save passphrase in Keystore</string> <string name="save_passphrase_in_keychain">Save passphrase in Keystore</string>
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="22px" viewBox="0 -960 960 960" width="22px" fill="#5f6368"><path d="M262.5-285q11.5 0 20.25-8.5t8.75-20q0-11.5-8.75-20.25t-20.25-8.75q-11.5 0-20 8.75T234-313.5q0 11.5 8.5 20t20 8.5Zm-29-168.5H291v-227h-57.5v227Zm217.5 174h275.5V-337H451v57.5Zm0-174h275.5V-511H451v57.5Zm0-169.5h275.5v-57.5H451v57.5ZM134.5-124.5q-22.97 0-40.23-17.27Q77-159.03 77-182v-596q0-22.97 17.27-40.23 17.26-17.27 40.23-17.27h691q22.97 0 40.23 17.27Q883-800.97 883-778v596q0 22.97-17.27 40.23-17.26 17.27-40.23 17.27h-691Zm0-57.5h691v-596h-691v596Zm0 0v-596 596Z"/></svg>

Before

Width:  |  Height:  |  Size: 592 B

@@ -67,7 +67,7 @@ object NtfManager {
ntf.second.close() ntf.second.close()
} catch (e: Exception) { } catch (e: Exception) {
// Can be java.lang.UnsupportedOperationException, for example. May do nothing // Can be java.lang.UnsupportedOperationException, for example. May do nothing
Log.e(TAG, "Failed to close notification: ${e.stackTraceToString()}") println("Failed to close notification: ${e.stackTraceToString()}")
}*/ }*/
} }
} }
@@ -85,8 +85,7 @@ object NtfManager {
} }
fun cancelAllNotifications() { fun cancelAllNotifications() {
// prevNtfs.forEach { try { it.second.close() } catch (e: Exception) { Log.e(TAG, "Failed to close notification: ${e // prevNtfs.forEach { try { it.second.close() } catch (e: Exception) { println("Failed to close notification: ${e.stackTraceToString()}") } }
// .stackTraceToString()}") } }
withBGApi { withBGApi {
prevNtfsMutex.withLock { prevNtfsMutex.withLock {
prevNtfs.clear() prevNtfs.clear()
@@ -154,7 +153,7 @@ object NtfManager {
ImageIO.write(icon.toAwtImage(), "PNG", newFile.outputStream()) ImageIO.write(icon.toAwtImage(), "PNG", newFile.outputStream())
newFile.absolutePath newFile.absolutePath
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Failed to write an icon to tmpDir: ${e.stackTraceToString()}") println("Failed to write an icon to tmpDir: ${e.stackTraceToString()}")
null null
} }
} else null } else null
@@ -1,10 +1,8 @@
package chat.simplex.common.platform package chat.simplex.common.platform
import chat.simplex.common.model.ChatController.appPrefs
actual object Log { actual object Log {
actual fun d(tag: String, text: String) { if (appPrefs.logLevel.get() <= LogLevel.DEBUG && appPrefs.developerTools.get()) println("D: $text") } actual fun d(tag: String, text: String) = println("D: $text")
actual fun e(tag: String, text: String) { if (appPrefs.logLevel.get() <= LogLevel.ERROR || !appPrefs.developerTools.get()) println("E: $text") } actual fun e(tag: String, text: String) = println("E: $text")
actual fun i(tag: String, text: String) { if (appPrefs.logLevel.get() <= LogLevel.INFO && appPrefs.developerTools.get()) println("I: $text") } actual fun i(tag: String, text: String) = println("I: $text")
actual fun w(tag: String, text: String) { if (appPrefs.logLevel.get() <= LogLevel.WARNING || !appPrefs.developerTools.get()) println("W: $text") } actual fun w(tag: String, text: String) = println("W: $text")
} }
+4 -4
View File
@@ -24,11 +24,11 @@ android.nonTransitiveRClass=true
kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.jvm.target=11 kotlin.jvm.target=11
android.version_name=6.2.1 android.version_name=6.2
android.version_code=261 android.version_code=259
desktop.version_name=6.2.1 desktop.version_name=6.2
desktop.version_code=83 desktop.version_code=82
kotlin.version=1.9.23 kotlin.version=1.9.23
gradle.plugin.version=8.2.0 gradle.plugin.version=8.2.0
+1 -1
View File
@@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package source-repository-package
type: git type: git
location: https://github.com/simplex-chat/simplexmq.git location: https://github.com/simplex-chat/simplexmq.git
tag: 8647c24a9555d4232b1cb21fed3a7c2518aa7b13 tag: 79e9447b73cc315ce35042b0a5f210c07ea39b07
source-repository-package source-repository-package
type: git type: git
+14
View File
@@ -0,0 +1,14 @@
{
"targets": [
{
"target_name": "addon",
"sources": [ "cpp/simplex.cc" ],
"libraries": [
"-Wl,-rpath,libs",
"-L<(module_root_dir)/build/Release/",
"-L<(module_root_dir)/libs",
"-lsimplex"
]
}
]
}
+188
View File
@@ -0,0 +1,188 @@
#include <sstream>
#include <string>
#include <node.h>
#include "simplex.h"
namespace simplex
{
using v8::Array;
using v8::ArrayBuffer;
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Maybe;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;
void haskell_init()
{
int argc = 5;
char *argv[] = {
"simplex",
"+RTS", // requires `hs_init_with_rtsopts`
"-A64m", // chunk size for new allocations
"-H64m", // initial heap size
"-xn", // non-moving GC
0};
char **pargv = argv;
hs_init_with_rtsopts(&argc, &pargv);
}
void ChatMigrateInit(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
std::string path(*(v8::String::Utf8Value(isolate, args[0])));
std::string key(*(v8::String::Utf8Value(isolate, args[1])));
std::string confirm(*(v8::String::Utf8Value(isolate, args[2])));
long *ctrl(0);
std::string res = chat_migrate_init(path.c_str(), key.c_str(), confirm.c_str(), &ctrl);
std::stringstream ss;
ss << ctrl
<< "\n"
<< res;
// printf("ChatCtrl after init %d", cChatCtrl);
// v8::Local<v8::String> ctrl = v8::String::NewFromUtf8(isolate, cppChatCtrl.c_str(), v8::String::kNormalString);
args.GetReturnValue().Set(
String::NewFromUtf8(
isolate, ss.str().c_str())
.ToLocalChecked());
}
void ChatCloseStore(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
long *ctrl = (long *)((long)args[0].As<Number>()->Value());
args.GetReturnValue().Set(
String::NewFromUtf8(
isolate, chat_close_store(ctrl))
.ToLocalChecked());
}
void ChatSendCmd(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
long *ctrl = (long *)((long)args[0].As<Number>()->Value());
std::string cmd(*(v8::String::Utf8Value(isolate, args[1])));
args.GetReturnValue().Set(
String::NewFromUtf8(
isolate, chat_send_cmd(ctrl, cmd.c_str()))
.ToLocalChecked());
}
void ChatRecvMsgWait(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
long *ctrl = (long *)((long)args[0].As<Number>()->Value());
long wait = ((long)args[1].As<Number>()->Value());
args.GetReturnValue().Set(
String::NewFromUtf8(
isolate, chat_recv_msg_wait(ctrl, wait))
.ToLocalChecked());
}
void ChatWriteFile(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
long *ctrl = (long *)((long)args[0].As<Number>()->Value());
std::string path(*(v8::String::Utf8Value(isolate, args[1])));
Local<v8::ArrayBuffer> arr = args[2].As<ArrayBuffer>();
char *buffer = (char *)arr->Data();
int len(arr->ByteLength());
// std::array address(*arr);
// v8::Array a = *buffer;
// std::string data(*((isolate, args[1])));
args.GetReturnValue().Set(
String::NewFromUtf8(
isolate, chat_write_file(ctrl, path.c_str(), buffer, len))
.ToLocalChecked());
}
void ChatReadFile(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
long *ctrl = (long *)((long)args[0].As<Number>()->Value());
std::string path(*(v8::String::Utf8Value(isolate, args[1])));
Local<v8::ArrayBuffer> arr = args[2].As<ArrayBuffer>();
char *buffer = (char *)arr->Data();
int len(arr->ByteLength());
args.GetReturnValue().Set(
String::NewFromUtf8(
isolate, chat_write_file(ctrl, path.c_str(), buffer, len))
.ToLocalChecked());
}
void ChatEncryptFile(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
long *ctrl = (long *)((long)args[0].As<Number>()->Value());
std::string fromPath(*(v8::String::Utf8Value(isolate, args[1])));
std::string toPath(*(v8::String::Utf8Value(isolate, args[2])));
args.GetReturnValue().Set(
String::NewFromUtf8(
isolate, chat_encrypt_file(ctrl, fromPath.c_str(), toPath.c_str()))
.ToLocalChecked());
}
void ChatDecryptFile(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
std::string fromPath(*(v8::String::Utf8Value(isolate, args[0])));
std::string key(*(v8::String::Utf8Value(isolate, args[1])));
std::string nonce(*(v8::String::Utf8Value(isolate, args[2])));
std::string toPath(*(v8::String::Utf8Value(isolate, args[3])));
args.GetReturnValue().Set(
String::NewFromUtf8(
isolate, chat_decrypt_file(fromPath.c_str(), key.c_str(), nonce.c_str(), toPath.c_str()))
.ToLocalChecked());
}
void Initialize(Local<Object> exports)
{
haskell_init();
NODE_SET_METHOD(exports, "chat_migrate_init", ChatMigrateInit);
NODE_SET_METHOD(exports, "chat_close_store", ChatCloseStore);
NODE_SET_METHOD(exports, "chat_send_cmd", ChatSendCmd);
NODE_SET_METHOD(exports, "chat_recv_msg_wait", ChatRecvMsgWait);
NODE_SET_METHOD(exports, "chat_write_file", ChatWriteFile);
NODE_SET_METHOD(exports, "chat_read_file", ChatReadFile);
NODE_SET_METHOD(exports, "chat_encrypt_file", ChatEncryptFile);
NODE_SET_METHOD(exports, "chat_decrypt_file", ChatDecryptFile);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
} // namespace simplex
@@ -0,0 +1,46 @@
//
// simplex.h
// SimpleX
//
// Created by Evgeny on 30/05/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
#ifndef SimpleX_h
#define SimpleX_h
extern "C" void hs_init(int argc, char **argv[]);
extern "C" void hs_init_with_rtsopts(int * argc, char **argv[]);
typedef long* chat_ctrl;
// the last parameter is used to return the pointer to chat controller
extern "C" char *chat_migrate_init(const char *path, const char *key, const char *confirm, chat_ctrl *ctrl);
extern "C" char *chat_close_store(chat_ctrl ctrl);
extern "C" char *chat_reopen_store(chat_ctrl ctrl);
extern "C" char *chat_send_cmd(chat_ctrl ctrl, const char *cmd);
extern "C" char *chat_recv_msg_wait(chat_ctrl ctrl, const int wait);
extern "C" char *chat_parse_markdown(const char *str);
extern "C" char *chat_parse_server(const char *str);
extern "C" char *chat_password_hash(const char *pwd, const char *salt);
extern "C" char *chat_valid_name(const char *name);
extern "C" int chat_json_length(const char *str);
extern "C" char *chat_encrypt_media(chat_ctrl ctrl, const char *key, const char *frame, const int len);
extern "C" char *chat_decrypt_media(const char *key, const char *frame, const int len);
// chat_write_file returns null-terminated string with JSON of WriteFileResult
extern "C" char *chat_write_file(chat_ctrl ctrl, const char *path, const char *data, const int len);
// chat_read_file returns a buffer with:
// result status (1 byte), then if
// status == 0 (success): buffer length (uint32, 4 bytes), buffer of specified length.
// status == 1 (error): null-terminated error message string.
extern "C" char *chat_read_file(const char *path, const char *key, const char *nonce);
// chat_encrypt_file returns null-terminated string with JSON of WriteFileResult
extern "C" char *chat_encrypt_file(chat_ctrl ctrl, const char *fromPath, const char *toPath);
// chat_decrypt_file returns null-terminated string with the error message
extern "C" char *chat_decrypt_file(const char *fromPath, const char *key, const char *nonce, const char *toPath);
#endif /* simplex_h */
+31
View File
@@ -0,0 +1,31 @@
{
"name": "simplexjs",
"version": "1.0.0",
"main": "src/index.js",
"scripts": {
"install-tools": "npm install -g node-gyp",
"configure": "node-gyp configure; mkdir libs 2> /dev/null | true",
"rebuild": "node-gyp rebuild",
"build": "node-gyp build",
"run": "node src/index.js",
"build-run": "node-gyp build && node src/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/simplex-chat/simplex-chat.git"
},
"keywords": [
"messenger",
"chat",
"privacy",
"security"
],
"author": "SimpleX Chat",
"license": "AGPL-3.0",
"bugs": {
"url": "https://github.com/simplex-chat/simplex-chat/issues"
},
"homepage": "https://github.com/simplex-chat/simplex-chat/packages/simplex-chat-nodejs#readme",
"description": ""
}
+22
View File
@@ -0,0 +1,22 @@
const addon = require('../build/Release/addon');
const fs = require('fs');
const ctrlAndRes = addon.chat_migrate_init("db", "a", "yesUp")
const ctrl = Number(ctrlAndRes.split("\n")[0])
const res = ctrlAndRes.split("\n")[1]
console.log("Migrate ctrl:", ctrl, "res:", res)
console.log(addon.chat_send_cmd(ctrl, "/v"))
// const wait = 15_000_000
// console.log(ctrl, addon.chat_recv_msg_wait(ctrl, wait))
const path = "/tmp/write_file.txt"
const data = [0, 1, 2]
console.log(addon.chat_write_file(ctrl, path, new ArrayBuffer(data)))
fs.writeFileSync("/tmp/file_unencrypted.txt", "unencrypted")
const encRes = JSON.parse(addon.chat_encrypt_file(ctrl, "/tmp/file_unencrypted.txt", "/tmp/file_encrypted.txt"))
const key = encRes.cryptoArgs.fileKey
const nonce = encRes.cryptoArgs.fileNonce
console.log(encRes)
console.log(addon.chat_decrypt_file("/tmp/file_encrypted.txt", key, nonce, "/tmp/file_decrypted.txt"))
+8 -7
View File
@@ -24,18 +24,19 @@ exports=( $(sed 's/foreign export ccall "chat_migrate_init_key"//' src/Simplex/C
for elem in "${exports[@]}"; do count=$(grep -R "$elem$" libsimplex.dll.def | wc -l); if [ $count -ne 1 ]; then echo Wrong exports in libsimplex.dll.def. Add \"$elem\" to that file; exit 1; fi ; done for elem in "${exports[@]}"; do count=$(grep -R "$elem$" libsimplex.dll.def | wc -l); if [ $count -ne 1 ]; then echo Wrong exports in libsimplex.dll.def. Add \"$elem\" to that file; exit 1; fi ; done
for elem in "${exports[@]}"; do count=$(grep -R "\"$elem\"" flake.nix | wc -l); if [ $count -ne 2 ]; then echo Wrong exports in flake.nix. Add \"$elem\" in two places of the file; exit 1; fi ; done for elem in "${exports[@]}"; do count=$(grep -R "\"$elem\"" flake.nix | wc -l); if [ $count -ne 2 ]; then echo Wrong exports in flake.nix. Add \"$elem\" in two places of the file; exit 1; fi ; done
rm -rf $BUILD_DIR #rm -rf $BUILD_DIR
cabal build lib:simplex-chat --ghc-options='-optl-Wl,-rpath,$ORIGIN -flink-rts -threaded' --constraint 'simplexmq +client_library' cabal build lib:simplex-chat --ghc-options='-optl-Wl,-rpath,$ORIGIN -optl-Wl,-soname,libsimplex.so -flink-rts -threaded' --constraint 'simplexmq +client_library'
cd $BUILD_DIR/build cd $BUILD_DIR/build
#patchelf --add-needed libHSrts_thr-ghc${GHC_VERSION}.so libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so mv libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so libsimplex.so 2> /dev/null || true
#patchelf --add-rpath '$ORIGIN' libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so #patchelf --add-needed libHSrts_thr-ghc${GHC_VERSION}.so libsimplex.so
#patchelf --add-rpath '$ORIGIN' libsimplex.so
# GitHub's Ubuntu 20.04 runner started to set libffi.so.7 as a dependency while Ubuntu 20.04 on user's devices may not have it # GitHub's Ubuntu 20.04 runner started to set libffi.so.7 as a dependency while Ubuntu 20.04 on user's devices may not have it
# but libffi.so.8 is shipped as an external library with other libs # but libffi.so.8 is shipped as an external library with other libs
patchelf --replace-needed "libffi.so.7" "libffi.so.8" libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so patchelf --replace-needed "libffi.so.7" "libffi.so.8" libsimplex.so
mkdir deps 2> /dev/null || true mkdir deps 2> /dev/null || true
ldd libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so | grep "ghc" | cut -d' ' -f 3 | xargs -I {} cp {} ./deps/ ldd libsimplex.so | grep "ghc" | cut -d' ' -f 3 | xargs -I {} cp {} ./deps/
cd - cd -
@@ -44,7 +45,7 @@ rm -rf apps/multiplatform/desktop/build/cmake
mkdir -p apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ mkdir -p apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/
cp -r $BUILD_DIR/build/deps/* apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ cp -r $BUILD_DIR/build/deps/* apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/
cp $BUILD_DIR/build/libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ cp $BUILD_DIR/build/libsimplex.so apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/
scripts/desktop/prepare-vlc-linux.sh scripts/desktop/prepare-vlc-linux.sh
links_dir=apps/multiplatform/build/links links_dir=apps/multiplatform/build/links
+4 -3
View File
@@ -14,7 +14,7 @@ else
fi fi
LIB_EXT=dylib LIB_EXT=dylib
LIB=libHSsimplex-chat-*-inplace-ghc*.$LIB_EXT LIB=libsimplex.$LIB_EXT
GHC_LIBS_DIR=$(ghc --print-libdir) GHC_LIBS_DIR=$(ghc --print-libdir)
BUILD_DIR=dist-newstyle/build/$ARCH-*/ghc-*/simplex-chat-* BUILD_DIR=dist-newstyle/build/$ARCH-*/ghc-*/simplex-chat-*
@@ -24,9 +24,10 @@ for elem in "${exports[@]}"; do count=$(grep -R "$elem$" libsimplex.dll.def | wc
for elem in "${exports[@]}"; do count=$(grep -R "\"$elem\"" flake.nix | wc -l); if [ $count -ne 2 ]; then echo Wrong exports in flake.nix. Add \"$elem\" in two places of the file; exit 1; fi ; done for elem in "${exports[@]}"; do count=$(grep -R "\"$elem\"" flake.nix | wc -l); if [ $count -ne 2 ]; then echo Wrong exports in flake.nix. Add \"$elem\" in two places of the file; exit 1; fi ; done
rm -rf $BUILD_DIR rm -rf $BUILD_DIR
cabal build lib:simplex-chat lib:simplex-chat --ghc-options="-optl-Wl,-rpath,@loader_path -optl-Wl,-L$GHC_LIBS_DIR/$ARCH-osx-ghc-$GHC_VERSION -optl-lHSrts_thr-ghc$GHC_VERSION -optl-lffi" --constraint 'simplexmq +client_library' cabal build lib:simplex-chat lib:simplex-chat --ghc-options="-optl-Wl,-rpath,@loader_path -optl-Wl,-install_name,@rpath/$LIB -optl-Wl,-L$GHC_LIBS_DIR/$ARCH-osx-ghc-$GHC_VERSION -optl-lHSrts_thr-ghc$GHC_VERSION -optl-lffi" --constraint 'simplexmq +client_library'
cd $BUILD_DIR/build cd $BUILD_DIR/build
mv libHSsimplex-chat-*-inplace-ghc*.$LIB_EXT libsimplex.dylib 2> /dev/null || true
mkdir deps 2> /dev/null || true mkdir deps 2> /dev/null || true
# It's not included by default for some reason. Compiled lib tries to find system one but it's not always available # It's not included by default for some reason. Compiled lib tries to find system one but it's not always available
@@ -95,7 +96,7 @@ rm -rf apps/multiplatform/desktop/build/cmake
mkdir -p apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ mkdir -p apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/
cp -r $BUILD_DIR/build/deps/* apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ cp -r $BUILD_DIR/build/deps/* apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/
cp $BUILD_DIR/build/libHSsimplex-chat-*-inplace-ghc*.$LIB_EXT apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ cp $BUILD_DIR/build/$LIB apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/
cd apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/ cd apps/multiplatform/common/src/commonMain/cpp/desktop/libs/$OS-$ARCH/
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"https://github.com/simplex-chat/simplexmq.git"."8647c24a9555d4232b1cb21fed3a7c2518aa7b13" = "1pmblkvmj5n6qa8ri8axd9sw7fbpmq7fipaf1klbhb9ghb89lqmf"; "https://github.com/simplex-chat/simplexmq.git"."79e9447b73cc315ce35042b0a5f210c07ea39b07" = "16z7z5a3f7gw0h188manykp008d1bqpydlrj7h497mgyjmp4cy9m";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d"; "https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl"; "https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
+9 -8
View File
@@ -92,8 +92,9 @@ import Simplex.Chat.Types.Preferences
import Simplex.Chat.Types.Shared import Simplex.Chat.Types.Shared
import Simplex.Chat.Util (encryptFile, liftIOEither, shuffle) import Simplex.Chat.Util (encryptFile, liftIOEither, shuffle)
import qualified Simplex.Chat.Util as U import qualified Simplex.Chat.Util as U
import Simplex.FileTransfer.Client.Main (maxFileSize, maxFileSizeHard)
import Simplex.FileTransfer.Client.Presets (defaultXFTPServers) import Simplex.FileTransfer.Client.Presets (defaultXFTPServers)
import Simplex.FileTransfer.Description (FileDescriptionURI (..), ValidFileDescription, maxFileSize, maxFileSizeHard) import Simplex.FileTransfer.Description (FileDescriptionURI (..), ValidFileDescription)
import qualified Simplex.FileTransfer.Description as FD import qualified Simplex.FileTransfer.Description as FD
import Simplex.FileTransfer.Protocol (FileParty (..), FilePartyI) import Simplex.FileTransfer.Protocol (FileParty (..), FilePartyI)
import qualified Simplex.FileTransfer.Transport as XFTP import qualified Simplex.FileTransfer.Transport as XFTP
@@ -542,13 +543,13 @@ startChatController mainApp enableSndFiles = do
then Just <$> async (subscribeUsers False users) then Just <$> async (subscribeUsers False users)
else pure Nothing else pure Nothing
atomically . writeTVar s $ Just (a1, a2) atomically . writeTVar s $ Just (a1, a2)
-- if mainApp if mainApp
-- then do then do
-- startXFTP xftpStartWorkers startXFTP xftpStartWorkers
-- void $ forkIO $ startFilesToReceive users void $ forkIO $ startFilesToReceive users
-- startCleanupManager startCleanupManager
-- void $ forkIO $ startExpireCIs users void $ forkIO $ startExpireCIs users
-- else when enableSndFiles $ startXFTP xftpStartSndWorkers else when enableSndFiles $ startXFTP xftpStartSndWorkers
pure a1 pure a1
startXFTP startWorkers = do startXFTP startWorkers = do
tmp <- readTVarIO =<< asks tempDirectory tmp <- readTVarIO =<< asks tempDirectory