mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-10-31 16:24:11 +00:00
Create CallView.Coordinator in ViewModel
preserving it across view rebuilds as phone rotates
This commit is contained in:
@@ -21,6 +21,8 @@ struct CallScreenViewState: BindableState {
|
||||
var url: URL?
|
||||
|
||||
var bindings = Bindings()
|
||||
|
||||
var swiftUICallViewCoordinator: CallView.Coordinator?
|
||||
}
|
||||
|
||||
struct Bindings {
|
||||
|
||||
@@ -52,6 +52,8 @@ class CallScreenViewModel: CallScreenViewModelType, CallScreenViewModelProtocol
|
||||
|
||||
super.init(initialViewState: CallScreenViewState(script: CallScreenJavaScriptMessageName.allCasesInjectionScript))
|
||||
|
||||
state.swiftUICallViewCoordinator = .init(viewModelContext: context)
|
||||
|
||||
elementCallService.actions
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] action in
|
||||
|
||||
@@ -53,7 +53,7 @@ struct CallScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
private struct CallView: UIViewRepresentable {
|
||||
struct CallView: UIViewRepresentable {
|
||||
/// The top-level view this representable displays. It wraps the web view when picture in picture isn't running.
|
||||
typealias WebViewWrapper = UIView
|
||||
|
||||
@@ -65,7 +65,13 @@ private struct CallView: UIViewRepresentable {
|
||||
}
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(viewModelContext: viewModelContext)
|
||||
if let existing = viewModelContext.viewState.swiftUICallViewCoordinator {
|
||||
return existing
|
||||
}
|
||||
// When the screen is rotated, the pro max models regenerate the swiftui view tree, destroying and
|
||||
// rebuilding this view. For that reason, we need to create and store the coordinator in the view model
|
||||
// (and by extension the UIView) to persist between rotations to retain state
|
||||
fatalError("CallView.Coordinator must be initialized in the context view state")
|
||||
}
|
||||
|
||||
func updateUIView(_ callWebView: WebViewWrapper, context: Context) {
|
||||
@@ -151,6 +157,7 @@ private struct CallView: UIViewRepresentable {
|
||||
}
|
||||
|
||||
func load(_ url: URL) {
|
||||
guard self.url != url else { return }
|
||||
self.url = url
|
||||
// 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
|
||||
if url.isFileURL {
|
||||
|
||||
Reference in New Issue
Block a user