Skip to content

Commit 60024c7

Browse files
Velin92hughns
andauthored
Embed element call (#3939)
* it works but only with the baseURL for now * works but strings are not referenced properly and we are using a dummy config.json which maybe is not required at all? * test with EmbeddedElementCall repo * updated the version * ignore our own package * updated version removed using EC through the well known URL * fix for remote URL overriding * updated version * fix for microphone and camera using local URL * better solution * Use version 0.9.0-release-test.3 * fix project * removed workaround for emebedded EC url generation * updated EC * pr suggestions * fix * removed unnecessary configuration flag --------- Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
1 parent 791ce67 commit 60024c7

File tree

10 files changed

+94
-61
lines changed

10 files changed

+94
-61
lines changed

.githooks/pre-commit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ then
99
exit 1
1010
fi
1111

12-
swift-package-list ElementX.xcodeproj --requires-license --ignore-package compound-ios --ignore-package compound-design-tokens --ignore-package matrix-rich-text-editor-swift --output-type settings-bundle --output-path ElementX/SupportingFiles
12+
swift-package-list ElementX.xcodeproj --requires-license --ignore-package compound-ios --ignore-package compound-design-tokens --ignore-package matrix-rich-text-editor-swift --ignore-package element-call-swift --output-type settings-bundle --output-path ElementX/SupportingFiles
1313
if ! git diff --quiet -- ./ElementX/SupportingFiles/Settings.bundle || [ -n "$(git ls-files --others --exclude-standard -- ./ElementX/SupportingFiles/Settings.bundle)" ]; then
1414
echo "pre-commit: Commit aborted due to unstaged changes to the package Acknowledgements."
1515
exit 1

ElementX.xcodeproj/project.pbxproj

Lines changed: 49 additions & 32 deletions
Large diffs are not rendered by default.

ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ElementX/Sources/Application/AppSettings.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
// Please see LICENSE files in the repository root for full details.
66
//
77

8+
#if canImport(EmbeddedElementCall)
9+
import EmbeddedElementCall
10+
#endif
11+
812
import Foundation
913
import SwiftUI
1014

@@ -267,7 +271,8 @@ final class AppSettings {
267271

268272
// MARK: - Element Call
269273

270-
let elementCallBaseURL: URL = "https://call.element.io/room"
274+
// swiftlint:disable:next force_unwrapping
275+
let elementCallBaseURL: URL = EmbeddedElementCall.appURL!
271276

272277
// These are publicly availble on https://call.element.io so we don't neeed to treat them as secrets
273278
let elementCallPosthogAPIHost = "https://posthog-element-call.element.io"

ElementX/Sources/Screens/CallScreen/CallScreenViewModel.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,6 @@ class CallScreenViewModel: CallScreenViewModelType, CallScreenViewModelProtocol
148148

149149
let baseURL = if let elementCallBaseURLOverride {
150150
elementCallBaseURLOverride
151-
} else if case .success(let wellKnown) = await clientProxy.getElementWellKnown(), let wellKnownCall = wellKnown?.call {
152-
wellKnownCall.widgetURL
153151
} else {
154152
elementCallBaseURL
155153
}

ElementX/Sources/Screens/CallScreen/View/CallScreen.swift

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import AVKit
99
import Combine
10+
import EmbeddedElementCall
1011
import SFSafeSymbols
1112
import SwiftUI
1213
import WebKit
@@ -98,6 +99,8 @@ private struct CallView: UIViewRepresentable {
9899
let userContentController = WKUserContentController()
99100
userContentController.add(WKScriptMessageHandlerWrapper(self), name: viewModelContext.viewState.messageHandler)
100101

102+
// Required to allow a webview that uses file URL to load its own assets
103+
configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
101104
configuration.userContentController = userContentController
102105
configuration.allowsInlineMediaPlayback = true
103106
configuration.allowsPictureInPictureMediaPlayback = true
@@ -133,8 +136,13 @@ private struct CallView: UIViewRepresentable {
133136

134137
func load(_ url: URL) {
135138
self.url = url
136-
let request = URLRequest(url: url)
137-
webView.load(request)
139+
// The only file URL we allow is the one coming from our own local ElementCall bundle, so it's okay to allow read permission only to our local EC bundle
140+
if url.isFileURL {
141+
webView.loadFileURL(url, allowingReadAccessTo: EmbeddedElementCall.bundle.bundleURL)
142+
} else {
143+
let request = URLRequest(url: url)
144+
webView.load(request)
145+
}
138146
}
139147

140148
func evaluateJavaScript(_ script: String) async throws -> Any? {
@@ -159,8 +167,8 @@ private struct CallView: UIViewRepresentable {
159167
// MARK: - WKUIDelegate
160168

161169
func webView(_ webView: WKWebView, decideMediaCapturePermissionsFor origin: WKSecurityOrigin, initiatedBy frame: WKFrameInfo, type: WKMediaCaptureType) async -> WKPermissionDecision {
162-
// Don't allow permissions for domains different than what the call was started on
163-
guard origin.host == url.host else {
170+
// Allow if the origin is local, otherwise don't allow permissions for domains different than what the call was started on
171+
guard origin.protocol == "file" || origin.host == url.host else {
164172
return .deny
165173
}
166174

@@ -174,9 +182,16 @@ private struct CallView: UIViewRepresentable {
174182
}
175183

176184
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction) async -> WKNavigationActionPolicy {
177-
// Allow any content from the main URL.
178-
if navigationAction.request.url?.host == url.host {
179-
return .allow
185+
if let navigationURL = navigationAction.request.url {
186+
// Do not allow navigation to a different URL scheme.
187+
if navigationURL.scheme != url.scheme {
188+
return .cancel
189+
}
190+
191+
// Allow any content from the main URL.
192+
if navigationURL.host == url.host {
193+
return .allow
194+
}
180195
}
181196

182197
// Additionally allow any embedded content such as captchas.

ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ struct DeveloperOptionsScreen: View {
7373
}
7474

7575
Section {
76-
TextField(context.viewState.elementCallBaseURL.absoluteString, text: $elementCallURLOverrideString)
76+
TextField("Leave empty to use EC locally", text: $elementCallURLOverrideString)
7777
.autocorrectionDisabled(true)
7878
.autocapitalization(.none)
7979
.foregroundColor(URL(string: elementCallURLOverrideString) == nil ? .red : .primary)
@@ -86,11 +86,7 @@ struct DeveloperOptionsScreen: View {
8686
}
8787
}
8888
} header: {
89-
Text("Element Call")
90-
} footer: {
91-
if context.elementCallBaseURLOverride == nil {
92-
Text("The call URL may be overridden by your homeserver.")
93-
}
89+
Text("Element Call remote URL override")
9490
}
9591

9692
Section {

ElementX/Sources/Services/Client/ElementWellKnown.swift

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,9 @@ import Foundation
99
import MatrixRustSDK
1010

1111
struct ElementWellKnown {
12-
struct Call {
13-
let widgetURL: URL
14-
15-
init?(_ wellKnown: MatrixRustSDK.ElementCallWellKnown) {
16-
guard let widgetURL = URL(string: wellKnown.widgetUrl) else { return nil }
17-
self.widgetURL = widgetURL
18-
}
19-
}
20-
21-
let call: Call?
2212
let registrationHelperURL: URL?
2313

2414
init?(_ wellKnown: MatrixRustSDK.ElementWellKnown) {
25-
call = wellKnown.call.flatMap(Call.init)
2615
registrationHelperURL = wellKnown.registrationHelperUrl.flatMap(URL.init)
2716
}
2817
}

ElementX/SupportingFiles/target.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ targets:
214214
- package: Collections
215215
- package: DeviceKit
216216
- package: DTCoreText
217+
- package: EmbeddedElementCall
217218
- package: KeychainAccess
218219
- package: Kingfisher
219220
- package: KZFileWatchers

project.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ packages:
8181
url: https://github.com/element-hq/matrix-rich-text-editor-swift
8282
exactVersion: 2.37.12
8383
# path: ../matrix-rich-text-editor/platforms/ios/lib/WysiwygComposer
84+
EmbeddedElementCall:
85+
url: https://github.com/element-hq/element-call-swift
86+
exactVersion: 0.9.0-rc.3
8487

8588
# External dependencies
8689
Algorithms:

0 commit comments

Comments
 (0)