@capgo/capacitor-stream-call 0.0.22 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -791,38 +791,57 @@ public class StreamCallPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
791
791
|
}
|
|
792
792
|
|
|
793
793
|
private func setupViews() {
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
//
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
//
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
//
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
794
|
+
guard let webView = self.webView, let parent = webView.superview else { return }
|
|
795
|
+
|
|
796
|
+
// Create the touch intercept view as an overlay for touch passthrough
|
|
797
|
+
let touchInterceptView = TouchInterceptView(frame: parent.bounds)
|
|
798
|
+
touchInterceptView.translatesAutoresizingMaskIntoConstraints = false
|
|
799
|
+
touchInterceptView.backgroundColor = .clear
|
|
800
|
+
touchInterceptView.isOpaque = false
|
|
801
|
+
|
|
802
|
+
// Create SwiftUI view with view model if not already created
|
|
803
|
+
if self.overlayView == nil, let callViewModel = self.callViewModel {
|
|
804
|
+
let hostingController = UIHostingController(rootView: CallOverlayView(viewModel: callViewModel))
|
|
805
|
+
hostingController.view.backgroundColor = .clear
|
|
806
|
+
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
|
|
807
|
+
hostingController.view.isHidden = true // Initially hidden until a call is active
|
|
808
|
+
|
|
809
|
+
self.hostingController = hostingController
|
|
810
|
+
self.overlayView = hostingController.view
|
|
811
|
+
|
|
812
|
+
if let overlayView = self.overlayView {
|
|
813
|
+
// Insert overlay view below webview
|
|
814
|
+
parent.insertSubview(overlayView, belowSubview: webView)
|
|
815
|
+
|
|
816
|
+
// Setup constraints for overlayView
|
|
817
|
+
let safeGuide = parent.safeAreaLayoutGuide
|
|
818
|
+
NSLayoutConstraint.activate([
|
|
819
|
+
overlayView.topAnchor.constraint(equalTo: safeGuide.topAnchor),
|
|
820
|
+
overlayView.bottomAnchor.constraint(equalTo: safeGuide.bottomAnchor),
|
|
821
|
+
overlayView.leadingAnchor.constraint(equalTo: safeGuide.leadingAnchor),
|
|
822
|
+
overlayView.trailingAnchor.constraint(equalTo: safeGuide.trailingAnchor)
|
|
823
|
+
])
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// Setup touch intercept view with references to webview and overlay
|
|
828
|
+
if let overlayView = self.overlayView {
|
|
829
|
+
touchInterceptView.setupWithWebView(webView, overlayView: overlayView)
|
|
830
|
+
// Insert touchInterceptView above webView
|
|
831
|
+
parent.insertSubview(touchInterceptView, aboveSubview: webView)
|
|
832
|
+
} else {
|
|
833
|
+
// If overlayView is not present, just add on top of webView
|
|
834
|
+
touchInterceptView.setupWithWebView(webView, overlayView: webView)
|
|
835
|
+
parent.insertSubview(touchInterceptView, aboveSubview: webView)
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// Setup constraints for touchInterceptView to cover the entire parent
|
|
839
|
+
NSLayoutConstraint.activate([
|
|
840
|
+
touchInterceptView.topAnchor.constraint(equalTo: parent.topAnchor),
|
|
841
|
+
touchInterceptView.bottomAnchor.constraint(equalTo: parent.bottomAnchor),
|
|
842
|
+
touchInterceptView.leadingAnchor.constraint(equalTo: parent.leadingAnchor),
|
|
843
|
+
touchInterceptView.trailingAnchor.constraint(equalTo: parent.trailingAnchor)
|
|
844
|
+
])
|
|
826
845
|
}
|
|
827
846
|
|
|
828
847
|
private func createCallOverlayView() {
|
|
@@ -832,17 +851,23 @@ public class StreamCallPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
832
851
|
|
|
833
852
|
// Check if we already have an overlay view - do nothing if it exists
|
|
834
853
|
if let existingOverlayView = self.overlayView, existingOverlayView.superview != nil {
|
|
835
|
-
print("Call overlay view already exists,
|
|
854
|
+
print("Call overlay view already exists, making it visible")
|
|
855
|
+
existingOverlayView.isHidden = false
|
|
856
|
+
// Make webview transparent to see StreamCall UI underneath
|
|
857
|
+
webView.isOpaque = false
|
|
858
|
+
webView.backgroundColor = .clear
|
|
859
|
+
webView.scrollView.backgroundColor = .clear
|
|
836
860
|
return
|
|
837
861
|
}
|
|
838
862
|
|
|
839
863
|
print("Creating new call overlay view")
|
|
840
864
|
|
|
841
865
|
// First, create the overlay view
|
|
842
|
-
let overlayView = CallOverlayView
|
|
866
|
+
let overlayView = UIHostingController(rootView: CallOverlayView(viewModel: callOverlayView))
|
|
843
867
|
overlayView.view.translatesAutoresizingMaskIntoConstraints = false
|
|
868
|
+
overlayView.view.isHidden = false // Make visible during a call
|
|
844
869
|
|
|
845
|
-
//
|
|
870
|
+
// Insert the overlay view below the webView in the view hierarchy
|
|
846
871
|
parent.insertSubview(overlayView.view, belowSubview: webView)
|
|
847
872
|
|
|
848
873
|
// Set constraints to fill the parent's safe area
|
|
@@ -855,7 +880,7 @@ public class StreamCallPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
855
880
|
overlayView.view.trailingAnchor.constraint(equalTo: safeGuide.trailingAnchor)
|
|
856
881
|
])
|
|
857
882
|
|
|
858
|
-
//
|
|
883
|
+
// Make webview transparent to see StreamCall UI underneath
|
|
859
884
|
webView.isOpaque = false
|
|
860
885
|
webView.backgroundColor = .clear
|
|
861
886
|
webView.scrollView.backgroundColor = .clear
|
|
@@ -863,26 +888,42 @@ public class StreamCallPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
863
888
|
// Store reference to the hosting controller
|
|
864
889
|
self.hostingController = overlayView
|
|
865
890
|
self.overlayView = overlayView.view
|
|
891
|
+
|
|
892
|
+
// Ensure touch intercept view is on top
|
|
893
|
+
if let touchInterceptView = parent.subviews.first(where: { $0 is TouchInterceptView }) {
|
|
894
|
+
parent.bringSubviewToFront(touchInterceptView)
|
|
895
|
+
} else {
|
|
896
|
+
// Create touch intercept view if not already created
|
|
897
|
+
let touchInterceptView = TouchInterceptView(frame: parent.bounds)
|
|
898
|
+
touchInterceptView.translatesAutoresizingMaskIntoConstraints = false
|
|
899
|
+
touchInterceptView.backgroundColor = .clear
|
|
900
|
+
touchInterceptView.isOpaque = false
|
|
901
|
+
touchInterceptView.setupWithWebView(webView, overlayView: overlayView.view)
|
|
902
|
+
parent.addSubview(touchInterceptView)
|
|
903
|
+
|
|
904
|
+
NSLayoutConstraint.activate([
|
|
905
|
+
touchInterceptView.topAnchor.constraint(equalTo: parent.topAnchor),
|
|
906
|
+
touchInterceptView.bottomAnchor.constraint(equalTo: parent.bottomAnchor),
|
|
907
|
+
touchInterceptView.leadingAnchor.constraint(equalTo: parent.leadingAnchor),
|
|
908
|
+
touchInterceptView.trailingAnchor.constraint(equalTo: parent.trailingAnchor)
|
|
909
|
+
])
|
|
910
|
+
}
|
|
866
911
|
}
|
|
867
912
|
|
|
868
913
|
private func ensureViewRemoved() {
|
|
869
914
|
// Check if we have an overlay view
|
|
870
915
|
if let existingOverlayView = self.overlayView {
|
|
871
|
-
print("
|
|
916
|
+
print("Hiding call overlay view")
|
|
872
917
|
|
|
873
|
-
//
|
|
874
|
-
existingOverlayView.
|
|
918
|
+
// Hide the view instead of removing it
|
|
919
|
+
existingOverlayView.isHidden = true
|
|
875
920
|
|
|
876
921
|
// Reset opacity for webView
|
|
877
922
|
self.webView?.isOpaque = true
|
|
878
923
|
self.webView?.backgroundColor = nil
|
|
879
924
|
self.webView?.scrollView.backgroundColor = nil
|
|
880
|
-
|
|
881
|
-
// Clear references
|
|
882
|
-
self.overlayView = nil
|
|
883
|
-
self.hostingController = nil
|
|
884
925
|
} else {
|
|
885
|
-
print("No call overlay view to
|
|
926
|
+
print("No call overlay view to hide")
|
|
886
927
|
}
|
|
887
928
|
}
|
|
888
929
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import UIKit
|
|
2
|
+
|
|
3
|
+
class TouchInterceptView: UIView {
|
|
4
|
+
private weak var webView: UIView?
|
|
5
|
+
private weak var overlayView: UIView?
|
|
6
|
+
|
|
7
|
+
func setupWithWebView(_ webView: UIView, overlayView: UIView) {
|
|
8
|
+
self.webView = webView
|
|
9
|
+
self.overlayView = overlayView
|
|
10
|
+
|
|
11
|
+
// Ensure this view is transparent and doesn't interfere with display
|
|
12
|
+
self.backgroundColor = .clear
|
|
13
|
+
self.isOpaque = false
|
|
14
|
+
// print("TouchInterceptView setup with webView: \(webView) and overlayView: \(overlayView)")
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
18
|
+
guard let webView = webView, let overlayView = overlayView, overlayView.isHidden == false else {
|
|
19
|
+
// print("hitTest: Conditions not met - webView: \(webView?.description ?? "nil"), overlayView: \(overlayView?.description ?? "nil"), overlayHidden: \(overlayView?.isHidden ?? true)")
|
|
20
|
+
return super.hitTest(point, with: event)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// First, check if the webview has a specific subview to interact with at this point
|
|
24
|
+
let webViewHit = webView.hitTest(point, with: event)
|
|
25
|
+
if webViewHit != nil && webViewHit != webView {
|
|
26
|
+
// Check if the hit view is a specific interactive element (like a button)
|
|
27
|
+
if webViewHit is UIButton || webViewHit?.accessibilityTraits.contains(.button) == true {
|
|
28
|
+
// print("hitTest: WebView interactive element hit at point \(point) - returning \(webViewHit?.description ?? "nil")")
|
|
29
|
+
return webViewHit
|
|
30
|
+
} else {
|
|
31
|
+
// print("hitTest: WebView hit at point \(point) but not an interactive element - passing through")
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
// print("hitTest: No WebView hit at point \(point) - passing through")
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// If no specific interactive element in webview is hit, pass through to overlay (StreamCall UI)
|
|
38
|
+
let overlayHit = overlayView.hitTest(point, with: event)
|
|
39
|
+
if overlayHit != nil {
|
|
40
|
+
// print("hitTest: Overlay hit at point \(point) - returning \(overlayHit?.description ?? "nil")")
|
|
41
|
+
return overlayHit
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// If neither webview nor overlay handles the touch, return nil to pass through
|
|
45
|
+
// print("hitTest: No hit at point \(point) - returning nil")
|
|
46
|
+
return nil
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
|
50
|
+
guard let webView = webView, let overlayView = overlayView, overlayView.isHidden == false else {
|
|
51
|
+
// print("point(inside:with): Conditions not met - webView: \(webView?.description ?? "nil"), overlayView: \(overlayView?.description ?? "nil"), overlayHidden: \(overlayView?.isHidden ?? true)")
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
// Check if webview has content at this point
|
|
55
|
+
if webView.point(inside: point, with: event) {
|
|
56
|
+
// If webview claims the point, check for interactive elements in hitTest
|
|
57
|
+
// print("point(inside:with): WebView claims point \(point) - will check for interactive elements")
|
|
58
|
+
return true
|
|
59
|
+
}
|
|
60
|
+
// Otherwise, allow touches to pass through to the overlay if relevant
|
|
61
|
+
if overlayView.point(inside: point, with: event) {
|
|
62
|
+
// print("point(inside:with): Overlay claims point \(point)")
|
|
63
|
+
return true
|
|
64
|
+
}
|
|
65
|
+
// print("point(inside:with): No view claims point \(point)")
|
|
66
|
+
return false
|
|
67
|
+
}
|
|
68
|
+
}
|
package/package.json
CHANGED