From 6118fca000eaf094b80787d5290bef8e56af2d02 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Fri, 27 Sep 2024 22:29:23 +0100 Subject: [PATCH 01/41] readme: update group links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e62fb8c8b3..c2df084477 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ You must: Messages not following these rules will be deleted, the right to send messages may be revoked, and the access to the new members to the group may be temporarily restricted, to prevent re-joining under a different name - our imperfect group moderation does not have a better solution at the moment. -You can join an English-speaking users group if you want to ask any questions: [#SimpleX users group](https://simplex.chat/contact#/?v=1-4&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2Fos8FftfoV8zjb2T89fUEjJtF7y64p5av%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAQqMgh0fw2lPhjn3PDIEfAKA_E0-gf8Hr8zzhYnDivRs%253D%26srv%3Dbylepyau3ty4czmn77q4fglvperknl4bi2eb2fdy2bh4jxtf32kf73yd.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22lBPiveK2mjfUH43SN77R0w%3D%3D%22%7D) +You can join an English-speaking users group if you want to ask any questions: [#SimpleX users group](https://simplex.chat/contact#/?v=2-4&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2Fos8FftfoV8zjb2T89fUEjJtF7y64p5av%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAQqMgh0fw2lPhjn3PDIEfAKA_E0-gf8Hr8zzhYnDivRs%253D%26srv%3Dbylepyau3ty4czmn77q4fglvperknl4bi2eb2fdy2bh4jxtf32kf73yd.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22lBPiveK2mjfUH43SN77R0w%3D%3D%22%7D) There is also a group [#simplex-devs](https://simplex.chat/contact#/?v=1-4&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FvYCRjIflKNMGYlfTkuHe4B40qSlQ0439%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAHNdcqNbzXZhyMoSBjT2R0-Eb1EPaLyUg3KZjn-kmM1w%253D%26srv%3Dbylepyau3ty4czmn77q4fglvperknl4bi2eb2fdy2bh4jxtf32kf73yd.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22PD20tcXjw7IpkkMCfR6HLA%3D%3D%22%7D) for developers who build on SimpleX platform: @@ -83,7 +83,7 @@ There is also a group [#simplex-devs](https://simplex.chat/contact#/?v=1-4&smp=s There are groups in other languages, that we have the apps interface translated into. These groups are for testing, and asking questions to other SimpleX Chat users: -[\#SimpleX-DE](https://simplex.chat/contact#/?v=1-2&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FkIEl7OQzcp-J6aDmjdlQbRJwqkcZE7XR%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAR16PCu02MobRmKAsjzhDWMZcWP9hS8l5AUZi-Gs8z18%253D%26srv%3Dbylepyau3ty4czmn77q4fglvperknl4bi2eb2fdy2bh4jxtf32kf73yd.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22puYPMCQt11yPUvgmI5jCiw%3D%3D%22%7D) (German-speaking), [\#SimpleX-ES](https://simplex.chat/contact#/?v=1-2&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FaJ8O1O8A8GbeoaHTo_V8dcefaCl7ouPb%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEA034qWTA3sWcTsi6aWhNf9BA34vKVCFaEBdP2R66z6Ao%253D%26srv%3Dbylepyau3ty4czmn77q4fglvperknl4bi2eb2fdy2bh4jxtf32kf73yd.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22wiZ1v_wNjLPlT-nCSB-bRA%3D%3D%22%7D) (Spanish-speaking), [\#SimpleX-FR](https://simplex.chat/contact#/?v=1-2&smp=smp%3A%2F%2Fhpq7_4gGJiilmz5Rf-CswuU5kZGkm_zOIooSw6yALRg%3D%40smp5.simplex.im%2FvIHQDxTor53nwnWWTy5cHNwQQAdWN5Hw%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAPdgK1eBnETmgiqEQufbUkydKBJafoRx4iRrtrC2NAGc%253D%26srv%3Djjbyvoemxysm7qxap7m5d5m35jzv5qq6gnlv7s4rsn7tdwwmuqciwpid.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%221FyUryBPza-1ZFFE80Ekbg%3D%3D%22%7D) (French-speaking), [\#SimpleX-RU](https://simplex.chat/contact#/?v=1-2&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FXZyt3hJmWsycpN7Dqve_wbrAqb6myk1R%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAMFVIoytozTEa_QXOgoZFq_oe0IwZBYKvW50trSFXzXo%253D%26srv%3Dbylepyau3ty4czmn77q4fglvperknl4bi2eb2fdy2bh4jxtf32kf73yd.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22xz05ngjA3pNIxLZ32a8Vxg%3D%3D%22%7D) (Russian-speaking), [\#SimpleX-IT](https://simplex.chat/contact#/?v=1-2&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2F0weR-ZgDUl7ruOtI_8TZwEsnJP6UiImA%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAq4PSThO9Fvb5ydF48wB0yNbpzCbuQJCW3vZ9BGUfcxk%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22e-iceLA0SctC62eARgYDWg%3D%3D%22%7D) (Italian-speaking). +[\#SimpleX-DE](https://simplex.chat/contact#/?v=1-4&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FmfiivxDKWFuowXrQOp11jsY8TuP__rBL%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAiz3pKNwvKudckFYMUfgoT0s96B0jfZ7ALHAu7rtE9HQ%253D%26srv%3Dbylepyau3ty4czmn77q4fglvperknl4bi2eb2fdy2bh4jxtf32kf73yd.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22jZeJpXGrRXQJU_-MSJ_v2A%3D%3D%22%7D) (German-speaking), [\#SimpleX-ES](https://simplex.chat/contact#/?v=2-4&smp=smp%3A%2F%2Fhpq7_4gGJiilmz5Rf-CswuU5kZGkm_zOIooSw6yALRg%3D%40smp5.simplex.im%2FJ5ES83pJimY2BRklS8fvy_iQwIU37xra%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEA0F0STP6UqN_12_k2cjjTrIjFgBGeWhOAmbY1qlk3pnM%253D%26srv%3Djjbyvoemxysm7qxap7m5d5m35jzv5qq6gnlv7s4rsn7tdwwmuqciwpid.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22VmUU0fqmYdCRmVCyvStvHA%3D%3D%22%7D) (Spanish-speaking), [\#SimpleX-FR](https://simplex.chat/contact#/?v=2-7&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FxCHBE_6PBRMqNEpm4UQDHXb9cz-mN7dd%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAetqlcM7zTCRw-iatnwCrvpJSto7lq5Yv6AsBMWv7GSM%253D%26srv%3Dbylepyau3ty4czmn77q4fglvperknl4bi2eb2fdy2bh4jxtf32kf73yd.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22foO5Xw4hhjOa_x7zET7otw%3D%3D%22%7D) (French-speaking), [\#SimpleX-RU](https://simplex.chat/contact#/?v=2-4&smp=smp%3A%2F%2Fhpq7_4gGJiilmz5Rf-CswuU5kZGkm_zOIooSw6yALRg%3D%40smp5.simplex.im%2FVXQTB0J2lLjYkgjWByhl6-1qmb5fgZHh%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAI6JaEWezfSwvcoTEkk6au-gkjrXR2ew2OqZYMYBvayk%253D%26srv%3Djjbyvoemxysm7qxap7m5d5m35jzv5qq6gnlv7s4rsn7tdwwmuqciwpid.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22ORH9OEe8Duissh-hslfeVg%3D%3D%22%7D) (Russian-speaking), [\#SimpleX-IT](https://simplex.chat/contact#/?v=2-7&smp=smp%3A%2F%2Fhpq7_4gGJiilmz5Rf-CswuU5kZGkm_zOIooSw6yALRg%3D%40smp5.simplex.im%2FqpHu0psOUdYfc11yQCzSyq5JhijrBzZT%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEACZ_7fbwlM45wl6cGif8cY47oPQ_AMdP0ATqOYLA6zHY%253D%26srv%3Djjbyvoemxysm7qxap7m5d5m35jzv5qq6gnlv7s4rsn7tdwwmuqciwpid.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%229uRQRTir3ealdcSfB0zsrw%3D%3D%22%7D) (Italian-speaking). You can join either by opening these links in the app or by opening them in a desktop browser and scanning the QR code. From a00e5901de18d48db85702d15d4d7ef6fb513856 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:42:36 +0400 Subject: [PATCH 02/41] core: 6.1.0.7 --- package.yaml | 2 +- simplex-chat.cabal | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.yaml b/package.yaml index 3d794ea1ec..c7f844e077 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: simplex-chat -version: 6.1.0.6 +version: 6.1.0.7 #synopsis: #description: homepage: https://github.com/simplex-chat/simplex-chat#readme diff --git a/simplex-chat.cabal b/simplex-chat.cabal index cf9b71cba1..c637789ad2 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: simplex-chat -version: 6.1.0.6 +version: 6.1.0.7 category: Web, System, Services, Cryptography homepage: https://github.com/simplex-chat/simplex-chat#readme author: simplex.chat From c6ece8afdd29d1f1436e8dbefef7bcf433dbc8fc Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Tue, 8 Oct 2024 17:13:17 +0400 Subject: [PATCH 03/41] ios: update library --- apps/ios/SimpleX.xcodeproj/project.pbxproj | 40 +++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 270dbfd8d7..f9a9eb2c2d 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -144,6 +144,11 @@ 5CFE0922282EEAF60002594B /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */; }; 640417CD2B29B8C200CCB412 /* NewChatMenuButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 640417CB2B29B8C200CCB412 /* NewChatMenuButton.swift */; }; 640417CE2B29B8C200CCB412 /* NewChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 640417CC2B29B8C200CCB412 /* NewChatView.swift */; }; + 640548A32CB56735005DE1E4 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6405489E2CB56735005DE1E4 /* libgmpxx.a */; }; + 640548A42CB56735005DE1E4 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6405489F2CB56735005DE1E4 /* libgmp.a */; }; + 640548A52CB56735005DE1E4 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 640548A02CB56735005DE1E4 /* libffi.a */; }; + 640548A62CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 640548A12CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a */; }; + 640548A72CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 640548A22CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a */; }; 6407BA83295DA85D0082BA18 /* CIInvalidJSONView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6407BA82295DA85D0082BA18 /* CIInvalidJSONView.swift */; }; 6419EC562AB8BC8B004A607A /* ContextInvitingContactMemberView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6419EC552AB8BC8B004A607A /* ContextInvitingContactMemberView.swift */; }; 6419EC582AB97507004A607A /* CIMemberCreatedContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6419EC572AB97507004A607A /* CIMemberCreatedContactView.swift */; }; @@ -169,11 +174,6 @@ 649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCDA12805D6EF00C3A862 /* CIImageView.swift */; }; 64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */; }; 64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */; }; - 64BAB0852CB417A500D7D8FD /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64BAB0802CB417A500D7D8FD /* libgmp.a */; }; - 64BAB0862CB417A500D7D8FD /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64BAB0812CB417A500D7D8FD /* libgmpxx.a */; }; - 64BAB0872CB417A500D7D8FD /* libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64BAB0822CB417A500D7D8FD /* libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15-ghc9.6.3.a */; }; - 64BAB0882CB417A500D7D8FD /* libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64BAB0832CB417A500D7D8FD /* libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15.a */; }; - 64BAB0892CB417A500D7D8FD /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64BAB0842CB417A500D7D8FD /* libffi.a */; }; 64C06EB52A0A4A7C00792D4D /* ChatItemInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */; }; 64C3B0212A0D359700E19930 /* CustomTimePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C3B0202A0D359700E19930 /* CustomTimePicker.swift */; }; 64D0C2C029F9688300B38D5F /* UserAddressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2BF29F9688300B38D5F /* UserAddressView.swift */; }; @@ -486,6 +486,11 @@ 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ZoomableScrollView.swift; path = Shared/Views/ZoomableScrollView.swift; sourceTree = SOURCE_ROOT; }; 640417CB2B29B8C200CCB412 /* NewChatMenuButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewChatMenuButton.swift; sourceTree = ""; }; 640417CC2B29B8C200CCB412 /* NewChatView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewChatView.swift; sourceTree = ""; }; + 6405489E2CB56735005DE1E4 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; + 6405489F2CB56735005DE1E4 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; + 640548A02CB56735005DE1E4 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + 640548A12CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a"; sourceTree = ""; }; + 640548A22CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a"; sourceTree = ""; }; 6407BA82295DA85D0082BA18 /* CIInvalidJSONView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIInvalidJSONView.swift; sourceTree = ""; }; 6419EC552AB8BC8B004A607A /* ContextInvitingContactMemberView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextInvitingContactMemberView.swift; sourceTree = ""; }; 6419EC572AB97507004A607A /* CIMemberCreatedContactView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIMemberCreatedContactView.swift; sourceTree = ""; }; @@ -512,11 +517,6 @@ 649BCDA12805D6EF00C3A862 /* CIImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIImageView.swift; sourceTree = ""; }; 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextItemView.swift; sourceTree = ""; }; 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletedItemView.swift; sourceTree = ""; }; - 64BAB0802CB417A500D7D8FD /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; - 64BAB0812CB417A500D7D8FD /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; - 64BAB0822CB417A500D7D8FD /* libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15-ghc9.6.3.a"; sourceTree = ""; }; - 64BAB0832CB417A500D7D8FD /* libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15.a"; sourceTree = ""; }; - 64BAB0842CB417A500D7D8FD /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; 64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemInfoView.swift; sourceTree = ""; }; 64C3B0202A0D359700E19930 /* CustomTimePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTimePicker.swift; sourceTree = ""; }; 64D0C2BF29F9688300B38D5F /* UserAddressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAddressView.swift; sourceTree = ""; }; @@ -655,14 +655,14 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 64BAB0882CB417A500D7D8FD /* libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15.a in Frameworks */, + 640548A32CB56735005DE1E4 /* libgmpxx.a in Frameworks */, + 640548A72CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a in Frameworks */, + 640548A52CB56735005DE1E4 /* libffi.a in Frameworks */, + 640548A42CB56735005DE1E4 /* libgmp.a in Frameworks */, 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */, - 64BAB0862CB417A500D7D8FD /* libgmpxx.a in Frameworks */, - 64BAB0892CB417A500D7D8FD /* libffi.a in Frameworks */, + 640548A62CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a in Frameworks */, 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */, - 64BAB0852CB417A500D7D8FD /* libgmp.a in Frameworks */, CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */, - 64BAB0872CB417A500D7D8FD /* libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15-ghc9.6.3.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -739,11 +739,11 @@ 5C764E5C279C70B7000C6508 /* Libraries */ = { isa = PBXGroup; children = ( - 64BAB0842CB417A500D7D8FD /* libffi.a */, - 64BAB0802CB417A500D7D8FD /* libgmp.a */, - 64BAB0812CB417A500D7D8FD /* libgmpxx.a */, - 64BAB0822CB417A500D7D8FD /* libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15-ghc9.6.3.a */, - 64BAB0832CB417A500D7D8FD /* libHSsimplex-chat-6.1.0.5-KYQ48Wt5wtN69vfbmNbu15.a */, + 640548A02CB56735005DE1E4 /* libffi.a */, + 6405489F2CB56735005DE1E4 /* libgmp.a */, + 6405489E2CB56735005DE1E4 /* libgmpxx.a */, + 640548A12CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a */, + 640548A22CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a */, ); path = Libraries; sourceTree = ""; From 6907f02ea628b395afff4a2c119c0bafbdce8613 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Tue, 8 Oct 2024 14:36:08 +0100 Subject: [PATCH 04/41] android, desktop: additional options for transport isolation mode (#4994) * android, desktop: additional options for transport isolation mode * small changes --------- Co-authored-by: Avently <7953703+avently@users.noreply.github.com> --- .../UserSettings/AdvancedNetworkSettings.swift | 18 ++++++++++++------ apps/ios/SimpleXChat/APITypes.swift | 8 ++++++-- apps/ios/SimpleXChat/AppGroup.swift | 4 ++-- .../chat/simplex/common/model/SimpleXAPI.kt | 7 +++++-- .../usersettings/AdvancedNetworkSettings.kt | 2 +- .../views/usersettings/NetworkAndServers.kt | 16 +++++++++++----- .../commonMain/resources/MR/base/strings.xml | 4 ++++ 7 files changed, 41 insertions(+), 18 deletions(-) diff --git a/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift b/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift index 9884c6e877..754ca3cf6b 100644 --- a/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift +++ b/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift @@ -196,11 +196,14 @@ struct AdvancedNetworkSettings: View { if developerTools { Section { Picker("Transport isolation", selection: $netCfg.sessionMode) { - ForEach(TransportSessionMode.values, id: \.self) { Text($0.text) } + let modes = TransportSessionMode.values.contains(netCfg.sessionMode) + ? TransportSessionMode.values + : TransportSessionMode.values + [netCfg.sessionMode] + ForEach(modes, id: \.self) { Text($0.text) } } .frame(height: 36) } footer: { - Text(sessionModeInfo(netCfg.sessionMode)) + sessionModeInfo(netCfg.sessionMode) .foregroundColor(theme.colors.secondary) } } @@ -353,10 +356,13 @@ struct AdvancedNetworkSettings: View { } } - private func sessionModeInfo(_ mode: TransportSessionMode) -> LocalizedStringKey { - switch mode { - case .user: return "A separate TCP connection will be used **for each chat profile you have in the app**." - case .entity: return "A separate TCP connection will be used **for each contact and group member**.\n**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail." + private func sessionModeInfo(_ mode: TransportSessionMode) -> Text { + let userMode = Text("A separate TCP connection will be used **for each chat profile you have in the app**.") + return switch mode { + case .user: userMode + case .session: userMode + Text("\n") + Text("New SOCKS credentials will be used every time you start the app.") + case .server: userMode + Text("\n") + Text("New SOCKS credentials will be used for each server.") + case .entity: Text("A separate TCP connection will be used **for each contact and group member**.\n**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail.") } } diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index ef7bb34947..bff150f58f 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -1491,18 +1491,22 @@ public enum OnionHosts: String, Identifiable { public enum TransportSessionMode: String, Codable, Identifiable { case user + case session + case server case entity public var text: LocalizedStringKey { switch self { - case .user: return "User profile" + case .user: return "Chat profile" + case .session: return "App session" + case .server: return "Server" case .entity: return "Connection" } } public var id: TransportSessionMode { self } - public static let values: [TransportSessionMode] = [.user, .entity] + public static let values: [TransportSessionMode] = [.user, .session, .server, .entity] } public struct KeepAliveOpts: Codable, Equatable { diff --git a/apps/ios/SimpleXChat/AppGroup.swift b/apps/ios/SimpleXChat/AppGroup.swift index f07d0b5737..afbcff2bf3 100644 --- a/apps/ios/SimpleXChat/AppGroup.swift +++ b/apps/ios/SimpleXChat/AppGroup.swift @@ -67,7 +67,7 @@ public func registerGroupDefaults() { GROUP_DEFAULT_NTF_ENABLE_LOCAL: false, GROUP_DEFAULT_NTF_ENABLE_PERIODIC: false, GROUP_DEFAULT_NETWORK_USE_ONION_HOSTS: OnionHosts.no.rawValue, - GROUP_DEFAULT_NETWORK_SESSION_MODE: TransportSessionMode.user.rawValue, + GROUP_DEFAULT_NETWORK_SESSION_MODE: TransportSessionMode.session.rawValue, GROUP_DEFAULT_NETWORK_SMP_PROXY_MODE: SMPProxyMode.unknown.rawValue, GROUP_DEFAULT_NETWORK_SMP_PROXY_FALLBACK: SMPProxyFallback.allowProtected.rawValue, GROUP_DEFAULT_NETWORK_TCP_CONNECT_TIMEOUT: NetCfg.defaults.tcpConnectTimeout, @@ -232,7 +232,7 @@ public let networkUseOnionHostsGroupDefault = EnumDefault( public let networkSessionModeGroupDefault = EnumDefault( defaults: groupDefaults, forKey: GROUP_DEFAULT_NETWORK_SESSION_MODE, - withDefault: .user + withDefault: .session ) public let networkSMPProxyModeGroupDefault = EnumDefault( diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 2e98d0bc89..eec7a0f30d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -3654,7 +3654,7 @@ data class NetCfg( val socksMode: SocksMode = SocksMode.Always, val hostMode: HostMode = HostMode.OnionViaSocks, val requiredHostMode: Boolean = false, - val sessionMode: TransportSessionMode = TransportSessionMode.User, + val sessionMode: TransportSessionMode = TransportSessionMode.default, val smpProxyMode: SMPProxyMode = SMPProxyMode.Unknown, val smpProxyFallback: SMPProxyFallback = SMPProxyFallback.AllowProtected, val smpWebPort: Boolean = false, @@ -3781,10 +3781,13 @@ enum class SMPProxyFallback { @Serializable enum class TransportSessionMode { @SerialName("user") User, + @SerialName("session") Session, + @SerialName("server") Server, @SerialName("entity") Entity; companion object { - val default = User + val default = Session + val safeValues = arrayOf(User, Session, Server) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt index 6dc0f74df3..35e0a3c6d8 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt @@ -218,7 +218,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U SectionDividerSpaced(maxTopPadding = true) } - if (currentRemoteHost == null && developerTools) { + if (currentRemoteHost == null) { SectionView(stringResource(MR.strings.network_session_mode_transport_isolation).uppercase()) { SessionModePicker(sessionMode, showModal, updateSessionMode) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt index 5272353c20..dc3def3884 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt @@ -164,9 +164,7 @@ fun NetworkAndServersView() { val showCustomModal = { it: @Composable (close: () -> Unit) -> Unit -> ModalManager.fullscreen.showCustomModal { close -> it(close) }} UseSocksProxySwitch(networkUseSocksProxy, toggleSocksProxy) SettingsActionItem(painterResource(MR.images.ic_settings_ethernet), stringResource(MR.strings.network_socks_proxy_settings), { showCustomModal { SocksProxySettings(networkUseSocksProxy.value, networkProxy, onionHosts, sessionMode.value, true, it) } }) - if (developerTools) { - SessionModePicker(sessionMode, showModal, updateSessionMode) - } + SessionModePicker(sessionMode, showModal, updateSessionMode) } @Composable @@ -458,9 +456,17 @@ fun SessionModePicker( ) { val density = LocalDensity.current val values = remember { - TransportSessionMode.values().map { + val safeModes = TransportSessionMode.safeValues + val modes: Array = + if (appPrefs.developerTools.get()) TransportSessionMode.values() + else if (safeModes.contains(sessionMode.value)) safeModes + else safeModes + sessionMode.value + modes.map { + val userModeDescr: AnnotatedString = escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_session_mode_user_description), density) when (it) { - TransportSessionMode.User -> ValueTitleDesc(TransportSessionMode.User, generalGetString(MR.strings.network_session_mode_user), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_session_mode_user_description), density)) + TransportSessionMode.User -> ValueTitleDesc(TransportSessionMode.User, generalGetString(MR.strings.network_session_mode_user), userModeDescr) + TransportSessionMode.Session -> ValueTitleDesc(TransportSessionMode.Session, generalGetString(MR.strings.network_session_mode_session), userModeDescr + AnnotatedString("\n") + escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_session_mode_session_description), density)) + TransportSessionMode.Server -> ValueTitleDesc(TransportSessionMode.Server, generalGetString(MR.strings.network_session_mode_server), userModeDescr + AnnotatedString("\n") + escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_session_mode_server_description), density)) TransportSessionMode.Entity -> ValueTitleDesc(TransportSessionMode.Entity, generalGetString(MR.strings.network_session_mode_entity), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_session_mode_entity_description), density)) } } diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 6ab9a268bd..c344382423 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -811,8 +811,12 @@ Onion hosts will be required for connection.\nPlease note: you will not be able to connect to the servers without .onion address. Transport isolation Chat profile + App session + Server Connection for each chat profile you have in the app.]]> + New SOCKS credentials will be used every time you start the app. + New SOCKS credentials will be used for each server. for each contact and group member.\nPlease note: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail.]]> Update transport isolation mode? Use .onion hosts to No if SOCKS proxy does not support them.]]> From 35fc0544a00c3b059cd1581b7e8ab4f9629884fd Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Tue, 8 Oct 2024 21:57:33 +0700 Subject: [PATCH 05/41] ui: do not enable speaker in calls when contact turned on video (#4998) --- apps/ios/Shared/Views/Call/ActiveCallView.swift | 6 +++--- .../chat/simplex/common/views/call/CallView.android.kt | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/ios/Shared/Views/Call/ActiveCallView.swift b/apps/ios/Shared/Views/Call/ActiveCallView.swift index ec0873a634..1f9f0739b6 100644 --- a/apps/ios/Shared/Views/Call/ActiveCallView.swift +++ b/apps/ios/Shared/Views/Call/ActiveCallView.swift @@ -434,12 +434,12 @@ struct ActiveCallOverlay: View { audioDevicePickerButton() } } - .onChange(of: call.hasVideo) { hasVideo in + .onChange(of: call.localMediaSources.hasVideo) { hasVideo in let current = AVAudioSession.sharedInstance().currentRoute.outputs.first?.portType let speakerEnabled = current == .builtInSpeaker let receiverEnabled = current == .builtInReceiver - // react automatically only when speaker or receiver were selected, otherwise keep an external device selected - if hasVideo != speakerEnabled && (speakerEnabled || receiverEnabled) { + // react automatically only when receiver were selected, otherwise keep an external device selected + if !speakerEnabled && hasVideo && receiverEnabled { client.setSpeakerEnabledAndConfigureSession(!speakerEnabled, skipExternalDevice: true) call.speakerEnabled = !speakerEnabled } diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt index dbcd05b3c7..37bf8d1330 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt @@ -226,8 +226,9 @@ actual fun ActiveCallView() { ActiveCallOverlay(call, chatModel, callAudioDeviceManager) } } - KeyChangeEffect(call?.hasVideo) { - if (call != null) { + KeyChangeEffect(call?.localMediaSources?.hasVideo) { + if (call != null && call.hasVideo && callAudioDeviceManager.currentDevice.value?.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE) { + // enabling speaker on user action (peer action ignored) and not disabling it again callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.hasVideo, true) } } From 54b40a583854b30fbf82f45250c0f63614920cd9 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Tue, 8 Oct 2024 23:16:34 +0700 Subject: [PATCH 06/41] android, desktop: checking for camera in calls and handle uninitialized call (#4997) * android, desktop: checking for camera in calls and handle uninitialized call * explanation for situation without permission * reorder * reorder * strings * font --------- Co-authored-by: Evgeny Poberezkin --- .../chat/simplex/common/views/call/WebRTC.kt | 1 + .../commonMain/resources/MR/base/strings.xml | 3 + .../commonMain/resources/assets/www/call.js | 49 +++++++++++- .../resources/assets/www/desktop/call.html | 6 ++ .../resources/assets/www/desktop/style.css | 19 ++++- .../resources/assets/www/desktop/ui.js | 10 +++ .../common/views/call/CallView.desktop.kt | 8 ++ packages/simplex-chat-webrtc/src/call.ts | 78 +++++++++++++++++-- .../simplex-chat-webrtc/src/desktop/call.html | 6 ++ .../simplex-chat-webrtc/src/desktop/style.css | 19 ++++- .../simplex-chat-webrtc/src/desktop/ui.ts | 13 ++++ 11 files changed, 201 insertions(+), 11 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/call/WebRTC.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/call/WebRTC.kt index 89883e1bf8..bbf860b39c 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/call/WebRTC.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/call/WebRTC.kt @@ -83,6 +83,7 @@ enum class CallState { @Serializable sealed class WCallCommand { @Serializable @SerialName("capabilities") data class Capabilities(val media: CallMediaType): WCallCommand() + @Serializable @SerialName("permission") data class Permission(val title: String, val chrome: String, val safari: String): WCallCommand() @Serializable @SerialName("start") data class Start(val media: CallMediaType, val aesKey: String? = null, val iceServers: List? = null, val relay: Boolean? = null): WCallCommand() @Serializable @SerialName("offer") data class Offer(val offer: String, val iceCandidates: String, val media: CallMediaType, val aesKey: String? = null, val iceServers: List? = null, val relay: Boolean? = null): WCallCommand() @Serializable @SerialName("answer") data class Answer (val answer: String, val iceCandidates: String): WCallCommand() diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index c344382423..2f6c601558 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -1047,6 +1047,9 @@ Call already ended! video call audio call + To make calls, allow to use your microphone. End the call and try to call again. + Click info button near address field to allow using microphone. + Open Safari Settings / Websites / Microphone, then choose Allow for localhost. Audio & video calls diff --git a/apps/multiplatform/common/src/commonMain/resources/assets/www/call.js b/apps/multiplatform/common/src/commonMain/resources/assets/www/call.js index f042859270..0e58050fcf 100644 --- a/apps/multiplatform/common/src/commonMain/resources/assets/www/call.js +++ b/apps/multiplatform/common/src/commonMain/resources/assets/www/call.js @@ -31,6 +31,7 @@ var sendMessageToNative = (msg) => console.log(JSON.stringify(msg)); var toggleScreenShare = async () => { }; var localOrPeerMediaSourcesChanged = (_call) => { }; var inactiveCallMediaSourcesChanged = (_inactiveCallMediaSources) => { }; +var failedToGetPermissions = (_title, _description) => { }; // Global object with cryptrographic/encoding functions const callCrypto = callCryptoFunction(); var TransformOperation; @@ -159,7 +160,7 @@ const processCommand = (function () { try { localStream = (notConnectedCall === null || notConnectedCall === void 0 ? void 0 : notConnectedCall.localStream) ? notConnectedCall.localStream - : await getLocalMediaStream(inactiveCallMediaSources.mic, inactiveCallMediaSources.camera, localCamera); + : await getLocalMediaStream(inactiveCallMediaSources.mic, inactiveCallMediaSources.camera && (await browserHasCamera()), localCamera); } catch (e) { console.log("Error while getting local media stream", e); @@ -296,7 +297,7 @@ const processCommand = (function () { endCall(); let localStream = null; try { - localStream = await getLocalMediaStream(true, command.media == CallMediaType.Video, VideoCamera.User); + localStream = await getLocalMediaStream(true, command.media == CallMediaType.Video && (await browserHasCamera()), VideoCamera.User); const videos = getVideoElements(); if (videos) { videos.local.srcObject = localStream; @@ -304,6 +305,10 @@ const processCommand = (function () { } } catch (e) { + console.log(e); + // Do not allow to continue the call without audio permission + resp = { type: "error", message: "capabilities: no permissions were granted for mic and/or camera" }; + break; localStream = new MediaStream(); // Will be shown on the next stage of call estabilishing, can work without any streams //desktopShowPermissionsAlert(command.media) @@ -437,6 +442,11 @@ const processCommand = (function () { break; case "media": if (!activeCall) { + if (!notConnectedCall) { + // call can have a slow startup and be in this place even before "capabilities" stage + resp = { type: "error", message: "media: call has not yet pass capabilities stage" }; + break; + } switch (command.source) { case CallMediaSource.Mic: inactiveCallMediaSources.mic = command.enable; @@ -484,8 +494,11 @@ const processCommand = (function () { if (!activeCall || !pc) { if (notConnectedCall) { recreateLocalStreamWhileNotConnected(command.camera); + resp = { type: "ok" }; + } + else { + resp = { type: "error", message: "camera: call has not yet pass capabilities stage" }; } - resp = { type: "ok" }; } else { if (await replaceMedia(activeCall, CallMediaSource.Camera, true, command.camera)) { @@ -515,6 +528,10 @@ const processCommand = (function () { endCall(); resp = { type: "ok" }; break; + case "permission": + failedToGetPermissions(command.title, permissionDescription(command)); + resp = { type: "ok" }; + break; default: resp = { type: "error", message: "unknown command" }; break; @@ -884,7 +901,7 @@ const processCommand = (function () { localStream.getVideoTracks().forEach((elem) => elem.stop()); localStream.getVideoTracks().forEach((elem) => localStream.removeTrack(elem)); } - await getLocalMediaStream(inactiveCallMediaSources.mic && localStream.getAudioTracks().length == 0, inactiveCallMediaSources.camera && (localStream.getVideoTracks().length == 0 || oldCamera != newCamera), newCamera) + await getLocalMediaStream(inactiveCallMediaSources.mic && localStream.getAudioTracks().length == 0, inactiveCallMediaSources.camera && (localStream.getVideoTracks().length == 0 || oldCamera != newCamera) && (await browserHasCamera()), newCamera) .then((stream) => { stream.getTracks().forEach((elem) => { localStream.addTrack(elem); @@ -1074,6 +1091,18 @@ const processCommand = (function () { }; return navigator.mediaDevices.getDisplayMedia(constraints); } + async function browserHasCamera() { + try { + const devices = await navigator.mediaDevices.enumerateDevices(); + const hasCamera = devices.some((elem) => elem.kind == "videoinput"); + console.log("Camera is available: " + hasCamera); + return hasCamera; + } + catch (error) { + console.log("Error while enumerating devices: " + error, error); + return false; + } + } function callMediaConstraints(mic, camera, facingMode) { return { audio: mic, @@ -1287,6 +1316,18 @@ function desktopShowPermissionsAlert(mediaType) { window.alert("Permissions denied. Please, allow access to mic and camera to make the call working and hit unmute/camera button. Don't reload the page."); } } +function permissionDescription(command) { + if (window.safari) { + return command.safari; + } + else if ((navigator.userAgent.includes("Chrome") && navigator.vendor.includes("Google Inc")) || + navigator.userAgent.includes("Firefox")) { + return command.chrome; + } + else { + return ""; + } +} // Cryptography function - it is loaded both in the main window and in worker context (if the worker is used) function callCryptoFunction() { const initialPlainTextRequired = { diff --git a/apps/multiplatform/common/src/commonMain/resources/assets/www/desktop/call.html b/apps/multiplatform/common/src/commonMain/resources/assets/www/desktop/call.html index 0432b1f475..8ea76ed488 100644 --- a/apps/multiplatform/common/src/commonMain/resources/assets/www/desktop/call.html +++ b/apps/multiplatform/common/src/commonMain/resources/assets/www/desktop/call.html @@ -50,6 +50,12 @@
+ +
+

+

+
+