Compare commits
16 Commits
weblate/we
...
v5.5.4-fdr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d523d5b4b | ||
|
|
2a321b3ff8 | ||
|
|
865a32c608 | ||
|
|
91f10c056f | ||
|
|
fec34ca875 | ||
|
|
3a0920e950 | ||
|
|
7e9e71ffbd | ||
|
|
09bbaa1c94 | ||
|
|
3a879b755b | ||
|
|
c6f4d62d6c | ||
|
|
5ad356172f | ||
|
|
0a6c464a8d | ||
|
|
1aa464bdb2 | ||
|
|
bce829ef58 | ||
|
|
7df300cf36 | ||
|
|
9b35ff6f11 |
@@ -1861,7 +1861,9 @@ func chatItemSimpleUpdate(_ user: any UserLike, _ aChatItem: AChatItem) async {
|
|||||||
let cItem = aChatItem.chatItem
|
let cItem = aChatItem.chatItem
|
||||||
if active(user) {
|
if active(user) {
|
||||||
if await MainActor.run(body: { m.upsertChatItem(cInfo, cItem) }) {
|
if await MainActor.run(body: { m.upsertChatItem(cInfo, cItem) }) {
|
||||||
NtfManager.shared.notifyMessageReceived(user, cInfo, cItem)
|
if cItem.showNotification {
|
||||||
|
NtfManager.shared.notifyMessageReceived(user, cInfo, cItem)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,11 @@
|
|||||||
5C116CDC27AABE0400E66D01 /* ContactRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C116CDB27AABE0400E66D01 /* ContactRequestView.swift */; };
|
5C116CDC27AABE0400E66D01 /* ContactRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C116CDB27AABE0400E66D01 /* ContactRequestView.swift */; };
|
||||||
5C13730B28156D2700F43030 /* ContactConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C13730A28156D2700F43030 /* ContactConnectionView.swift */; };
|
5C13730B28156D2700F43030 /* ContactConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C13730A28156D2700F43030 /* ContactConnectionView.swift */; };
|
||||||
5C1A4C1E27A715B700EAD5AD /* ChatItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1A4C1D27A715B700EAD5AD /* ChatItemView.swift */; };
|
5C1A4C1E27A715B700EAD5AD /* ChatItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1A4C1D27A715B700EAD5AD /* ChatItemView.swift */; };
|
||||||
|
5C29C3AF2B783F82003DF84C /* libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C29C3AA2B783F82003DF84C /* libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk-ghc9.6.3.a */; };
|
||||||
|
5C29C3B02B783F82003DF84C /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C29C3AB2B783F82003DF84C /* libgmpxx.a */; };
|
||||||
|
5C29C3B12B783F82003DF84C /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C29C3AC2B783F82003DF84C /* libffi.a */; };
|
||||||
|
5C29C3B22B783F82003DF84C /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C29C3AD2B783F82003DF84C /* libgmp.a */; };
|
||||||
|
5C29C3B32B783F82003DF84C /* libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C29C3AE2B783F82003DF84C /* libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk.a */; };
|
||||||
5C2E260727A2941F00F70299 /* SimpleXAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260627A2941F00F70299 /* SimpleXAPI.swift */; };
|
5C2E260727A2941F00F70299 /* SimpleXAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260627A2941F00F70299 /* SimpleXAPI.swift */; };
|
||||||
5C2E260B27A30CFA00F70299 /* ChatListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260A27A30CFA00F70299 /* ChatListView.swift */; };
|
5C2E260B27A30CFA00F70299 /* ChatListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260A27A30CFA00F70299 /* ChatListView.swift */; };
|
||||||
5C2E260F27A30FDC00F70299 /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260E27A30FDC00F70299 /* ChatView.swift */; };
|
5C2E260F27A30FDC00F70299 /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260E27A30FDC00F70299 /* ChatView.swift */; };
|
||||||
@@ -61,11 +66,6 @@
|
|||||||
5C7505A527B679EE00BE3227 /* NavLinkPlain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */; };
|
5C7505A527B679EE00BE3227 /* NavLinkPlain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */; };
|
||||||
5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */; };
|
5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */; };
|
||||||
5C764E89279CBCB3000C6508 /* ChatModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C764E88279CBCB3000C6508 /* ChatModel.swift */; };
|
5C764E89279CBCB3000C6508 /* ChatModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C764E88279CBCB3000C6508 /* ChatModel.swift */; };
|
||||||
5C83A1AD2B5EF67D00AE0A4A /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C83A1A82B5EF67D00AE0A4A /* libgmp.a */; };
|
|
||||||
5C83A1AE2B5EF67D00AE0A4A /* libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C83A1A92B5EF67D00AE0A4A /* libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3-ghc9.6.3.a */; };
|
|
||||||
5C83A1AF2B5EF67D00AE0A4A /* libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C83A1AA2B5EF67D00AE0A4A /* libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3.a */; };
|
|
||||||
5C83A1B02B5EF67D00AE0A4A /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C83A1AB2B5EF67D00AE0A4A /* libffi.a */; };
|
|
||||||
5C83A1B12B5EF67D00AE0A4A /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C83A1AC2B5EF67D00AE0A4A /* libgmpxx.a */; };
|
|
||||||
5C8F01CD27A6F0D8007D2C8D /* CodeScanner in Frameworks */ = {isa = PBXBuildFile; productRef = 5C8F01CC27A6F0D8007D2C8D /* CodeScanner */; };
|
5C8F01CD27A6F0D8007D2C8D /* CodeScanner in Frameworks */ = {isa = PBXBuildFile; productRef = 5C8F01CC27A6F0D8007D2C8D /* CodeScanner */; };
|
||||||
5C93292F29239A170090FFF9 /* ProtocolServersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C93292E29239A170090FFF9 /* ProtocolServersView.swift */; };
|
5C93292F29239A170090FFF9 /* ProtocolServersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C93292E29239A170090FFF9 /* ProtocolServersView.swift */; };
|
||||||
5C93293129239BED0090FFF9 /* ProtocolServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C93293029239BED0090FFF9 /* ProtocolServerView.swift */; };
|
5C93293129239BED0090FFF9 /* ProtocolServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C93293029239BED0090FFF9 /* ProtocolServerView.swift */; };
|
||||||
@@ -278,6 +278,11 @@
|
|||||||
5C245F3C2B501E98001CC39F /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
5C245F3C2B501E98001CC39F /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
5C245F3D2B501F13001CC39F /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = "tr.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
|
5C245F3D2B501F13001CC39F /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = "tr.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
|
||||||
5C245F3E2B501F13001CC39F /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
5C245F3E2B501F13001CC39F /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
|
5C29C3AA2B783F82003DF84C /* libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||||
|
5C29C3AB2B783F82003DF84C /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||||
|
5C29C3AC2B783F82003DF84C /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||||
|
5C29C3AD2B783F82003DF84C /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||||
|
5C29C3AE2B783F82003DF84C /* libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk.a"; sourceTree = "<group>"; };
|
||||||
5C2E260627A2941F00F70299 /* SimpleXAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleXAPI.swift; sourceTree = "<group>"; };
|
5C2E260627A2941F00F70299 /* SimpleXAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleXAPI.swift; sourceTree = "<group>"; };
|
||||||
5C2E260A27A30CFA00F70299 /* ChatListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListView.swift; sourceTree = "<group>"; };
|
5C2E260A27A30CFA00F70299 /* ChatListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListView.swift; sourceTree = "<group>"; };
|
||||||
5C2E260E27A30FDC00F70299 /* ChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatView.swift; sourceTree = "<group>"; };
|
5C2E260E27A30FDC00F70299 /* ChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatView.swift; sourceTree = "<group>"; };
|
||||||
@@ -325,11 +330,6 @@
|
|||||||
5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavLinkPlain.swift; sourceTree = "<group>"; };
|
5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavLinkPlain.swift; sourceTree = "<group>"; };
|
||||||
5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoToolbar.swift; sourceTree = "<group>"; };
|
5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoToolbar.swift; sourceTree = "<group>"; };
|
||||||
5C764E88279CBCB3000C6508 /* ChatModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatModel.swift; sourceTree = "<group>"; };
|
5C764E88279CBCB3000C6508 /* ChatModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatModel.swift; sourceTree = "<group>"; };
|
||||||
5C83A1A82B5EF67D00AE0A4A /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
|
||||||
5C83A1A92B5EF67D00AE0A4A /* libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3-ghc9.6.3.a"; sourceTree = "<group>"; };
|
|
||||||
5C83A1AA2B5EF67D00AE0A4A /* libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3.a"; sourceTree = "<group>"; };
|
|
||||||
5C83A1AB2B5EF67D00AE0A4A /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
|
||||||
5C83A1AC2B5EF67D00AE0A4A /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
|
||||||
5C84FE9129A216C800D95B1A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
5C84FE9129A216C800D95B1A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
5C84FE9329A2179C00D95B1A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = "nl.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
|
5C84FE9329A2179C00D95B1A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = "nl.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
|
||||||
5C84FE9429A2179C00D95B1A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
5C84FE9429A2179C00D95B1A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
@@ -514,13 +514,13 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
5C29C3B02B783F82003DF84C /* libgmpxx.a in Frameworks */,
|
||||||
|
5C29C3B32B783F82003DF84C /* libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk.a in Frameworks */,
|
||||||
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
|
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
|
||||||
5C83A1B02B5EF67D00AE0A4A /* libffi.a in Frameworks */,
|
|
||||||
5C83A1AD2B5EF67D00AE0A4A /* libgmp.a in Frameworks */,
|
|
||||||
5C83A1AE2B5EF67D00AE0A4A /* libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3-ghc9.6.3.a in Frameworks */,
|
|
||||||
5C83A1AF2B5EF67D00AE0A4A /* libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3.a in Frameworks */,
|
|
||||||
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
|
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
|
||||||
5C83A1B12B5EF67D00AE0A4A /* libgmpxx.a in Frameworks */,
|
5C29C3B12B783F82003DF84C /* libffi.a in Frameworks */,
|
||||||
|
5C29C3B22B783F82003DF84C /* libgmp.a in Frameworks */,
|
||||||
|
5C29C3AF2B783F82003DF84C /* libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk-ghc9.6.3.a in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -582,11 +582,11 @@
|
|||||||
5C764E5C279C70B7000C6508 /* Libraries */ = {
|
5C764E5C279C70B7000C6508 /* Libraries */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
5C83A1AB2B5EF67D00AE0A4A /* libffi.a */,
|
5C29C3AC2B783F82003DF84C /* libffi.a */,
|
||||||
5C83A1A82B5EF67D00AE0A4A /* libgmp.a */,
|
5C29C3AD2B783F82003DF84C /* libgmp.a */,
|
||||||
5C83A1AC2B5EF67D00AE0A4A /* libgmpxx.a */,
|
5C29C3AB2B783F82003DF84C /* libgmpxx.a */,
|
||||||
5C83A1A92B5EF67D00AE0A4A /* libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3-ghc9.6.3.a */,
|
5C29C3AA2B783F82003DF84C /* libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk-ghc9.6.3.a */,
|
||||||
5C83A1AA2B5EF67D00AE0A4A /* libHSsimplex-chat-5.5.0.4-HTW6wkBBAjO2GDtnvnI9O3.a */,
|
5C29C3AE2B783F82003DF84C /* libHSsimplex-chat-5.5.3.0-AUrnxTuqxo1yzY63w39Bk.a */,
|
||||||
);
|
);
|
||||||
path = Libraries;
|
path = Libraries;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1509,7 +1509,7 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 194;
|
CURRENT_PROJECT_VERSION = 199;
|
||||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@@ -1531,7 +1531,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 5.5;
|
MARKETING_VERSION = 5.5.4;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
|
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
|
||||||
PRODUCT_NAME = SimpleX;
|
PRODUCT_NAME = SimpleX;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@@ -1552,7 +1552,7 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 194;
|
CURRENT_PROJECT_VERSION = 199;
|
||||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@@ -1574,7 +1574,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 5.5;
|
MARKETING_VERSION = 5.5.4;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
|
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
|
||||||
PRODUCT_NAME = SimpleX;
|
PRODUCT_NAME = SimpleX;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@@ -1633,7 +1633,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 = 194;
|
CURRENT_PROJECT_VERSION = 199;
|
||||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1646,7 +1646,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 5.5;
|
MARKETING_VERSION = 5.5.4;
|
||||||
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 = "";
|
||||||
@@ -1665,7 +1665,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 = 194;
|
CURRENT_PROJECT_VERSION = 199;
|
||||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1678,7 +1678,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 5.5;
|
MARKETING_VERSION = 5.5.4;
|
||||||
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 = "";
|
||||||
@@ -1697,7 +1697,7 @@
|
|||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 194;
|
CURRENT_PROJECT_VERSION = 199;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
@@ -1721,7 +1721,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Libraries/sim",
|
"$(PROJECT_DIR)/Libraries/sim",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 5.5;
|
MARKETING_VERSION = 5.5.4;
|
||||||
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;
|
||||||
@@ -1743,7 +1743,7 @@
|
|||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 194;
|
CURRENT_PROJECT_VERSION = 199;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
@@ -1767,7 +1767,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Libraries/sim",
|
"$(PROJECT_DIR)/Libraries/sim",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 5.5;
|
MARKETING_VERSION = 5.5.4;
|
||||||
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;
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class SimplexApp: Application(), LifecycleEventObserver {
|
|||||||
|
|
||||||
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
|
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
|
||||||
Log.d(TAG, "onStateChanged: $event")
|
Log.d(TAG, "onStateChanged: $event")
|
||||||
withBGApi {
|
withLongRunningApi {
|
||||||
when (event) {
|
when (event) {
|
||||||
Lifecycle.Event.ON_START -> {
|
Lifecycle.Event.ON_START -> {
|
||||||
isAppOnForeground = true
|
isAppOnForeground = true
|
||||||
|
|||||||
@@ -14,17 +14,27 @@ import chat.simplex.common.views.helpers.*
|
|||||||
import java.io.BufferedOutputStream
|
import java.io.BufferedOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import chat.simplex.res.MR
|
import chat.simplex.res.MR
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
actual fun ClipboardManager.shareText(text: String) {
|
actual fun ClipboardManager.shareText(text: String) {
|
||||||
val sendIntent: Intent = Intent().apply {
|
var text = text
|
||||||
action = Intent.ACTION_SEND
|
for (i in 10 downTo 1) {
|
||||||
putExtra(Intent.EXTRA_TEXT, text)
|
try {
|
||||||
type = "text/plain"
|
val sendIntent: Intent = Intent().apply {
|
||||||
flags = FLAG_ACTIVITY_NEW_TASK
|
action = Intent.ACTION_SEND
|
||||||
|
putExtra(Intent.EXTRA_TEXT, text)
|
||||||
|
type = "text/plain"
|
||||||
|
flags = FLAG_ACTIVITY_NEW_TASK
|
||||||
|
}
|
||||||
|
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||||
|
shareIntent.addFlags(FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
androidAppContext.startActivity(shareIntent)
|
||||||
|
break
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Failed to share text: ${e.stackTraceToString()}")
|
||||||
|
text = text.substring(0, min(i * 1000, text.length))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
|
||||||
shareIntent.addFlags(FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
androidAppContext.startActivity(shareIntent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun shareFile(text: String, fileSource: CryptoFile) {
|
actual fun shareFile(text: String, fileSource: CryptoFile) {
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import androidx.activity.compose.setContent
|
|||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
import chat.simplex.common.AppScreen
|
import chat.simplex.common.AppScreen
|
||||||
|
import chat.simplex.common.model.clear
|
||||||
|
import chat.simplex.common.ui.theme.SimpleXTheme
|
||||||
import chat.simplex.common.views.helpers.*
|
import chat.simplex.common.views.helpers.*
|
||||||
import androidx.compose.ui.platform.LocalContext as LocalContext1
|
import androidx.compose.ui.platform.LocalContext as LocalContext1
|
||||||
import chat.simplex.res.MR
|
import chat.simplex.res.MR
|
||||||
@@ -112,7 +114,8 @@ actual class GlobalExceptionsHandler: Thread.UncaughtExceptionHandler {
|
|||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
AlertManager.shared.showAlertMsg(
|
AlertManager.shared.showAlertMsg(
|
||||||
title = generalGetString(MR.strings.app_was_crashed),
|
title = generalGetString(MR.strings.app_was_crashed),
|
||||||
text = e.stackTraceToString()
|
text = e.stackTraceToString(),
|
||||||
|
shareText = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package chat.simplex.common.model
|
|||||||
|
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||||
import androidx.compose.runtime.snapshots.SnapshotStateMap
|
import androidx.compose.runtime.snapshots.SnapshotStateMap
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.SpanStyle
|
import androidx.compose.ui.text.SpanStyle
|
||||||
@@ -56,7 +57,7 @@ object ChatModel {
|
|||||||
|
|
||||||
// current chat
|
// current chat
|
||||||
val chatId = mutableStateOf<String?>(null)
|
val chatId = mutableStateOf<String?>(null)
|
||||||
val chatItems = mutableStateListOf<ChatItem>()
|
val chatItems = mutableStateOf(SnapshotStateList<ChatItem>())
|
||||||
// rhId, chatId
|
// rhId, chatId
|
||||||
val deletedChats = mutableStateOf<List<Pair<Long?, String>>>(emptyList())
|
val deletedChats = mutableStateOf<List<Pair<Long?, String>>>(emptyList())
|
||||||
val chatItemStatuses = mutableMapOf<Long, CIStatus>()
|
val chatItemStatuses = mutableMapOf<Long, CIStatus>()
|
||||||
@@ -268,18 +269,15 @@ object ChatModel {
|
|||||||
} else {
|
} else {
|
||||||
addChat(Chat(remoteHostId = rhId, chatInfo = cInfo, chatItems = arrayListOf(cItem)))
|
addChat(Chat(remoteHostId = rhId, chatInfo = cInfo, chatItems = arrayListOf(cItem)))
|
||||||
}
|
}
|
||||||
Log.d(TAG, "TODOCHAT: addChatItem: adding to chat ${chatId.value} from ${cInfo.id} ${cItem.id}, size ${chatItems.size}")
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
// add to current chat
|
// add to current chat
|
||||||
if (chatId.value == cInfo.id) {
|
if (chatId.value == cInfo.id) {
|
||||||
Log.d(TAG, "TODOCHAT: addChatItem: chatIds are equal, size ${chatItems.size}")
|
|
||||||
// Prevent situation when chat item already in the list received from backend
|
// Prevent situation when chat item already in the list received from backend
|
||||||
if (chatItems.none { it.id == cItem.id }) {
|
if (chatItems.value.none { it.id == cItem.id }) {
|
||||||
if (chatItems.lastOrNull()?.id == ChatItem.TEMP_LIVE_CHAT_ITEM_ID) {
|
if (chatItems.value.lastOrNull()?.id == ChatItem.TEMP_LIVE_CHAT_ITEM_ID) {
|
||||||
chatItems.add(kotlin.math.max(0, chatItems.lastIndex), cItem)
|
chatItems.add(kotlin.math.max(0, chatItems.value.lastIndex), cItem)
|
||||||
} else {
|
} else {
|
||||||
chatItems.add(cItem)
|
chatItems.add(cItem)
|
||||||
Log.d(TAG, "TODOCHAT: addChatItem: added to chat ${chatId.value} from ${cInfo.id} ${cItem.id}, size ${chatItems.size}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,14 +304,13 @@ object ChatModel {
|
|||||||
addChat(Chat(remoteHostId = rhId, chatInfo = cInfo, chatItems = arrayListOf(cItem)))
|
addChat(Chat(remoteHostId = rhId, chatInfo = cInfo, chatItems = arrayListOf(cItem)))
|
||||||
res = true
|
res = true
|
||||||
}
|
}
|
||||||
Log.d(TAG, "TODOCHAT: upsertChatItem: upserting to chat ${chatId.value} from ${cInfo.id} ${cItem.id}, size ${chatItems.size}")
|
|
||||||
return withContext(Dispatchers.Main) {
|
return withContext(Dispatchers.Main) {
|
||||||
// update current chat
|
// update current chat
|
||||||
if (chatId.value == cInfo.id) {
|
if (chatId.value == cInfo.id) {
|
||||||
val itemIndex = chatItems.indexOfFirst { it.id == cItem.id }
|
val items = chatItems.value
|
||||||
|
val itemIndex = items.indexOfFirst { it.id == cItem.id }
|
||||||
if (itemIndex >= 0) {
|
if (itemIndex >= 0) {
|
||||||
chatItems[itemIndex] = cItem
|
items[itemIndex] = cItem
|
||||||
Log.d(TAG, "TODOCHAT: upsertChatItem: updated in chat $chatId from ${cInfo.id} ${cItem.id}, size ${chatItems.size}")
|
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
val status = chatItemStatuses.remove(cItem.id)
|
val status = chatItemStatuses.remove(cItem.id)
|
||||||
@@ -323,7 +320,6 @@ object ChatModel {
|
|||||||
cItem
|
cItem
|
||||||
}
|
}
|
||||||
chatItems.add(ci)
|
chatItems.add(ci)
|
||||||
Log.d(TAG, "TODOCHAT: upsertChatItem: added to chat $chatId from ${cInfo.id} ${cItem.id}, size ${chatItems.size}")
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -335,9 +331,10 @@ object ChatModel {
|
|||||||
suspend fun updateChatItem(cInfo: ChatInfo, cItem: ChatItem, status: CIStatus? = null) {
|
suspend fun updateChatItem(cInfo: ChatInfo, cItem: ChatItem, status: CIStatus? = null) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (chatId.value == cInfo.id) {
|
if (chatId.value == cInfo.id) {
|
||||||
val itemIndex = chatItems.indexOfFirst { it.id == cItem.id }
|
val items = chatItems.value
|
||||||
|
val itemIndex = items.indexOfFirst { it.id == cItem.id }
|
||||||
if (itemIndex >= 0) {
|
if (itemIndex >= 0) {
|
||||||
chatItems[itemIndex] = cItem
|
items[itemIndex] = cItem
|
||||||
}
|
}
|
||||||
} else if (status != null) {
|
} else if (status != null) {
|
||||||
chatItemStatuses[cItem.id] = status
|
chatItemStatuses[cItem.id] = status
|
||||||
@@ -361,10 +358,10 @@ object ChatModel {
|
|||||||
}
|
}
|
||||||
// remove from current chat
|
// remove from current chat
|
||||||
if (chatId.value == cInfo.id) {
|
if (chatId.value == cInfo.id) {
|
||||||
val itemIndex = chatItems.indexOfFirst { it.id == cItem.id }
|
chatItems.removeAll {
|
||||||
if (itemIndex >= 0) {
|
val remove = it.id == cItem.id
|
||||||
AudioPlayer.stop(chatItems[itemIndex])
|
if (remove) { AudioPlayer.stop(it) }
|
||||||
chatItems.removeAt(itemIndex)
|
remove
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -405,7 +402,7 @@ object ChatModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun removeLiveDummy() {
|
fun removeLiveDummy() {
|
||||||
if (chatItems.lastOrNull()?.id == ChatItem.TEMP_LIVE_CHAT_ITEM_ID) {
|
if (chatItems.value.lastOrNull()?.id == ChatItem.TEMP_LIVE_CHAT_ITEM_ID) {
|
||||||
chatItems.removeLast()
|
chatItems.removeLast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -437,14 +434,14 @@ object ChatModel {
|
|||||||
var markedRead = 0
|
var markedRead = 0
|
||||||
if (chatId.value == cInfo.id) {
|
if (chatId.value == cInfo.id) {
|
||||||
var i = 0
|
var i = 0
|
||||||
Log.d(TAG, "TODOCHAT: markItemsReadInCurrentChat: marking read ${cInfo.id}, current chatId ${chatId.value}, size was ${chatItems.size}")
|
val items = chatItems.value
|
||||||
while (i < chatItems.count()) {
|
while (i < items.size) {
|
||||||
val item = chatItems[i]
|
val item = items[i]
|
||||||
if (item.meta.itemStatus is CIStatus.RcvNew && (range == null || (range.from <= item.id && item.id <= range.to))) {
|
if (item.meta.itemStatus is CIStatus.RcvNew && (range == null || (range.from <= item.id && item.id <= range.to))) {
|
||||||
val newItem = item.withStatus(CIStatus.RcvRead())
|
val newItem = item.withStatus(CIStatus.RcvRead())
|
||||||
chatItems[i] = newItem
|
items[i] = newItem
|
||||||
if (newItem.meta.itemLive != true && newItem.meta.itemTimed?.ttl != null) {
|
if (newItem.meta.itemLive != true && newItem.meta.itemTimed?.ttl != null) {
|
||||||
chatItems[i] = newItem.copy(meta = newItem.meta.copy(itemTimed = newItem.meta.itemTimed.copy(
|
items[i] = newItem.copy(meta = newItem.meta.copy(itemTimed = newItem.meta.itemTimed.copy(
|
||||||
deleteAt = Clock.System.now() + newItem.meta.itemTimed.ttl.toDuration(DurationUnit.SECONDS)))
|
deleteAt = Clock.System.now() + newItem.meta.itemTimed.ttl.toDuration(DurationUnit.SECONDS)))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -452,7 +449,6 @@ object ChatModel {
|
|||||||
}
|
}
|
||||||
i += 1
|
i += 1
|
||||||
}
|
}
|
||||||
Log.d(TAG, "TODOCHAT: markItemsReadInCurrentChat: marked read ${cInfo.id}, current chatId ${chatId.value}, size now ${chatItems.size}")
|
|
||||||
}
|
}
|
||||||
return markedRead
|
return markedRead
|
||||||
}
|
}
|
||||||
@@ -2006,6 +2002,46 @@ data class ChatItem (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun MutableState<SnapshotStateList<ChatItem>>.add(index: Int, chatItem: ChatItem) {
|
||||||
|
value = SnapshotStateList<ChatItem>().apply { addAll(value); add(index, chatItem) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MutableState<SnapshotStateList<ChatItem>>.add(chatItem: ChatItem) {
|
||||||
|
value = SnapshotStateList<ChatItem>().apply { addAll(value); add(chatItem) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MutableState<SnapshotStateList<ChatItem>>.addAll(index: Int, chatItems: List<ChatItem>) {
|
||||||
|
value = SnapshotStateList<ChatItem>().apply { addAll(value); addAll(index, chatItems) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MutableState<SnapshotStateList<ChatItem>>.addAll(chatItems: List<ChatItem>) {
|
||||||
|
value = SnapshotStateList<ChatItem>().apply { addAll(value); addAll(chatItems) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MutableState<SnapshotStateList<ChatItem>>.removeAll(block: (ChatItem) -> Boolean) {
|
||||||
|
value = SnapshotStateList<ChatItem>().apply { addAll(value); removeAll(block) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MutableState<SnapshotStateList<ChatItem>>.removeAt(index: Int) {
|
||||||
|
value = SnapshotStateList<ChatItem>().apply { addAll(value); removeAt(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MutableState<SnapshotStateList<ChatItem>>.removeLast() {
|
||||||
|
value = SnapshotStateList<ChatItem>().apply { addAll(value); removeLast() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MutableState<SnapshotStateList<ChatItem>>.replaceAll(chatItems: List<ChatItem>) {
|
||||||
|
value = SnapshotStateList<ChatItem>().apply { addAll(chatItems) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MutableState<SnapshotStateList<ChatItem>>.clear() {
|
||||||
|
value = SnapshotStateList<ChatItem>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun State<SnapshotStateList<ChatItem>>.asReversed(): MutableList<ChatItem> = value.asReversed()
|
||||||
|
|
||||||
|
val State<List<ChatItem>>.size: Int get() = value.size
|
||||||
|
|
||||||
enum class CIMergeCategory {
|
enum class CIMergeCategory {
|
||||||
MemberConnected,
|
MemberConnected,
|
||||||
RcvGroupEvent,
|
RcvGroupEvent,
|
||||||
|
|||||||
@@ -451,7 +451,21 @@ object ChatController {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val msg = recvMsg(ctrl)
|
val msg = recvMsg(ctrl)
|
||||||
if (msg != null) processReceivedMsg(msg)
|
if (msg != null) {
|
||||||
|
val finishedWithoutTimeout = withTimeoutOrNull(60_000L) {
|
||||||
|
processReceivedMsg(msg)
|
||||||
|
}
|
||||||
|
if (finishedWithoutTimeout == null) {
|
||||||
|
Log.e(TAG, "Timeout reached while processing received message: " + msg.resp.responseType)
|
||||||
|
if (appPreferences.developerTools.get() && appPreferences.showSlowApiCalls.get()) {
|
||||||
|
AlertManager.shared.showAlertMsg(
|
||||||
|
title = generalGetString(MR.strings.possible_slow_function_title),
|
||||||
|
text = generalGetString(MR.strings.possible_slow_function_desc).format(60, msg.resp.responseType + "\n" + Exception().stackTraceToString()),
|
||||||
|
shareText = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "ChatController recvMsg/processReceivedMsg exception: " + e.stackTraceToString());
|
Log.e(TAG, "ChatController recvMsg/processReceivedMsg exception: " + e.stackTraceToString());
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
@@ -1685,7 +1699,7 @@ object ChatController {
|
|||||||
chatModel.networkStatuses[s.agentConnId] = s.networkStatus
|
chatModel.networkStatuses[s.agentConnId] = s.networkStatus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is CR.NewChatItem -> {
|
is CR.NewChatItem -> withBGApi {
|
||||||
val cInfo = r.chatItem.chatInfo
|
val cInfo = r.chatItem.chatInfo
|
||||||
val cItem = r.chatItem.chatItem
|
val cItem = r.chatItem.chatItem
|
||||||
if (active(r.user)) {
|
if (active(r.user)) {
|
||||||
@@ -1700,7 +1714,7 @@ object ChatController {
|
|||||||
((mc is MsgContent.MCImage && file.fileSize <= MAX_IMAGE_SIZE_AUTO_RCV)
|
((mc is MsgContent.MCImage && file.fileSize <= MAX_IMAGE_SIZE_AUTO_RCV)
|
||||||
|| (mc is MsgContent.MCVideo && file.fileSize <= MAX_VIDEO_SIZE_AUTO_RCV)
|
|| (mc is MsgContent.MCVideo && file.fileSize <= MAX_VIDEO_SIZE_AUTO_RCV)
|
||||||
|| (mc is MsgContent.MCVoice && file.fileSize <= MAX_VOICE_SIZE_AUTO_RCV && file.fileStatus !is CIFileStatus.RcvAccepted))) {
|
|| (mc is MsgContent.MCVoice && file.fileSize <= MAX_VOICE_SIZE_AUTO_RCV && file.fileStatus !is CIFileStatus.RcvAccepted))) {
|
||||||
withBGApi { receiveFile(rhId, r.user, file.fileId, auto = true) }
|
receiveFile(rhId, r.user, file.fileId, auto = true)
|
||||||
}
|
}
|
||||||
if (cItem.showNotification && (allowedToShowNotification() || chatModel.chatId.value != cInfo.id || chatModel.remoteHostId() != rhId)) {
|
if (cItem.showNotification && (allowedToShowNotification() || chatModel.chatId.value != cInfo.id || chatModel.remoteHostId() != rhId)) {
|
||||||
ntfManager.notifyMessageReceived(r.user, cInfo, cItem)
|
ntfManager.notifyMessageReceived(r.user, cInfo, cItem)
|
||||||
|
|||||||
@@ -67,14 +67,12 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId:
|
|||||||
launch {
|
launch {
|
||||||
snapshotFlow { chatModel.chatId.value }
|
snapshotFlow { chatModel.chatId.value }
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.onEach { Log.d(TAG, "TODOCHAT: chatId: activeChatId ${activeChat.value?.id} == new chatId $it ${activeChat.value?.id == it} ") }
|
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
.collect { chatId ->
|
.collect { chatId ->
|
||||||
if (activeChat.value?.id != chatId) {
|
if (activeChat.value?.id != chatId) {
|
||||||
// Redisplay the whole hierarchy if the chat is different to make going from groups to direct chat working correctly
|
// Redisplay the whole hierarchy if the chat is different to make going from groups to direct chat working correctly
|
||||||
// Also for situation when chatId changes after clicking in notification, etc
|
// Also for situation when chatId changes after clicking in notification, etc
|
||||||
activeChat.value = chatModel.getChat(chatId)
|
activeChat.value = chatModel.getChat(chatId)
|
||||||
Log.d(TAG, "TODOCHAT: chatId: activeChatId became ${activeChat.value?.id}")
|
|
||||||
}
|
}
|
||||||
markUnreadChatAsRead(activeChat, chatModel)
|
markUnreadChatAsRead(activeChat, chatModel)
|
||||||
}
|
}
|
||||||
@@ -94,12 +92,10 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.onEach { Log.d(TAG, "TODOCHAT: chats: activeChatId ${activeChat.value?.id} == new chatId ${it?.id} ${activeChat.value?.id == it?.id} ") }
|
|
||||||
// Only changed chatInfo is important thing. Other properties can be skipped for reducing recompositions
|
// Only changed chatInfo is important thing. Other properties can be skipped for reducing recompositions
|
||||||
.filter { it != null && it?.chatInfo != activeChat.value?.chatInfo }
|
.filter { it != null && it.chatInfo != activeChat.value?.chatInfo }
|
||||||
.collect {
|
.collect {
|
||||||
activeChat.value = it
|
activeChat.value = it
|
||||||
Log.d(TAG, "TODOCHAT: chats: activeChatId became ${activeChat.value?.id}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,7 +146,6 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId:
|
|||||||
},
|
},
|
||||||
attachmentOption,
|
attachmentOption,
|
||||||
attachmentBottomSheetState,
|
attachmentBottomSheetState,
|
||||||
chatModel.chatItems,
|
|
||||||
searchText,
|
searchText,
|
||||||
useLinkPreviews = useLinkPreviews,
|
useLinkPreviews = useLinkPreviews,
|
||||||
linkMode = chatModel.simplexLinkMode.value,
|
linkMode = chatModel.simplexLinkMode.value,
|
||||||
@@ -228,19 +223,17 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId:
|
|||||||
loadPrevMessages = {
|
loadPrevMessages = {
|
||||||
if (chatModel.chatId.value != activeChat.value?.id) return@ChatLayout
|
if (chatModel.chatId.value != activeChat.value?.id) return@ChatLayout
|
||||||
val c = chatModel.getChat(chatModel.chatId.value ?: return@ChatLayout)
|
val c = chatModel.getChat(chatModel.chatId.value ?: return@ChatLayout)
|
||||||
val firstId = chatModel.chatItems.firstOrNull()?.id
|
val firstId = chatModel.chatItems.value.firstOrNull()?.id
|
||||||
if (c != null && firstId != null) {
|
if (c != null && firstId != null) {
|
||||||
withBGApi {
|
withBGApi {
|
||||||
Log.d(TAG, "TODOCHAT: loadPrevMessages: loading for ${c.id}, current chatId ${ChatModel.chatId.value}, size was ${ChatModel.chatItems.size}")
|
|
||||||
apiLoadPrevMessages(c, chatModel, firstId, searchText.value)
|
apiLoadPrevMessages(c, chatModel, firstId, searchText.value)
|
||||||
Log.d(TAG, "TODOCHAT: loadPrevMessages: loaded for ${c.id}, current chatId ${ChatModel.chatId.value}, size now ${ChatModel.chatItems.size}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteMessage = { itemId, mode ->
|
deleteMessage = { itemId, mode ->
|
||||||
withBGApi {
|
withBGApi {
|
||||||
val cInfo = chat.chatInfo
|
val cInfo = chat.chatInfo
|
||||||
val toDeleteItem = chatModel.chatItems.firstOrNull { it.id == itemId }
|
val toDeleteItem = chatModel.chatItems.value.firstOrNull { it.id == itemId }
|
||||||
val toModerate = toDeleteItem?.memberToModerate(chat.chatInfo)
|
val toModerate = toDeleteItem?.memberToModerate(chat.chatInfo)
|
||||||
val groupInfo = toModerate?.first
|
val groupInfo = toModerate?.first
|
||||||
val groupMember = toModerate?.second
|
val groupMember = toModerate?.second
|
||||||
@@ -500,7 +493,6 @@ fun ChatLayout(
|
|||||||
composeView: (@Composable () -> Unit),
|
composeView: (@Composable () -> Unit),
|
||||||
attachmentOption: MutableState<AttachmentOption?>,
|
attachmentOption: MutableState<AttachmentOption?>,
|
||||||
attachmentBottomSheetState: ModalBottomSheetState,
|
attachmentBottomSheetState: ModalBottomSheetState,
|
||||||
chatItems: List<ChatItem>,
|
|
||||||
searchValue: State<String>,
|
searchValue: State<String>,
|
||||||
useLinkPreviews: Boolean,
|
useLinkPreviews: Boolean,
|
||||||
linkMode: SimplexLinkMode,
|
linkMode: SimplexLinkMode,
|
||||||
@@ -587,7 +579,7 @@ fun ChatLayout(
|
|||||||
.padding(contentPadding)
|
.padding(contentPadding)
|
||||||
) {
|
) {
|
||||||
ChatItemsList(
|
ChatItemsList(
|
||||||
chat, unreadCount, composeState, chatItems, searchValue,
|
chat, unreadCount, composeState, searchValue,
|
||||||
useLinkPreviews, linkMode, showMemberInfo, loadPrevMessages, deleteMessage, deleteMessages,
|
useLinkPreviews, linkMode, showMemberInfo, loadPrevMessages, deleteMessage, deleteMessages,
|
||||||
receiveFile, cancelFile, joinGroup, acceptCall, acceptFeature, openDirectChat,
|
receiveFile, cancelFile, joinGroup, acceptCall, acceptFeature, openDirectChat,
|
||||||
updateContactStats, updateMemberStats, syncContactConnection, syncMemberConnection, findModelChat, findModelMember,
|
updateContactStats, updateMemberStats, syncContactConnection, syncMemberConnection, findModelChat, findModelMember,
|
||||||
@@ -845,7 +837,6 @@ fun BoxWithConstraintsScope.ChatItemsList(
|
|||||||
chat: Chat,
|
chat: Chat,
|
||||||
unreadCount: State<Int>,
|
unreadCount: State<Int>,
|
||||||
composeState: MutableState<ComposeState>,
|
composeState: MutableState<ComposeState>,
|
||||||
chatItems: List<ChatItem>,
|
|
||||||
searchValue: State<String>,
|
searchValue: State<String>,
|
||||||
useLinkPreviews: Boolean,
|
useLinkPreviews: Boolean,
|
||||||
linkMode: SimplexLinkMode,
|
linkMode: SimplexLinkMode,
|
||||||
@@ -874,7 +865,7 @@ fun BoxWithConstraintsScope.ChatItemsList(
|
|||||||
) {
|
) {
|
||||||
val listState = rememberLazyListState()
|
val listState = rememberLazyListState()
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
ScrollToBottom(chat.id, listState, chatItems)
|
ScrollToBottom(chat.id, listState, chatModel.chatItems)
|
||||||
var prevSearchEmptiness by rememberSaveable { mutableStateOf(searchValue.value.isEmpty()) }
|
var prevSearchEmptiness by rememberSaveable { mutableStateOf(searchValue.value.isEmpty()) }
|
||||||
// Scroll to bottom when search value changes from something to nothing and back
|
// Scroll to bottom when search value changes from something to nothing and back
|
||||||
LaunchedEffect(searchValue.value.isEmpty()) {
|
LaunchedEffect(searchValue.value.isEmpty()) {
|
||||||
@@ -891,7 +882,7 @@ fun BoxWithConstraintsScope.ChatItemsList(
|
|||||||
PreloadItems(listState, ChatPagination.UNTIL_PRELOAD_COUNT, loadPrevMessages)
|
PreloadItems(listState, ChatPagination.UNTIL_PRELOAD_COUNT, loadPrevMessages)
|
||||||
|
|
||||||
Spacer(Modifier.size(8.dp))
|
Spacer(Modifier.size(8.dp))
|
||||||
val reversedChatItems by remember { derivedStateOf { chatItems.reversed().toList() } }
|
val reversedChatItems by remember { derivedStateOf { chatModel.chatItems.asReversed() } }
|
||||||
val maxHeightRounded = with(LocalDensity.current) { maxHeight.roundToPx() }
|
val maxHeightRounded = with(LocalDensity.current) { maxHeight.roundToPx() }
|
||||||
val scrollToItem: (Long) -> Unit = { itemId: Long ->
|
val scrollToItem: (Long) -> Unit = { itemId: Long ->
|
||||||
val index = reversedChatItems.indexOfFirst { it.id == itemId }
|
val index = reversedChatItems.indexOfFirst { it.id == itemId }
|
||||||
@@ -944,7 +935,7 @@ fun BoxWithConstraintsScope.ChatItemsList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val provider = {
|
val provider = {
|
||||||
providerForGallery(i, chatItems, cItem.id) { indexInReversed ->
|
providerForGallery(i, chatModel.chatItems.value, cItem.id) { indexInReversed ->
|
||||||
scope.launch {
|
scope.launch {
|
||||||
listState.scrollToItem(
|
listState.scrollToItem(
|
||||||
kotlin.math.min(reversedChatItems.lastIndex, indexInReversed + 1),
|
kotlin.math.min(reversedChatItems.lastIndex, indexInReversed + 1),
|
||||||
@@ -1067,11 +1058,11 @@ fun BoxWithConstraintsScope.ChatItemsList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FloatingButtons(chatItems, unreadCount, chat.chatStats.minUnreadItemId, searchValue, markRead, setFloatingButton, listState)
|
FloatingButtons(chatModel.chatItems, unreadCount, chat.chatStats.minUnreadItemId, searchValue, markRead, setFloatingButton, listState)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ScrollToBottom(chatId: ChatId, listState: LazyListState, chatItems: List<ChatItem>) {
|
private fun ScrollToBottom(chatId: ChatId, listState: LazyListState, chatItems: State<List<ChatItem>>) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
// Helps to scroll to bottom after moving from Group to Direct chat
|
// Helps to scroll to bottom after moving from Group to Direct chat
|
||||||
// and prevents scrolling to bottom on orientation change
|
// and prevents scrolling to bottom on orientation change
|
||||||
@@ -1089,7 +1080,7 @@ private fun ScrollToBottom(chatId: ChatId, listState: LazyListState, chatItems:
|
|||||||
* When the first visible item (from bottom) is visible (even partially) we can autoscroll to 0 item. Or just scrollBy small distance otherwise
|
* When the first visible item (from bottom) is visible (even partially) we can autoscroll to 0 item. Or just scrollBy small distance otherwise
|
||||||
* */
|
* */
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
snapshotFlow { chatItems.lastOrNull()?.id }
|
snapshotFlow { chatItems.value.lastOrNull()?.id }
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.filter { listState.layoutInfo.visibleItemsInfo.firstOrNull()?.key != it }
|
.filter { listState.layoutInfo.visibleItemsInfo.firstOrNull()?.key != it }
|
||||||
.collect {
|
.collect {
|
||||||
@@ -1112,7 +1103,7 @@ private fun ScrollToBottom(chatId: ChatId, listState: LazyListState, chatItems:
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BoxWithConstraintsScope.FloatingButtons(
|
fun BoxWithConstraintsScope.FloatingButtons(
|
||||||
chatItems: List<ChatItem>,
|
chatItems: State<List<ChatItem>>,
|
||||||
unreadCount: State<Int>,
|
unreadCount: State<Int>,
|
||||||
minUnreadItemId: Long,
|
minUnreadItemId: Long,
|
||||||
searchValue: State<String>,
|
searchValue: State<String>,
|
||||||
@@ -1146,10 +1137,11 @@ fun BoxWithConstraintsScope.FloatingButtons(
|
|||||||
val bottomUnreadCount by remember {
|
val bottomUnreadCount by remember {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
if (unreadCount.value == 0) return@derivedStateOf 0
|
if (unreadCount.value == 0) return@derivedStateOf 0
|
||||||
val from = chatItems.lastIndex - firstVisibleIndex - lastIndexOfVisibleItems
|
val items = chatItems.value
|
||||||
if (chatItems.size <= from || from < 0) return@derivedStateOf 0
|
val from = items.lastIndex - firstVisibleIndex - lastIndexOfVisibleItems
|
||||||
|
if (items.size <= from || from < 0) return@derivedStateOf 0
|
||||||
|
|
||||||
chatItems.subList(from, chatItems.size).count { it.isRcvNew }
|
items.subList(from, items.size).count { it.isRcvNew }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val firstVisibleOffset = (-with(LocalDensity.current) { maxHeight.roundToPx() } * 0.8).toInt()
|
val firstVisibleOffset = (-with(LocalDensity.current) { maxHeight.roundToPx() } * 0.8).toInt()
|
||||||
@@ -1195,7 +1187,7 @@ fun BoxWithConstraintsScope.FloatingButtons(
|
|||||||
painterResource(MR.images.ic_check),
|
painterResource(MR.images.ic_check),
|
||||||
onClick = {
|
onClick = {
|
||||||
markRead(
|
markRead(
|
||||||
CC.ItemRange(minUnreadItemId, chatItems[chatItems.size - listState.layoutInfo.visibleItemsInfo.lastIndex - 1].id - 1),
|
CC.ItemRange(minUnreadItemId, chatItems.value[chatItems.size - listState.layoutInfo.visibleItemsInfo.lastIndex - 1].id - 1),
|
||||||
bottomUnreadCount
|
bottomUnreadCount
|
||||||
)
|
)
|
||||||
showDropDown.value = false
|
showDropDown.value = false
|
||||||
@@ -1500,7 +1492,6 @@ fun PreviewChatLayout() {
|
|||||||
composeView = {},
|
composeView = {},
|
||||||
attachmentOption = remember { mutableStateOf<AttachmentOption?>(null) },
|
attachmentOption = remember { mutableStateOf<AttachmentOption?>(null) },
|
||||||
attachmentBottomSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden),
|
attachmentBottomSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden),
|
||||||
chatItems = chatItems,
|
|
||||||
searchValue,
|
searchValue,
|
||||||
useLinkPreviews = true,
|
useLinkPreviews = true,
|
||||||
linkMode = SimplexLinkMode.DESCRIPTION,
|
linkMode = SimplexLinkMode.DESCRIPTION,
|
||||||
@@ -1573,7 +1564,6 @@ fun PreviewGroupChatLayout() {
|
|||||||
composeView = {},
|
composeView = {},
|
||||||
attachmentOption = remember { mutableStateOf<AttachmentOption?>(null) },
|
attachmentOption = remember { mutableStateOf<AttachmentOption?>(null) },
|
||||||
attachmentBottomSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden),
|
attachmentBottomSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden),
|
||||||
chatItems = chatItems,
|
|
||||||
searchValue,
|
searchValue,
|
||||||
useLinkPreviews = true,
|
useLinkPreviews = true,
|
||||||
linkMode = SimplexLinkMode.DESCRIPTION,
|
linkMode = SimplexLinkMode.DESCRIPTION,
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ fun ComposeView(
|
|||||||
fun loadLinkPreview(url: String, wait: Long? = null) {
|
fun loadLinkPreview(url: String, wait: Long? = null) {
|
||||||
if (pendingLinkUrl.value == url) {
|
if (pendingLinkUrl.value == url) {
|
||||||
composeState.value = composeState.value.copy(preview = ComposePreview.CLinkPreview(null))
|
composeState.value = composeState.value.copy(preview = ComposePreview.CLinkPreview(null))
|
||||||
withLongRunningApi(slow = 30_000, deadlock = 60_000) {
|
withLongRunningApi(slow = 60_000) {
|
||||||
if (wait != null) delay(wait)
|
if (wait != null) delay(wait)
|
||||||
val lp = getLinkPreview(url)
|
val lp = getLinkPreview(url)
|
||||||
if (lp != null && pendingLinkUrl.value == url) {
|
if (lp != null && pendingLinkUrl.value == url) {
|
||||||
@@ -551,7 +551,7 @@ fun ComposeView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun sendMessage(ttl: Int?) {
|
fun sendMessage(ttl: Int?) {
|
||||||
withLongRunningApi(slow = 30_000, deadlock = 60_000) {
|
withLongRunningApi(slow = 120_000) {
|
||||||
sendMessageAsync(null, false, ttl)
|
sendMessageAsync(null, false, ttl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -665,7 +665,7 @@ fun ComposeView(
|
|||||||
|
|
||||||
fun editPrevMessage() {
|
fun editPrevMessage() {
|
||||||
if (composeState.value.contextItem != ComposeContextItem.NoContextItem || composeState.value.preview != ComposePreview.NoPreview) return
|
if (composeState.value.contextItem != ComposeContextItem.NoContextItem || composeState.value.preview != ComposePreview.NoPreview) return
|
||||||
val lastEditable = chatModel.chatItems.findLast { it.meta.editable }
|
val lastEditable = chatModel.chatItems.value.findLast { it.meta.editable }
|
||||||
if (lastEditable != null) {
|
if (lastEditable != null) {
|
||||||
composeState.value = ComposeState(editingItem = lastEditable, useLinkPreviews = useLinkPreviews)
|
composeState.value = ComposeState(editingItem = lastEditable, useLinkPreviews = useLinkPreviews)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ fun AddGroupMembersView(rhId: Long?, groupInfo: GroupInfo, creatingGroup: Boolea
|
|||||||
},
|
},
|
||||||
inviteMembers = {
|
inviteMembers = {
|
||||||
allowModifyMembers = false
|
allowModifyMembers = false
|
||||||
withLongRunningApi(slow = 30_000, deadlock = 120_000) {
|
withLongRunningApi(slow = 120_000) {
|
||||||
for (contactId in selectedContacts) {
|
for (contactId in selectedContacts) {
|
||||||
val member = chatModel.controller.apiAddMember(rhId, groupInfo.groupId, contactId, selectedRole.value)
|
val member = chatModel.controller.apiAddMember(rhId, groupInfo.groupId, contactId, selectedRole.value)
|
||||||
if (member != null) {
|
if (member != null) {
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ fun leaveGroupDialog(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatModel, cl
|
|||||||
text = generalGetString(MR.strings.you_will_stop_receiving_messages_from_this_group_chat_history_will_be_preserved),
|
text = generalGetString(MR.strings.you_will_stop_receiving_messages_from_this_group_chat_history_will_be_preserved),
|
||||||
confirmText = generalGetString(MR.strings.leave_group_button),
|
confirmText = generalGetString(MR.strings.leave_group_button),
|
||||||
onConfirm = {
|
onConfirm = {
|
||||||
withBGApi {
|
withLongRunningApi(60_000) {
|
||||||
chatModel.controller.leaveGroup(rhId, groupInfo.groupId)
|
chatModel.controller.leaveGroup(rhId, groupInfo.groupId)
|
||||||
close?.invoke()
|
close?.invoke()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,9 @@ package chat.simplex.common.views.chat.group
|
|||||||
import InfoRow
|
import InfoRow
|
||||||
import SectionBottomSpacer
|
import SectionBottomSpacer
|
||||||
import SectionDividerSpaced
|
import SectionDividerSpaced
|
||||||
import SectionItemView
|
|
||||||
import SectionSpacer
|
import SectionSpacer
|
||||||
import SectionTextFooter
|
import SectionTextFooter
|
||||||
import SectionView
|
import SectionView
|
||||||
import TextIconSpaced
|
|
||||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.*
|
||||||
@@ -74,9 +72,8 @@ fun GroupMemberInfoView(
|
|||||||
if (chatModel.getContactChat(it) == null) {
|
if (chatModel.getContactChat(it) == null) {
|
||||||
chatModel.addChat(c)
|
chatModel.addChat(c)
|
||||||
}
|
}
|
||||||
chatModel.chatItems.clear()
|
|
||||||
chatModel.chatItemStatuses.clear()
|
chatModel.chatItemStatuses.clear()
|
||||||
chatModel.chatItems.addAll(c.chatItems)
|
chatModel.chatItems.replaceAll(c.chatItems)
|
||||||
chatModel.chatId.value = c.id
|
chatModel.chatId.value = c.id
|
||||||
closeAll()
|
closeAll()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ fun CIFileView(
|
|||||||
FileProtocol.LOCAL -> {}
|
FileProtocol.LOCAL -> {}
|
||||||
}
|
}
|
||||||
file.fileStatus is CIFileStatus.RcvComplete || (file.fileStatus is CIFileStatus.SndStored && file.fileProtocol == FileProtocol.LOCAL) -> {
|
file.fileStatus is CIFileStatus.RcvComplete || (file.fileStatus is CIFileStatus.SndStored && file.fileProtocol == FileProtocol.LOCAL) -> {
|
||||||
withLongRunningApi(slow = 60_000, deadlock = 600_000) {
|
withLongRunningApi(slow = 600_000) {
|
||||||
var filePath = getLoadedFilePath(file)
|
var filePath = getLoadedFilePath(file)
|
||||||
if (chatModel.connectedToRemote() && filePath == null) {
|
if (chatModel.connectedToRemote() && filePath == null) {
|
||||||
file.loadRemoteFile(true)
|
file.loadRemoteFile(true)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ fun CIVideoView(
|
|||||||
val filePath = remember(file, CIFile.cachedRemoteFileRequests.toList()) { mutableStateOf(getLoadedFilePath(file)) }
|
val filePath = remember(file, CIFile.cachedRemoteFileRequests.toList()) { mutableStateOf(getLoadedFilePath(file)) }
|
||||||
if (chatModel.connectedToRemote()) {
|
if (chatModel.connectedToRemote()) {
|
||||||
LaunchedEffect(file) {
|
LaunchedEffect(file) {
|
||||||
withLongRunningApi(slow = 60_000, deadlock = 600_000) {
|
withLongRunningApi(slow = 600_000) {
|
||||||
if (file != null && file.loaded && getLoadedFilePath(file) == null) {
|
if (file != null && file.loaded && getLoadedFilePath(file) == null) {
|
||||||
file.loadRemoteFile(false)
|
file.loadRemoteFile(false)
|
||||||
filePath.value = getLoadedFilePath(file)
|
filePath.value = getLoadedFilePath(file)
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ fun ChatItemView(
|
|||||||
showMenu.value = false
|
showMenu.value = false
|
||||||
}
|
}
|
||||||
if (chatModel.connectedToRemote() && fileSource == null) {
|
if (chatModel.connectedToRemote() && fileSource == null) {
|
||||||
withLongRunningApi(slow = 60_000, deadlock = 600_000) {
|
withLongRunningApi(slow = 600_000) {
|
||||||
cItem.file?.loadRemoteFile(true)
|
cItem.file?.loadRemoteFile(true)
|
||||||
fileSource = getLoadedFileSource(cItem.file)
|
fileSource = getLoadedFileSource(cItem.file)
|
||||||
shareIfExists()
|
shareIfExists()
|
||||||
@@ -527,8 +527,9 @@ fun DeleteItemAction(
|
|||||||
val range = chatViewItemsRange(currIndex, prevHidden)
|
val range = chatViewItemsRange(currIndex, prevHidden)
|
||||||
if (range != null) {
|
if (range != null) {
|
||||||
val itemIds: ArrayList<Long> = arrayListOf()
|
val itemIds: ArrayList<Long> = arrayListOf()
|
||||||
|
val reversedChatItems = chatModel.chatItems.asReversed()
|
||||||
for (i in range) {
|
for (i in range) {
|
||||||
itemIds.add(chatModel.chatItems.asReversed()[i].id)
|
itemIds.add(reversedChatItems[i].id)
|
||||||
}
|
}
|
||||||
deleteMessagesAlertDialog(itemIds, generalGetString(MR.strings.delete_message_mark_deleted_warning), deleteMessages = deleteMessages)
|
deleteMessagesAlertDialog(itemIds, generalGetString(MR.strings.delete_message_mark_deleted_warning), deleteMessages = deleteMessages)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -212,18 +212,15 @@ suspend fun openGroupChat(rhId: Long?, groupId: Long, chatModel: ChatModel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun openChat(rhId: Long?, chatInfo: ChatInfo, chatModel: ChatModel) {
|
suspend fun openChat(rhId: Long?, chatInfo: ChatInfo, chatModel: ChatModel) {
|
||||||
Log.d(TAG, "TODOCHAT: openChat: opening ${chatInfo.id}, current chatId ${ChatModel.chatId.value}, size ${ChatModel.chatItems.size}")
|
|
||||||
val chat = chatModel.controller.apiGetChat(rhId, chatInfo.chatType, chatInfo.apiId)
|
val chat = chatModel.controller.apiGetChat(rhId, chatInfo.chatType, chatInfo.apiId)
|
||||||
if (chat != null) {
|
if (chat != null) {
|
||||||
openLoadedChat(chat, chatModel)
|
openLoadedChat(chat, chatModel)
|
||||||
Log.d(TAG, "TODOCHAT: openChat: opened ${chatInfo.id}, current chatId ${ChatModel.chatId.value}, size ${ChatModel.chatItems.size}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openLoadedChat(chat: Chat, chatModel: ChatModel) {
|
fun openLoadedChat(chat: Chat, chatModel: ChatModel) {
|
||||||
chatModel.chatItems.clear()
|
|
||||||
chatModel.chatItemStatuses.clear()
|
chatModel.chatItemStatuses.clear()
|
||||||
chatModel.chatItems.addAll(chat.chatItems)
|
chatModel.chatItems.replaceAll(chat.chatItems)
|
||||||
chatModel.chatId.value = chat.chatInfo.id
|
chatModel.chatId.value = chat.chatInfo.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,8 +236,7 @@ suspend fun apiFindMessages(ch: Chat, chatModel: ChatModel, search: String) {
|
|||||||
val chatInfo = ch.chatInfo
|
val chatInfo = ch.chatInfo
|
||||||
val chat = chatModel.controller.apiGetChat(ch.remoteHostId, chatInfo.chatType, chatInfo.apiId, search = search) ?: return
|
val chat = chatModel.controller.apiGetChat(ch.remoteHostId, chatInfo.chatType, chatInfo.apiId, search = search) ?: return
|
||||||
if (chatModel.chatId.value != chat.id) return
|
if (chatModel.chatId.value != chat.id) return
|
||||||
chatModel.chatItems.clear()
|
chatModel.chatItems.replaceAll(chat.chatItems)
|
||||||
chatModel.chatItems.addAll(0, chat.chatItems)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun setGroupMembers(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatModel) {
|
suspend fun setGroupMembers(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatModel) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.*
|
import androidx.compose.ui.focus.*
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalClipboardManager
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
@@ -22,6 +23,7 @@ import chat.simplex.common.ui.theme.*
|
|||||||
import chat.simplex.res.MR
|
import chat.simplex.res.MR
|
||||||
import dev.icerock.moko.resources.StringResource
|
import dev.icerock.moko.resources.StringResource
|
||||||
import dev.icerock.moko.resources.compose.painterResource
|
import dev.icerock.moko.resources.compose.painterResource
|
||||||
|
import dev.icerock.moko.resources.compose.stringResource
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
@@ -189,6 +191,7 @@ class AlertManager {
|
|||||||
title: String, text: String? = null,
|
title: String, text: String? = null,
|
||||||
confirmText: String = generalGetString(MR.strings.ok),
|
confirmText: String = generalGetString(MR.strings.ok),
|
||||||
hostDevice: Pair<Long?, String>? = null,
|
hostDevice: Pair<Long?, String>? = null,
|
||||||
|
shareText: Boolean? = null
|
||||||
) {
|
) {
|
||||||
showAlert {
|
showAlert {
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
@@ -202,10 +205,19 @@ class AlertManager {
|
|||||||
delay(200)
|
delay(200)
|
||||||
focusRequester.requestFocus()
|
focusRequester.requestFocus()
|
||||||
}
|
}
|
||||||
|
// Can pass shareText = false to prevent showing Share button if it's needed in a specific case
|
||||||
|
val showShareButton = text != null && (shareText == true || (shareText == null && text.length > 500))
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING),
|
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING),
|
||||||
horizontalArrangement = Arrangement.Center
|
horizontalArrangement = if (showShareButton) Arrangement.SpaceBetween else Arrangement.Center
|
||||||
) {
|
) {
|
||||||
|
val clipboard = LocalClipboardManager.current
|
||||||
|
if (showShareButton && text != null) {
|
||||||
|
TextButton(onClick = {
|
||||||
|
clipboard.shareText(text)
|
||||||
|
hideAlert()
|
||||||
|
}) { Text(stringResource(MR.strings.share_verb)) }
|
||||||
|
}
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
hideAlert()
|
hideAlert()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class ProcessedErrors <T: AgentErrorType>(val interval: Long) {
|
|||||||
|
|
||||||
fun newError(error: T, offerRestart: Boolean) {
|
fun newError(error: T, offerRestart: Boolean) {
|
||||||
timer.cancel()
|
timer.cancel()
|
||||||
timer = withLongRunningApi(slow = 70_000, deadlock = 130_000) {
|
timer = withLongRunningApi(slow = 130_000) {
|
||||||
val delayBeforeNext = (lastShownTimestamp + interval) - System.currentTimeMillis()
|
val delayBeforeNext = (lastShownTimestamp + interval) - System.currentTimeMillis()
|
||||||
if ((lastShownOfferRestart || !offerRestart) && delayBeforeNext >= 0) {
|
if ((lastShownOfferRestart || !offerRestart) && delayBeforeNext >= 0) {
|
||||||
delay(delayBeforeNext)
|
delay(delayBeforeNext)
|
||||||
|
|||||||
@@ -37,30 +37,22 @@ fun withBGApi(action: suspend CoroutineScope.() -> Unit): Job =
|
|||||||
CoroutineScope(singleThreadDispatcher).launch(block = { wrapWithLogging(action, it) })
|
CoroutineScope(singleThreadDispatcher).launch(block = { wrapWithLogging(action, it) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fun withLongRunningApi(slow: Long = Long.MAX_VALUE, deadlock: Long = Long.MAX_VALUE, action: suspend CoroutineScope.() -> Unit): Job =
|
fun withLongRunningApi(slow: Long = Long.MAX_VALUE, action: suspend CoroutineScope.() -> Unit): Job =
|
||||||
Exception().let {
|
Exception().let {
|
||||||
CoroutineScope(Dispatchers.Default).launch(block = { wrapWithLogging(action, it, slow = slow, deadlock = deadlock) })
|
CoroutineScope(Dispatchers.Default).launch(block = { wrapWithLogging(action, it, slow = slow) })
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun wrapWithLogging(action: suspend CoroutineScope.() -> Unit, exception: java.lang.Exception, slow: Long = 10_000, deadlock: Long = 60_000) = coroutineScope {
|
private suspend fun wrapWithLogging(action: suspend CoroutineScope.() -> Unit, exception: java.lang.Exception, slow: Long = 20_000) = coroutineScope {
|
||||||
val start = System.currentTimeMillis()
|
val start = System.currentTimeMillis()
|
||||||
val job = launch {
|
|
||||||
delay(deadlock)
|
|
||||||
Log.e(TAG, "Possible deadlock of the thread, not finished after ${deadlock / 1000}s:\n${exception.stackTraceToString()}")
|
|
||||||
AlertManager.shared.showAlertMsg(
|
|
||||||
title = generalGetString(MR.strings.possible_deadlock_title),
|
|
||||||
text = generalGetString(MR.strings.possible_deadlock_desc).format(deadlock / 1000, exception.stackTraceToString()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
action()
|
action()
|
||||||
job.cancel()
|
val end = System.currentTimeMillis()
|
||||||
if (appPreferences.developerTools.get() && appPreferences.showSlowApiCalls.get()) {
|
if (end - start > slow) {
|
||||||
val end = System.currentTimeMillis()
|
Log.e(TAG, "Possible problem with execution of the thread, took ${(end - start) / 1000}s:\n${exception.stackTraceToString()}")
|
||||||
if (end - start > slow) {
|
if (appPreferences.developerTools.get() && appPreferences.showSlowApiCalls.get()) {
|
||||||
Log.e(TAG, "Possible problem with execution of the thread, took ${(end - start) / 1000}s:\n${exception.stackTraceToString()}")
|
|
||||||
AlertManager.shared.showAlertMsg(
|
AlertManager.shared.showAlertMsg(
|
||||||
title = generalGetString(MR.strings.possible_slow_function_title),
|
title = generalGetString(MR.strings.possible_slow_function_title),
|
||||||
text = generalGetString(MR.strings.possible_slow_function_desc).format((end - start) / 1000, exception.stackTraceToString()),
|
text = generalGetString(MR.strings.possible_slow_function_desc).format((end - start) / 1000, exception.stackTraceToString()),
|
||||||
|
shareText = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ fun PrivacySettingsView(
|
|||||||
val currentUser = chatModel.currentUser.value
|
val currentUser = chatModel.currentUser.value
|
||||||
if (currentUser != null) {
|
if (currentUser != null) {
|
||||||
fun setSendReceiptsContacts(enable: Boolean, clearOverrides: Boolean) {
|
fun setSendReceiptsContacts(enable: Boolean, clearOverrides: Boolean) {
|
||||||
withLongRunningApi(slow = 30_000, deadlock = 60_000) {
|
withLongRunningApi(slow = 60_000) {
|
||||||
val mrs = UserMsgReceiptSettings(enable, clearOverrides)
|
val mrs = UserMsgReceiptSettings(enable, clearOverrides)
|
||||||
chatModel.controller.apiSetUserContactReceipts(currentUser, mrs)
|
chatModel.controller.apiSetUserContactReceipts(currentUser, mrs)
|
||||||
chatModel.controller.appPrefs.privacyDeliveryReceiptsSet.set(true)
|
chatModel.controller.appPrefs.privacyDeliveryReceiptsSet.set(true)
|
||||||
@@ -119,7 +119,7 @@ fun PrivacySettingsView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setSendReceiptsGroups(enable: Boolean, clearOverrides: Boolean) {
|
fun setSendReceiptsGroups(enable: Boolean, clearOverrides: Boolean) {
|
||||||
withLongRunningApi(slow = 30_000, deadlock = 60_000) {
|
withLongRunningApi(slow = 60_000) {
|
||||||
val mrs = UserMsgReceiptSettings(enable, clearOverrides)
|
val mrs = UserMsgReceiptSettings(enable, clearOverrides)
|
||||||
chatModel.controller.apiSetUserGroupReceipts(currentUser, mrs)
|
chatModel.controller.apiSetUserGroupReceipts(currentUser, mrs)
|
||||||
chatModel.controller.appPrefs.privacyDeliveryReceiptsSet.set(true)
|
chatModel.controller.appPrefs.privacyDeliveryReceiptsSet.set(true)
|
||||||
|
|||||||
@@ -1588,8 +1588,6 @@
|
|||||||
<string name="remote_ctrl_error_busy">سطح المكتب مشغول</string>
|
<string name="remote_ctrl_error_busy">سطح المكتب مشغول</string>
|
||||||
<string name="remote_ctrl_error_bad_version">يحتوي سطح المكتب على إصدار غير مدعوم. يُرجى التأكد من استخدام نفس الإصدار على كلا الجهازين</string>
|
<string name="remote_ctrl_error_bad_version">يحتوي سطح المكتب على إصدار غير مدعوم. يُرجى التأكد من استخدام نفس الإصدار على كلا الجهازين</string>
|
||||||
<string name="past_member_vName">العضو السابق %1$s</string>
|
<string name="past_member_vName">العضو السابق %1$s</string>
|
||||||
<string name="possible_deadlock_title">مأزق</string>
|
|
||||||
<string name="possible_deadlock_desc">يستغرق تنفيذ التعليمات البرمجية وقتًا طويلاً جدًا: %1$d ثانية. من المحتمل أن التطبيق مجمّد: %2$s</string>
|
|
||||||
<string name="possible_slow_function_title">وظيفة بطيئة</string>
|
<string name="possible_slow_function_title">وظيفة بطيئة</string>
|
||||||
<string name="developer_options_section">خيارات المطور</string>
|
<string name="developer_options_section">خيارات المطور</string>
|
||||||
<string name="profile_update_event_member_name_changed">تغيّر العضو %1$s إلى %2$s</string>
|
<string name="profile_update_event_member_name_changed">تغيّر العضو %1$s إلى %2$s</string>
|
||||||
|
|||||||
@@ -147,8 +147,6 @@
|
|||||||
<string name="smp_server_test_delete_file">Delete file</string>
|
<string name="smp_server_test_delete_file">Delete file</string>
|
||||||
<string name="error_deleting_user">Error deleting user profile</string>
|
<string name="error_deleting_user">Error deleting user profile</string>
|
||||||
<string name="error_updating_user_privacy">Error updating user privacy</string>
|
<string name="error_updating_user_privacy">Error updating user privacy</string>
|
||||||
<string name="possible_deadlock_title">Deadlock</string>
|
|
||||||
<string name="possible_deadlock_desc">Execution of code takes too long time: %1$d seconds. Probably, the app is frozen: %2$s</string>
|
|
||||||
<string name="possible_slow_function_title">Slow function</string>
|
<string name="possible_slow_function_title">Slow function</string>
|
||||||
<string name="possible_slow_function_desc">Execution of function takes too long time: %1$d seconds: %2$s</string>
|
<string name="possible_slow_function_desc">Execution of function takes too long time: %1$d seconds: %2$s</string>
|
||||||
|
|
||||||
|
|||||||
@@ -1555,7 +1555,6 @@
|
|||||||
<string name="chat_is_stopped_you_should_transfer_database">Чатът е спрян. Ако вече сте използвали тази база данни на друго устройство, трябва да я прехвърлите обратно, преди да стартирате чата отново.</string>
|
<string name="chat_is_stopped_you_should_transfer_database">Чатът е спрян. Ако вече сте използвали тази база данни на друго устройство, трябва да я прехвърлите обратно, преди да стартирате чата отново.</string>
|
||||||
<string name="remote_ctrl_error_bad_invitation">Настолното устройство има грешен код за връзка</string>
|
<string name="remote_ctrl_error_bad_invitation">Настолното устройство има грешен код за връзка</string>
|
||||||
<string name="remote_ctrl_error_bad_version">Настолното устройство е с неподдържана версия. Моля, уверете се, че използвате една и съща версия и на двете устройства</string>
|
<string name="remote_ctrl_error_bad_version">Настолното устройство е с неподдържана версия. Моля, уверете се, че използвате една и съща версия и на двете устройства</string>
|
||||||
<string name="possible_deadlock_desc">Изпълнението на кода отнема твърде много време: %1$d секунди. Вероятно приложението е замразено: %2$s</string>
|
|
||||||
<string name="possible_slow_function_title">Бавна функция</string>
|
<string name="possible_slow_function_title">Бавна функция</string>
|
||||||
<string name="possible_slow_function_desc">Изпълнението на функцията отнема твърде много време: %1$d секунди: %2$s</string>
|
<string name="possible_slow_function_desc">Изпълнението на функцията отнема твърде много време: %1$d секунди: %2$s</string>
|
||||||
<string name="show_internal_errors">Покажи вътрешните грешки</string>
|
<string name="show_internal_errors">Покажи вътрешните грешки</string>
|
||||||
@@ -1591,5 +1590,4 @@
|
|||||||
\nПрепоръчително е да рестартирате приложението.</string>
|
\nПрепоръчително е да рестартирате приложението.</string>
|
||||||
<string name="developer_options_section">Опции за разработчици</string>
|
<string name="developer_options_section">Опции за разработчици</string>
|
||||||
<string name="show_slow_api_calls">Показване на бавни API заявки</string>
|
<string name="show_slow_api_calls">Показване на бавни API заявки</string>
|
||||||
<string name="possible_deadlock_title">Грешка в заключено положение</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1672,9 +1672,7 @@
|
|||||||
<string name="possible_slow_function_title">Langsame Funktion</string>
|
<string name="possible_slow_function_title">Langsame Funktion</string>
|
||||||
<string name="show_slow_api_calls">Zeige langsame API-Aufrufe an</string>
|
<string name="show_slow_api_calls">Zeige langsame API-Aufrufe an</string>
|
||||||
<string name="group_member_status_unknown_short">unbekannt</string>
|
<string name="group_member_status_unknown_short">unbekannt</string>
|
||||||
<string name="possible_deadlock_title">Blockade</string>
|
|
||||||
<string name="developer_options_section">Optionen für Entwickler</string>
|
<string name="developer_options_section">Optionen für Entwickler</string>
|
||||||
<string name="possible_deadlock_desc">Die Code-Ausführung dauert zu lange: %1$d Sekunden. Wahrscheinlich ist die App eingefroren: %2$s</string>
|
|
||||||
<string name="group_member_status_unknown">unbekannter Gruppenmitglieds-Status</string>
|
<string name="group_member_status_unknown">unbekannter Gruppenmitglieds-Status</string>
|
||||||
<string name="v5_5_private_notes_descr">Mit verschlüsselten Dateien und Medien.</string>
|
<string name="v5_5_private_notes_descr">Mit verschlüsselten Dateien und Medien.</string>
|
||||||
<string name="v5_5_private_notes">Private Notizen</string>
|
<string name="v5_5_private_notes">Private Notizen</string>
|
||||||
|
|||||||
@@ -1559,11 +1559,9 @@
|
|||||||
<string name="remote_host_error_bad_state"><![CDATA[État médiocre de la connexion au mobile <b>%s</b>.]]></string>
|
<string name="remote_host_error_bad_state"><![CDATA[État médiocre de la connexion au mobile <b>%s</b>.]]></string>
|
||||||
<string name="remote_ctrl_was_disconnected_title">Connexion interrompue</string>
|
<string name="remote_ctrl_was_disconnected_title">Connexion interrompue</string>
|
||||||
<string name="remote_ctrl_error_bad_state">État médiocre de la connexion avec le bureau</string>
|
<string name="remote_ctrl_error_bad_state">État médiocre de la connexion avec le bureau</string>
|
||||||
<string name="possible_deadlock_title">Impasse</string>
|
|
||||||
<string name="remote_ctrl_error_bad_version">La version de l\'ordinateur de bureau n\'est pas prise en charge. Veillez à utiliser la même version sur les deux appareils.</string>
|
<string name="remote_ctrl_error_bad_version">La version de l\'ordinateur de bureau n\'est pas prise en charge. Veillez à utiliser la même version sur les deux appareils.</string>
|
||||||
<string name="remote_ctrl_error_disconnected">Le bureau a été déconnecté</string>
|
<string name="remote_ctrl_error_disconnected">Le bureau a été déconnecté</string>
|
||||||
<string name="developer_options_section">Options pour les développeurs</string>
|
<string name="developer_options_section">Options pour les développeurs</string>
|
||||||
<string name="possible_deadlock_desc">Le code prend trop de temps à s\'exécuter : %1$d secondes. Il est probable que l\'application soit figée : %2$s</string>
|
|
||||||
<string name="agent_internal_error_title">Erreur interne</string>
|
<string name="agent_internal_error_title">Erreur interne</string>
|
||||||
<string name="remote_host_error_bad_version"><![CDATA[La version du mobile <b>%s</b> n\'est pas prise en charge. Veillez à utiliser la même version sur les deux appareils.]]></string>
|
<string name="remote_host_error_bad_version"><![CDATA[La version du mobile <b>%s</b> n\'est pas prise en charge. Veillez à utiliser la même version sur les deux appareils.]]></string>
|
||||||
<string name="show_internal_errors">Afficher les erreurs internes</string>
|
<string name="show_internal_errors">Afficher les erreurs internes</string>
|
||||||
|
|||||||
@@ -1583,9 +1583,7 @@
|
|||||||
<string name="possible_slow_function_title">Lassú funkció</string>
|
<string name="possible_slow_function_title">Lassú funkció</string>
|
||||||
<string name="show_slow_api_calls">Lassú API-hívások megjelenítése</string>
|
<string name="show_slow_api_calls">Lassú API-hívások megjelenítése</string>
|
||||||
<string name="remote_host_error_inactive"><![CDATA[A(z) <b>%s</b> mobil eszköz inaktív]]></string>
|
<string name="remote_host_error_inactive"><![CDATA[A(z) <b>%s</b> mobil eszköz inaktív]]></string>
|
||||||
<string name="possible_deadlock_title">Elakadt</string>
|
|
||||||
<string name="developer_options_section">Fejlesztői beállítások</string>
|
<string name="developer_options_section">Fejlesztői beállítások</string>
|
||||||
<string name="possible_deadlock_desc">A kód végrehajtása túl sokáig tart: %1$d másodperc. Valószínűleg az alkalmazás lefagyott: %2$s</string>
|
|
||||||
<string name="possible_slow_function_desc">A funkció végrehajtása túl sokáig tart: %1$d másodperc: %2$s</string>
|
<string name="possible_slow_function_desc">A funkció végrehajtása túl sokáig tart: %1$d másodperc: %2$s</string>
|
||||||
<string name="remote_host_error_busy"><![CDATA[A(z) <b>%s</b> mobil eszköz elfoglalt]]></string>
|
<string name="remote_host_error_busy"><![CDATA[A(z) <b>%s</b> mobil eszköz elfoglalt]]></string>
|
||||||
<string name="past_member_vName">Legutóbbi tag %1$s</string>
|
<string name="past_member_vName">Legutóbbi tag %1$s</string>
|
||||||
|
|||||||
@@ -1591,9 +1591,7 @@
|
|||||||
<string name="possible_slow_function_title">Funzione lenta</string>
|
<string name="possible_slow_function_title">Funzione lenta</string>
|
||||||
<string name="show_slow_api_calls">Mostra chiamate API lente</string>
|
<string name="show_slow_api_calls">Mostra chiamate API lente</string>
|
||||||
<string name="group_member_status_unknown_short">sconosciuto</string>
|
<string name="group_member_status_unknown_short">sconosciuto</string>
|
||||||
<string name="possible_deadlock_desc">L\'esecuzione del codice impiega troppo tempo: %1$d secondi. Probabilmente l\'app è congelata: %2$s</string>
|
|
||||||
<string name="group_member_status_unknown">stato sconosciuto</string>
|
<string name="group_member_status_unknown">stato sconosciuto</string>
|
||||||
<string name="possible_deadlock_title">Stallo</string>
|
|
||||||
<string name="developer_options_section">Opzioni sviluppatore</string>
|
<string name="developer_options_section">Opzioni sviluppatore</string>
|
||||||
<string name="v5_5_private_notes">Note private</string>
|
<string name="v5_5_private_notes">Note private</string>
|
||||||
<string name="v5_5_new_interface_languages">Interfaccia in ungherese e turco</string>
|
<string name="v5_5_new_interface_languages">Interfaccia in ungherese e turco</string>
|
||||||
|
|||||||
@@ -1571,9 +1571,7 @@
|
|||||||
<string name="remote_ctrl_error_busy">PC版が処理中</string>
|
<string name="remote_ctrl_error_busy">PC版が処理中</string>
|
||||||
<string name="remote_ctrl_error_disconnected">PC版が切断されました</string>
|
<string name="remote_ctrl_error_disconnected">PC版が切断されました</string>
|
||||||
<string name="remote_ctrl_error_bad_version">ご利用のPC版のバージョンがサポートされてません。両端末が同じバージョンかどうか、ご確認ください。</string>
|
<string name="remote_ctrl_error_bad_version">ご利用のPC版のバージョンがサポートされてません。両端末が同じバージョンかどうか、ご確認ください。</string>
|
||||||
<string name="possible_deadlock_title">デッドロック状態</string>
|
|
||||||
<string name="developer_options_section">開発者向けの設定</string>
|
<string name="developer_options_section">開発者向けの設定</string>
|
||||||
<string name="possible_deadlock_desc">処理時間が異常にかかるようです: %1$d 秒。アプリが固まった恐れがあります: %2$s</string>
|
|
||||||
<string name="remote_host_error_busy"><![CDATA[携帯版 <b>%s</b> がただいま処理中]]></string>
|
<string name="remote_host_error_busy"><![CDATA[携帯版 <b>%s</b> がただいま処理中]]></string>
|
||||||
<string name="possible_slow_function_desc">機能の処理時間が以上にかかってます: %1$d 秒: %2$s</string>
|
<string name="possible_slow_function_desc">機能の処理時間が以上にかかってます: %1$d 秒: %2$s</string>
|
||||||
<string name="show_internal_errors">内部エラーを表示</string>
|
<string name="show_internal_errors">内部エラーを表示</string>
|
||||||
|
|||||||
@@ -1574,7 +1574,6 @@
|
|||||||
<string name="remote_host_error_missing"><![CDATA[Mobiel <b>%s</b> ontbreekt]]></string>
|
<string name="remote_host_error_missing"><![CDATA[Mobiel <b>%s</b> ontbreekt]]></string>
|
||||||
<string name="remote_host_error_bad_state"><![CDATA[De verbinding met de mobiel <b>%s</b> is in slechte staat]]></string>
|
<string name="remote_host_error_bad_state"><![CDATA[De verbinding met de mobiel <b>%s</b> is in slechte staat]]></string>
|
||||||
<string name="remote_ctrl_error_disconnected">De verbinding met desktop is verbroken</string>
|
<string name="remote_ctrl_error_disconnected">De verbinding met desktop is verbroken</string>
|
||||||
<string name="possible_deadlock_title">Impasse</string>
|
|
||||||
<string name="possible_slow_function_desc">Uitvoering van functie duurt te lang: %1$d seconden: %2$s</string>
|
<string name="possible_slow_function_desc">Uitvoering van functie duurt te lang: %1$d seconden: %2$s</string>
|
||||||
<string name="possible_slow_function_title">Langzame functie</string>
|
<string name="possible_slow_function_title">Langzame functie</string>
|
||||||
<string name="developer_options_section">Ontwikkelaars opties</string>
|
<string name="developer_options_section">Ontwikkelaars opties</string>
|
||||||
@@ -1588,7 +1587,6 @@
|
|||||||
<string name="restart_chat_button">Chat opnieuw starten</string>
|
<string name="restart_chat_button">Chat opnieuw starten</string>
|
||||||
<string name="remote_host_error_timeout"><![CDATA[Time-out bereikt tijdens het verbinden met de mobiel <b>%s</b>]]></string>
|
<string name="remote_host_error_timeout"><![CDATA[Time-out bereikt tijdens het verbinden met de mobiel <b>%s</b>]]></string>
|
||||||
<string name="remote_ctrl_error_bad_state">De verbinding met de desktop is in slechte staat</string>
|
<string name="remote_ctrl_error_bad_state">De verbinding met de desktop is in slechte staat</string>
|
||||||
<string name="possible_deadlock_desc">Het uitvoeren van de code duurt te lang: %1$d seconden. Waarschijnlijk is de app vastgelopen: %2$s</string>
|
|
||||||
<string name="remote_ctrl_error_bad_invitation">Desktop heeft verkeerde uitnodigingscode</string>
|
<string name="remote_ctrl_error_bad_invitation">Desktop heeft verkeerde uitnodigingscode</string>
|
||||||
<string name="remote_host_error_bad_version"><![CDATA[Mobiel <b>%s</b> heeft een niet-ondersteunde versie. Zorg ervoor dat u op beide apparaten dezelfde versie gebruikt]]></string>
|
<string name="remote_host_error_bad_version"><![CDATA[Mobiel <b>%s</b> heeft een niet-ondersteunde versie. Zorg ervoor dat u op beide apparaten dezelfde versie gebruikt]]></string>
|
||||||
<string name="remote_ctrl_error_timeout">Time-out bereikt tijdens het verbinden met de desktop</string>
|
<string name="remote_ctrl_error_timeout">Time-out bereikt tijdens het verbinden met de desktop</string>
|
||||||
|
|||||||
@@ -1606,7 +1606,6 @@
|
|||||||
<string name="remote_ctrl_error_bad_version">Komputer ma niewspieraną wersję. Proszę upewnić się, że używasz tych samych wersji na obu urządzeniach</string>
|
<string name="remote_ctrl_error_bad_version">Komputer ma niewspieraną wersję. Proszę upewnić się, że używasz tych samych wersji na obu urządzeniach</string>
|
||||||
<string name="blocked_by_admin_items_description">%d wiadomości zablokowanych przez admina</string>
|
<string name="blocked_by_admin_items_description">%d wiadomości zablokowanych przez admina</string>
|
||||||
<string name="error_creating_message">Błąd tworzenia wiadomości</string>
|
<string name="error_creating_message">Błąd tworzenia wiadomości</string>
|
||||||
<string name="possible_deadlock_desc">Wykonanie kodu zajmuje za dużo czasu: %1$d sekund. Prawdopodobnie aplikacja jest zamrożona: %2$s</string>
|
|
||||||
<string name="possible_slow_function_desc">Wykonanie kodu zajmuje za dużo czasu: %1$d sekund: %2$s</string>
|
<string name="possible_slow_function_desc">Wykonanie kodu zajmuje za dużo czasu: %1$d sekund: %2$s</string>
|
||||||
<string name="note_folder_local_display_name">Prywatne notatki</string>
|
<string name="note_folder_local_display_name">Prywatne notatki</string>
|
||||||
<string name="group_member_status_unknown">nieznany status</string>
|
<string name="group_member_status_unknown">nieznany status</string>
|
||||||
@@ -1621,7 +1620,6 @@
|
|||||||
<string name="remote_host_error_inactive"><![CDATA[Telefon <b>%s</b> jest nieaktywny]]></string>
|
<string name="remote_host_error_inactive"><![CDATA[Telefon <b>%s</b> jest nieaktywny]]></string>
|
||||||
<string name="remote_host_error_bad_version"><![CDATA[Telefon <b>%s</b> ma niewspieraną wersję. Proszę, upewnij się, że używasz tej samej wersji na obydwu urządzeniach]]></string>
|
<string name="remote_host_error_bad_version"><![CDATA[Telefon <b>%s</b> ma niewspieraną wersję. Proszę, upewnij się, że używasz tej samej wersji na obydwu urządzeniach]]></string>
|
||||||
<string name="group_member_status_unknown_short">nieznany</string>
|
<string name="group_member_status_unknown_short">nieznany</string>
|
||||||
<string name="possible_deadlock_title">Blokada</string>
|
|
||||||
<string name="profile_update_event_contact_name_changed">kontakt %1$s zmieniony na %2$s</string>
|
<string name="profile_update_event_contact_name_changed">kontakt %1$s zmieniony na %2$s</string>
|
||||||
<string name="profile_update_event_removed_address">usunięto adres kontaktu</string>
|
<string name="profile_update_event_removed_address">usunięto adres kontaktu</string>
|
||||||
<string name="profile_update_event_removed_picture">usunięto zdjęcie profilu</string>
|
<string name="profile_update_event_removed_picture">usunięto zdjęcie profilu</string>
|
||||||
|
|||||||
@@ -1680,8 +1680,6 @@
|
|||||||
<string name="error_showing_message">ошибка отображения сообщения</string>
|
<string name="error_showing_message">ошибка отображения сообщения</string>
|
||||||
<string name="error_showing_content">ошибка отображения содержания</string>
|
<string name="error_showing_content">ошибка отображения содержания</string>
|
||||||
<string name="remote_ctrl_disconnected_with_reason">Отсоединён по причине: %s</string>
|
<string name="remote_ctrl_disconnected_with_reason">Отсоединён по причине: %s</string>
|
||||||
<string name="possible_deadlock_title">Взаимная блокировка</string>
|
|
||||||
<string name="possible_deadlock_desc">Выполнение задачи занимает долгое время: %1$d секунд. Возможно, приложение заблокировано: %2$s</string>
|
|
||||||
<string name="possible_slow_function_desc">Выполнение задачи занимает долгое время: %1$d секунд: %2$s</string>
|
<string name="possible_slow_function_desc">Выполнение задачи занимает долгое время: %1$d секунд: %2$s</string>
|
||||||
<string name="possible_slow_function_title">Медленный вызов</string>
|
<string name="possible_slow_function_title">Медленный вызов</string>
|
||||||
<string name="profile_update_event_contact_name_changed">контакт %1$s изменён на %2$s</string>
|
<string name="profile_update_event_contact_name_changed">контакт %1$s изменён на %2$s</string>
|
||||||
|
|||||||
@@ -1586,8 +1586,6 @@
|
|||||||
<string name="remote_host_error_bad_state"><![CDATA[到移动主机 <b>%s</b>的连接状态不佳]]></string>
|
<string name="remote_host_error_bad_state"><![CDATA[到移动主机 <b>%s</b>的连接状态不佳]]></string>
|
||||||
<string name="remote_host_error_timeout"><![CDATA[连接到移动主机<b>%s</b>时超时]]></string>
|
<string name="remote_host_error_timeout"><![CDATA[连接到移动主机<b>%s</b>时超时]]></string>
|
||||||
<string name="failed_to_create_user_invalid_desc">显示名无效。请另选一个名称。</string>
|
<string name="failed_to_create_user_invalid_desc">显示名无效。请另选一个名称。</string>
|
||||||
<string name="possible_deadlock_title">死锁</string>
|
|
||||||
<string name="possible_deadlock_desc">代码执行花费的时间过久:%1$d秒。应用可能卡住了:%2$s</string>
|
|
||||||
<string name="possible_slow_function_title">慢函数</string>
|
<string name="possible_slow_function_title">慢函数</string>
|
||||||
<string name="show_slow_api_calls">显示缓慢的 API 调用</string>
|
<string name="show_slow_api_calls">显示缓慢的 API 调用</string>
|
||||||
<string name="past_member_vName">过往成员 %1$s</string>
|
<string name="past_member_vName">过往成员 %1$s</string>
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ import androidx.compose.ui.input.key.*
|
|||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.*
|
import androidx.compose.ui.window.*
|
||||||
import chat.simplex.common.model.ChatController
|
import chat.simplex.common.model.*
|
||||||
import chat.simplex.common.model.ChatModel
|
|
||||||
import chat.simplex.common.platform.*
|
import chat.simplex.common.platform.*
|
||||||
import chat.simplex.common.ui.theme.DEFAULT_START_MODAL_WIDTH
|
import chat.simplex.common.ui.theme.DEFAULT_START_MODAL_WIDTH
|
||||||
import chat.simplex.common.ui.theme.SimpleXTheme
|
import chat.simplex.common.ui.theme.SimpleXTheme
|
||||||
@@ -40,7 +39,8 @@ fun showApp() {
|
|||||||
WindowExceptionHandler { e ->
|
WindowExceptionHandler { e ->
|
||||||
AlertManager.shared.showAlertMsg(
|
AlertManager.shared.showAlertMsg(
|
||||||
title = generalGetString(MR.strings.app_was_crashed),
|
title = generalGetString(MR.strings.app_was_crashed),
|
||||||
text = e.stackTraceToString()
|
text = e.stackTraceToString(),
|
||||||
|
shareText = true
|
||||||
)
|
)
|
||||||
Log.e(TAG, "App crashed, thread name: " + Thread.currentThread().name + ", exception: " + e.stackTraceToString())
|
Log.e(TAG, "App crashed, thread name: " + Thread.currentThread().name + ", exception: " + e.stackTraceToString())
|
||||||
window.dispatchEvent(WindowEvent(window, WindowEvent.WINDOW_CLOSING))
|
window.dispatchEvent(WindowEvent(window, WindowEvent.WINDOW_CLOSING))
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ actual fun SaveContentItemAction(cItem: ChatItem, saveFileLauncher: FileChooserL
|
|||||||
}
|
}
|
||||||
var fileSource = getLoadedFileSource(cItem.file)
|
var fileSource = getLoadedFileSource(cItem.file)
|
||||||
if (chatModel.connectedToRemote() && fileSource == null) {
|
if (chatModel.connectedToRemote() && fileSource == null) {
|
||||||
withLongRunningApi(slow = 60_000, deadlock = 600_000) {
|
withLongRunningApi(slow = 600_000) {
|
||||||
cItem.file?.loadRemoteFile(true)
|
cItem.file?.loadRemoteFile(true)
|
||||||
fileSource = getLoadedFileSource(cItem.file)
|
fileSource = getLoadedFileSource(cItem.file)
|
||||||
saveIfExists()
|
saveIfExists()
|
||||||
@@ -51,7 +51,7 @@ actual fun SaveContentItemAction(cItem: ChatItem, saveFileLauncher: FileChooserL
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun copyItemToClipboard(cItem: ChatItem, clipboard: ClipboardManager) = withLongRunningApi(slow = 60_000, deadlock = 600_000) {
|
actual fun copyItemToClipboard(cItem: ChatItem, clipboard: ClipboardManager) = withLongRunningApi(slow = 600_000) {
|
||||||
var fileSource = getLoadedFileSource(cItem.file)
|
var fileSource = getLoadedFileSource(cItem.file)
|
||||||
if (chatModel.connectedToRemote() && fileSource == null) {
|
if (chatModel.connectedToRemote() && fileSource == null) {
|
||||||
cItem.file?.loadRemoteFile(true)
|
cItem.file?.loadRemoteFile(true)
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ android.nonTransitiveRClass=true
|
|||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
kotlin.mpp.androidSourceSetLayoutVersion=2
|
kotlin.mpp.androidSourceSetLayoutVersion=2
|
||||||
|
|
||||||
android.version_name=5.5
|
android.version_name=5.5.4
|
||||||
android.version_code=175
|
android.version_code=183
|
||||||
|
|
||||||
desktop.version_name=5.5
|
desktop.version_name=5.5.4
|
||||||
desktop.version_code=26
|
desktop.version_code=30
|
||||||
|
|
||||||
kotlin.version=1.8.20
|
kotlin.version=1.8.20
|
||||||
gradle.plugin.version=7.4.2
|
gradle.plugin.version=7.4.2
|
||||||
|
|||||||
@@ -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: 7a0cd8041bbb7d7ab2f089395a244dc4af0f9e3b
|
tag: e64b6cba4b7e4107f78ae596ab2a6a28ef24ff78
|
||||||
|
|
||||||
source-repository-package
|
source-repository-package
|
||||||
type: git
|
type: git
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
---
|
---
|
||||||
title: Download SimpleX apps
|
title: Download SimpleX apps
|
||||||
permalink: /downloads/index.html
|
permalink: /downloads/index.html
|
||||||
revision: 25.11.2023
|
revision: 11.02.2024
|
||||||
---
|
---
|
||||||
|
|
||||||
| Updated 25.11.2023 | Languages: EN |
|
| Updated 11.02.2024 | Languages: EN |
|
||||||
# Download SimpleX apps
|
# Download SimpleX apps
|
||||||
|
|
||||||
The latest stable version is v5.5.
|
The latest stable version is v5.5.3.
|
||||||
|
|
||||||
You can get the latest beta releases from [GitHub](https://github.com/simplex-chat/simplex-chat/releases).
|
You can get the latest beta releases from [GitHub](https://github.com/simplex-chat/simplex-chat/releases).
|
||||||
|
|
||||||
@@ -21,24 +21,24 @@ You can get the latest beta releases from [GitHub](https://github.com/simplex-ch
|
|||||||
|
|
||||||
Using the same profile as on mobile device is not yet supported – you need to create a separate profile to use desktop apps.
|
Using the same profile as on mobile device is not yet supported – you need to create a separate profile to use desktop apps.
|
||||||
|
|
||||||
**Linux**: [AppImage](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex-desktop-x86_64.AppImage) (most Linux distros), [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex-desktop-ubuntu-20_04-x86_64.deb) (and Debian-based distros), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex-desktop-ubuntu-22_04-x86_64.deb).
|
**Linux**: [AppImage](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-x86_64.AppImage) (most Linux distros), [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-ubuntu-20_04-x86_64.deb) (and Debian-based distros), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-ubuntu-22_04-x86_64.deb).
|
||||||
|
|
||||||
**Mac**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex-desktop-macos-x86_64.dmg) (Intel), [aarch64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex-desktop-macos-aarch64.dmg) (Apple Silicon).
|
**Mac**: [aarch64](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-macos-aarch64.dmg) (Apple Silicon), [x86_64](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-macos-x86_64.dmg) (Intel).
|
||||||
|
|
||||||
**Windows**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex-desktop-windows-x86_64.msi).
|
**Windows**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-windows-x86_64.msi).
|
||||||
|
|
||||||
## Mobile apps
|
## Mobile apps
|
||||||
|
|
||||||
**iOS**: [App store](https://apps.apple.com/us/app/simplex-chat/id1605771084), [TestFlight](https://testflight.apple.com/join/DWuT2LQu).
|
**iOS**: [App store](https://apps.apple.com/us/app/simplex-chat/id1605771084), [TestFlight](https://testflight.apple.com/join/DWuT2LQu).
|
||||||
|
|
||||||
**Android**: [Play store](https://play.google.com/store/apps/details?id=chat.simplex.app), [F-Droid](https://simplex.chat/fdroid/), [APK aarch64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex.apk), [APK armv7](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex-armv7a.apk).
|
**Android**: [Play store](https://play.google.com/store/apps/details?id=chat.simplex.app), [F-Droid](https://simplex.chat/fdroid/), [APK aarch64](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex.apk), [APK armv7](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-armv7a.apk).
|
||||||
|
|
||||||
## Terminal (console) app
|
## Terminal (console) app
|
||||||
|
|
||||||
See [Using terminal app](/docs/CLI.md).
|
See [Using terminal app](/docs/CLI.md).
|
||||||
|
|
||||||
**Linux**: [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex-chat-ubuntu-20_04-x86-64), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex-chat-ubuntu-22_04-x86-64).
|
**Linux**: [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-chat-ubuntu-20_04-x86-64), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-chat-ubuntu-22_04-x86-64).
|
||||||
|
|
||||||
**Mac** [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex-chat-macos-x86-64), aarch64 - [compile from source](/docs/CLI.md#).
|
**Mac** [x86_64](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-chat-macos-x86-64), aarch64 - [compile from source](/docs/CLI.md#).
|
||||||
|
|
||||||
**Windows**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/download/v5.5.0/simplex-chat-windows-x86-64).
|
**Windows**: [x86_64](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-chat-windows-x86-64).
|
||||||
|
|||||||
@@ -385,6 +385,7 @@
|
|||||||
"chat_send_cmd"
|
"chat_send_cmd"
|
||||||
"chat_send_remote_cmd"
|
"chat_send_remote_cmd"
|
||||||
"chat_valid_name"
|
"chat_valid_name"
|
||||||
|
"chat_json_length"
|
||||||
"chat_write_file"
|
"chat_write_file"
|
||||||
];
|
];
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
@@ -487,6 +488,7 @@
|
|||||||
"chat_send_cmd"
|
"chat_send_cmd"
|
||||||
"chat_send_remote_cmd"
|
"chat_send_remote_cmd"
|
||||||
"chat_valid_name"
|
"chat_valid_name"
|
||||||
|
"chat_json_length"
|
||||||
"chat_write_file"
|
"chat_write_file"
|
||||||
];
|
];
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ EXPORTS
|
|||||||
chat_parse_server
|
chat_parse_server
|
||||||
chat_password_hash
|
chat_password_hash
|
||||||
chat_valid_name
|
chat_valid_name
|
||||||
|
chat_json_length
|
||||||
chat_encrypt_media
|
chat_encrypt_media
|
||||||
chat_decrypt_media
|
chat_decrypt_media
|
||||||
chat_write_file
|
chat_write_file
|
||||||
|
|||||||
13
package.yaml
13
package.yaml
@@ -1,5 +1,5 @@
|
|||||||
name: simplex-chat
|
name: simplex-chat
|
||||||
version: 5.5.0.4
|
version: 5.5.3.0
|
||||||
#synopsis:
|
#synopsis:
|
||||||
#description:
|
#description:
|
||||||
homepage: https://github.com/simplex-chat/simplex-chat#readme
|
homepage: https://github.com/simplex-chat/simplex-chat#readme
|
||||||
@@ -36,7 +36,6 @@ dependencies:
|
|||||||
- network >= 3.1.2.7 && < 3.2
|
- network >= 3.1.2.7 && < 3.2
|
||||||
- network-transport == 0.5.6
|
- network-transport == 0.5.6
|
||||||
- optparse-applicative >= 0.15 && < 0.17
|
- optparse-applicative >= 0.15 && < 0.17
|
||||||
- process == 1.6.*
|
|
||||||
- random >= 1.1 && < 1.3
|
- random >= 1.1 && < 1.3
|
||||||
- record-hasfield == 1.0.*
|
- record-hasfield == 1.0.*
|
||||||
- simple-logger == 0.1.*
|
- simple-logger == 0.1.*
|
||||||
@@ -64,11 +63,13 @@ when:
|
|||||||
- condition: impl(ghc >= 9.6.2)
|
- condition: impl(ghc >= 9.6.2)
|
||||||
dependencies:
|
dependencies:
|
||||||
- bytestring == 0.11.*
|
- bytestring == 0.11.*
|
||||||
|
- process == 1.6.*
|
||||||
- template-haskell == 2.20.*
|
- template-haskell == 2.20.*
|
||||||
- text >= 2.0.1 && < 2.2
|
- text >= 2.0.1 && < 2.2
|
||||||
- condition: impl(ghc < 9.6.2)
|
- condition: impl(ghc < 9.6.2)
|
||||||
dependencies:
|
dependencies:
|
||||||
- bytestring == 0.10.*
|
- bytestring == 0.10.*
|
||||||
|
- process >= 1.6 && < 1.6.18
|
||||||
- template-haskell == 2.16.*
|
- template-haskell == 2.16.*
|
||||||
- text >= 1.2.3.0 && < 1.3
|
- text >= 1.2.3.0 && < 1.3
|
||||||
|
|
||||||
@@ -125,13 +126,19 @@ tests:
|
|||||||
- apps/simplex-broadcast-bot/src
|
- apps/simplex-broadcast-bot/src
|
||||||
- apps/simplex-directory-service/src
|
- apps/simplex-directory-service/src
|
||||||
main: Test.hs
|
main: Test.hs
|
||||||
|
when:
|
||||||
|
- condition: impl(ghc >= 9.6.2)
|
||||||
|
dependencies:
|
||||||
|
- hspec == 2.11.*
|
||||||
|
- condition: impl(ghc < 9.6.2)
|
||||||
|
dependencies:
|
||||||
|
- hspec == 2.7.*
|
||||||
dependencies:
|
dependencies:
|
||||||
- QuickCheck == 2.14.*
|
- QuickCheck == 2.14.*
|
||||||
- simplex-chat
|
- simplex-chat
|
||||||
- async == 2.2.*
|
- async == 2.2.*
|
||||||
- deepseq == 1.4.*
|
- deepseq == 1.4.*
|
||||||
- generic-random == 1.5.*
|
- generic-random == 1.5.*
|
||||||
- hspec == 2.11.*
|
|
||||||
- network == 3.1.*
|
- network == 3.1.*
|
||||||
- silently == 1.2.*
|
- silently == 1.2.*
|
||||||
- stm == 2.5.*
|
- stm == 2.5.*
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ root_dir="$(dirname "$(dirname "$(readlink "$0")")")"
|
|||||||
cd $root_dir
|
cd $root_dir
|
||||||
BUILD_DIR=dist-newstyle/build/$ARCH-$OS/ghc-${GHC_VERSION}/simplex-chat-*
|
BUILD_DIR=dist-newstyle/build/$ARCH-$OS/ghc-${GHC_VERSION}/simplex-chat-*
|
||||||
|
|
||||||
|
exports=( $(sed 's/foreign export ccall "chat_migrate_init_key"//' src/Simplex/Chat/Mobile.hs | sed 's/foreign export ccall "chat_reopen_store"//' |grep "foreign export ccall" | cut -d '"' -f2) )
|
||||||
|
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
|
||||||
|
|
||||||
rm -rf $BUILD_DIR
|
rm -rf $BUILD_DIR
|
||||||
cabal build lib:simplex-chat --ghc-options='-optl-Wl,-rpath,$ORIGIN -flink-rts -threaded'
|
cabal build lib:simplex-chat --ghc-options='-optl-Wl,-rpath,$ORIGIN -flink-rts -threaded'
|
||||||
cd $BUILD_DIR/build
|
cd $BUILD_DIR/build
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ GHC_LIBS_DIR=$(ghc --print-libdir)
|
|||||||
|
|
||||||
BUILD_DIR=dist-newstyle/build/$ARCH-*/ghc-*/simplex-chat-*
|
BUILD_DIR=dist-newstyle/build/$ARCH-*/ghc-*/simplex-chat-*
|
||||||
|
|
||||||
|
exports=( $(sed 's/foreign export ccall "chat_migrate_init_key"//' src/Simplex/Chat/Mobile.hs | sed 's/foreign export ccall "chat_reopen_store"//' |grep "foreign export ccall" | cut -d '"' -f2) )
|
||||||
|
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
|
||||||
|
|
||||||
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"
|
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"
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ fi
|
|||||||
|
|
||||||
BUILD_DIR=dist-newstyle/build/$ARCH-$OS/ghc-*/simplex-chat-*
|
BUILD_DIR=dist-newstyle/build/$ARCH-$OS/ghc-*/simplex-chat-*
|
||||||
|
|
||||||
|
exports=( $(sed 's/foreign export ccall "chat_migrate_init_key"//' src/Simplex/Chat/Mobile.hs | sed 's/foreign export ccall "chat_reopen_store"//' |grep "foreign export ccall" | cut -d '"' -f2) )
|
||||||
|
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
|
||||||
|
|
||||||
# IMPORTANT: in order to get a working build you should use x86_64 MinGW with make, cmake, gcc.
|
# IMPORTANT: in order to get a working build you should use x86_64 MinGW with make, cmake, gcc.
|
||||||
# 100% working MinGW is https://github.com/brechtsanders/winlibs_mingw/releases/download/13.1.0-16.0.5-11.0.0-ucrt-r5/winlibs-x86_64-posix-seh-gcc-13.1.0-mingw-w64ucrt-11.0.0-r5.zip
|
# 100% working MinGW is https://github.com/brechtsanders/winlibs_mingw/releases/download/13.1.0-16.0.5-11.0.0-ucrt-r5/winlibs-x86_64-posix-seh-gcc-13.1.0-mingw-w64ucrt-11.0.0-r5.zip
|
||||||
# Many other distributions I tested don't work in some cases or don't have required tools.
|
# Many other distributions I tested don't work in some cases or don't have required tools.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"https://github.com/simplex-chat/simplexmq.git"."7a0cd8041bbb7d7ab2f089395a244dc4af0f9e3b" = "0jxf9dnsg14ffd1y3i7md2ninrds4daq1fmpnd6j5z99im07ns52";
|
"https://github.com/simplex-chat/simplexmq.git"."e64b6cba4b7e4107f78ae596ab2a6a28ef24ff78" = "0fxgklq65bh2f4kx36vjicdxqmi88m91xs601hm81v5pn6kk0ppd";
|
||||||
"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";
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ cabal-version: 1.12
|
|||||||
-- see: https://github.com/sol/hpack
|
-- see: https://github.com/sol/hpack
|
||||||
|
|
||||||
name: simplex-chat
|
name: simplex-chat
|
||||||
version: 5.5.0.4
|
version: 5.5.3.0
|
||||||
category: Web, System, Services, Cryptography
|
category: Web, System, Services, Cryptography
|
||||||
homepage: https://github.com/simplex-chat/simplex-chat#readme
|
homepage: https://github.com/simplex-chat/simplex-chat#readme
|
||||||
author: simplex.chat
|
author: simplex.chat
|
||||||
@@ -197,7 +197,6 @@ library
|
|||||||
, network >=3.1.2.7 && <3.2
|
, network >=3.1.2.7 && <3.2
|
||||||
, network-transport ==0.5.6
|
, network-transport ==0.5.6
|
||||||
, optparse-applicative >=0.15 && <0.17
|
, optparse-applicative >=0.15 && <0.17
|
||||||
, process ==1.6.*
|
|
||||||
, random >=1.1 && <1.3
|
, random >=1.1 && <1.3
|
||||||
, record-hasfield ==1.0.*
|
, record-hasfield ==1.0.*
|
||||||
, simple-logger ==0.1.*
|
, simple-logger ==0.1.*
|
||||||
@@ -217,11 +216,13 @@ library
|
|||||||
if impl(ghc >= 9.6.2)
|
if impl(ghc >= 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.11.*
|
bytestring ==0.11.*
|
||||||
|
, process ==1.6.*
|
||||||
, template-haskell ==2.20.*
|
, template-haskell ==2.20.*
|
||||||
, text >=2.0.1 && <2.2
|
, text >=2.0.1 && <2.2
|
||||||
if impl(ghc < 9.6.2)
|
if impl(ghc < 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.10.*
|
bytestring ==0.10.*
|
||||||
|
, process >=1.6 && <1.6.18
|
||||||
, template-haskell ==2.16.*
|
, template-haskell ==2.16.*
|
||||||
, text >=1.2.3.0 && <1.3
|
, text >=1.2.3.0 && <1.3
|
||||||
|
|
||||||
@@ -256,7 +257,6 @@ executable simplex-bot
|
|||||||
, network >=3.1.2.7 && <3.2
|
, network >=3.1.2.7 && <3.2
|
||||||
, network-transport ==0.5.6
|
, network-transport ==0.5.6
|
||||||
, optparse-applicative >=0.15 && <0.17
|
, optparse-applicative >=0.15 && <0.17
|
||||||
, process ==1.6.*
|
|
||||||
, random >=1.1 && <1.3
|
, random >=1.1 && <1.3
|
||||||
, record-hasfield ==1.0.*
|
, record-hasfield ==1.0.*
|
||||||
, simple-logger ==0.1.*
|
, simple-logger ==0.1.*
|
||||||
@@ -277,11 +277,13 @@ executable simplex-bot
|
|||||||
if impl(ghc >= 9.6.2)
|
if impl(ghc >= 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.11.*
|
bytestring ==0.11.*
|
||||||
|
, process ==1.6.*
|
||||||
, template-haskell ==2.20.*
|
, template-haskell ==2.20.*
|
||||||
, text >=2.0.1 && <2.2
|
, text >=2.0.1 && <2.2
|
||||||
if impl(ghc < 9.6.2)
|
if impl(ghc < 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.10.*
|
bytestring ==0.10.*
|
||||||
|
, process >=1.6 && <1.6.18
|
||||||
, template-haskell ==2.16.*
|
, template-haskell ==2.16.*
|
||||||
, text >=1.2.3.0 && <1.3
|
, text >=1.2.3.0 && <1.3
|
||||||
|
|
||||||
@@ -316,7 +318,6 @@ executable simplex-bot-advanced
|
|||||||
, network >=3.1.2.7 && <3.2
|
, network >=3.1.2.7 && <3.2
|
||||||
, network-transport ==0.5.6
|
, network-transport ==0.5.6
|
||||||
, optparse-applicative >=0.15 && <0.17
|
, optparse-applicative >=0.15 && <0.17
|
||||||
, process ==1.6.*
|
|
||||||
, random >=1.1 && <1.3
|
, random >=1.1 && <1.3
|
||||||
, record-hasfield ==1.0.*
|
, record-hasfield ==1.0.*
|
||||||
, simple-logger ==0.1.*
|
, simple-logger ==0.1.*
|
||||||
@@ -337,11 +338,13 @@ executable simplex-bot-advanced
|
|||||||
if impl(ghc >= 9.6.2)
|
if impl(ghc >= 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.11.*
|
bytestring ==0.11.*
|
||||||
|
, process ==1.6.*
|
||||||
, template-haskell ==2.20.*
|
, template-haskell ==2.20.*
|
||||||
, text >=2.0.1 && <2.2
|
, text >=2.0.1 && <2.2
|
||||||
if impl(ghc < 9.6.2)
|
if impl(ghc < 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.10.*
|
bytestring ==0.10.*
|
||||||
|
, process >=1.6 && <1.6.18
|
||||||
, template-haskell ==2.16.*
|
, template-haskell ==2.16.*
|
||||||
, text >=1.2.3.0 && <1.3
|
, text >=1.2.3.0 && <1.3
|
||||||
|
|
||||||
@@ -378,7 +381,6 @@ executable simplex-broadcast-bot
|
|||||||
, network >=3.1.2.7 && <3.2
|
, network >=3.1.2.7 && <3.2
|
||||||
, network-transport ==0.5.6
|
, network-transport ==0.5.6
|
||||||
, optparse-applicative >=0.15 && <0.17
|
, optparse-applicative >=0.15 && <0.17
|
||||||
, process ==1.6.*
|
|
||||||
, random >=1.1 && <1.3
|
, random >=1.1 && <1.3
|
||||||
, record-hasfield ==1.0.*
|
, record-hasfield ==1.0.*
|
||||||
, simple-logger ==0.1.*
|
, simple-logger ==0.1.*
|
||||||
@@ -399,11 +401,13 @@ executable simplex-broadcast-bot
|
|||||||
if impl(ghc >= 9.6.2)
|
if impl(ghc >= 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.11.*
|
bytestring ==0.11.*
|
||||||
|
, process ==1.6.*
|
||||||
, template-haskell ==2.20.*
|
, template-haskell ==2.20.*
|
||||||
, text >=2.0.1 && <2.2
|
, text >=2.0.1 && <2.2
|
||||||
if impl(ghc < 9.6.2)
|
if impl(ghc < 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.10.*
|
bytestring ==0.10.*
|
||||||
|
, process >=1.6 && <1.6.18
|
||||||
, template-haskell ==2.16.*
|
, template-haskell ==2.16.*
|
||||||
, text >=1.2.3.0 && <1.3
|
, text >=1.2.3.0 && <1.3
|
||||||
|
|
||||||
@@ -439,7 +443,6 @@ executable simplex-chat
|
|||||||
, network ==3.1.*
|
, network ==3.1.*
|
||||||
, network-transport ==0.5.6
|
, network-transport ==0.5.6
|
||||||
, optparse-applicative >=0.15 && <0.17
|
, optparse-applicative >=0.15 && <0.17
|
||||||
, process ==1.6.*
|
|
||||||
, random >=1.1 && <1.3
|
, random >=1.1 && <1.3
|
||||||
, record-hasfield ==1.0.*
|
, record-hasfield ==1.0.*
|
||||||
, simple-logger ==0.1.*
|
, simple-logger ==0.1.*
|
||||||
@@ -461,11 +464,13 @@ executable simplex-chat
|
|||||||
if impl(ghc >= 9.6.2)
|
if impl(ghc >= 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.11.*
|
bytestring ==0.11.*
|
||||||
|
, process ==1.6.*
|
||||||
, template-haskell ==2.20.*
|
, template-haskell ==2.20.*
|
||||||
, text >=2.0.1 && <2.2
|
, text >=2.0.1 && <2.2
|
||||||
if impl(ghc < 9.6.2)
|
if impl(ghc < 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.10.*
|
bytestring ==0.10.*
|
||||||
|
, process >=1.6 && <1.6.18
|
||||||
, template-haskell ==2.16.*
|
, template-haskell ==2.16.*
|
||||||
, text >=1.2.3.0 && <1.3
|
, text >=1.2.3.0 && <1.3
|
||||||
|
|
||||||
@@ -505,7 +510,6 @@ executable simplex-directory-service
|
|||||||
, network >=3.1.2.7 && <3.2
|
, network >=3.1.2.7 && <3.2
|
||||||
, network-transport ==0.5.6
|
, network-transport ==0.5.6
|
||||||
, optparse-applicative >=0.15 && <0.17
|
, optparse-applicative >=0.15 && <0.17
|
||||||
, process ==1.6.*
|
|
||||||
, random >=1.1 && <1.3
|
, random >=1.1 && <1.3
|
||||||
, record-hasfield ==1.0.*
|
, record-hasfield ==1.0.*
|
||||||
, simple-logger ==0.1.*
|
, simple-logger ==0.1.*
|
||||||
@@ -526,11 +530,13 @@ executable simplex-directory-service
|
|||||||
if impl(ghc >= 9.6.2)
|
if impl(ghc >= 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.11.*
|
bytestring ==0.11.*
|
||||||
|
, process ==1.6.*
|
||||||
, template-haskell ==2.20.*
|
, template-haskell ==2.20.*
|
||||||
, text >=2.0.1 && <2.2
|
, text >=2.0.1 && <2.2
|
||||||
if impl(ghc < 9.6.2)
|
if impl(ghc < 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.10.*
|
bytestring ==0.10.*
|
||||||
|
, process >=1.6 && <1.6.18
|
||||||
, template-haskell ==2.16.*
|
, template-haskell ==2.16.*
|
||||||
, text >=1.2.3.0 && <1.3
|
, text >=1.2.3.0 && <1.3
|
||||||
|
|
||||||
@@ -592,7 +598,6 @@ test-suite simplex-chat-test
|
|||||||
, exceptions ==0.10.*
|
, exceptions ==0.10.*
|
||||||
, filepath ==1.4.*
|
, filepath ==1.4.*
|
||||||
, generic-random ==1.5.*
|
, generic-random ==1.5.*
|
||||||
, hspec ==2.11.*
|
|
||||||
, http-types ==0.12.*
|
, http-types ==0.12.*
|
||||||
, http2 >=4.2.2 && <4.3
|
, http2 >=4.2.2 && <4.3
|
||||||
, memory ==0.18.*
|
, memory ==0.18.*
|
||||||
@@ -600,7 +605,6 @@ test-suite simplex-chat-test
|
|||||||
, network ==3.1.*
|
, network ==3.1.*
|
||||||
, network-transport ==0.5.6
|
, network-transport ==0.5.6
|
||||||
, optparse-applicative >=0.15 && <0.17
|
, optparse-applicative >=0.15 && <0.17
|
||||||
, process ==1.6.*
|
|
||||||
, random >=1.1 && <1.3
|
, random >=1.1 && <1.3
|
||||||
, record-hasfield ==1.0.*
|
, record-hasfield ==1.0.*
|
||||||
, silently ==1.2.*
|
, silently ==1.2.*
|
||||||
@@ -622,10 +626,18 @@ test-suite simplex-chat-test
|
|||||||
if impl(ghc >= 9.6.2)
|
if impl(ghc >= 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.11.*
|
bytestring ==0.11.*
|
||||||
|
, process ==1.6.*
|
||||||
, template-haskell ==2.20.*
|
, template-haskell ==2.20.*
|
||||||
, text >=2.0.1 && <2.2
|
, text >=2.0.1 && <2.2
|
||||||
if impl(ghc < 9.6.2)
|
if impl(ghc < 9.6.2)
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ==0.10.*
|
bytestring ==0.10.*
|
||||||
|
, process >=1.6 && <1.6.18
|
||||||
, template-haskell ==2.16.*
|
, template-haskell ==2.16.*
|
||||||
, text >=1.2.3.0 && <1.3
|
, text >=1.2.3.0 && <1.3
|
||||||
|
if impl(ghc >= 9.6.2)
|
||||||
|
build-depends:
|
||||||
|
hspec ==2.11.*
|
||||||
|
if impl(ghc < 9.6.2)
|
||||||
|
build-depends:
|
||||||
|
hspec ==2.7.*
|
||||||
|
|||||||
Reference in New Issue
Block a user