@webspatial/builder 0.0.10 → 0.0.11
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.
- package/dist/index.js +1 -1
- package/dist/lib/Cli.js +1 -1
- package/dist/lib/cmds/build.d.ts +1 -1
- package/dist/lib/cmds/build.js +1 -1
- package/dist/lib/cmds/check.js +1 -1
- package/dist/lib/cmds/help.js +1 -1
- package/dist/lib/cmds/version.js +1 -1
- package/dist/lib/pwa/config.js +1 -1
- package/dist/lib/pwa/index.js +1 -1
- package/dist/lib/pwa/validate.js +1 -1
- package/dist/lib/resource/file.js +1 -1
- package/dist/lib/resource/imageHelper.js +1 -1
- package/dist/lib/resource/index.d.ts +10 -3
- package/dist/lib/resource/index.js +1 -1
- package/dist/lib/resource/load.js +1 -1
- package/dist/lib/utils/CustomError.js +1 -1
- package/dist/lib/utils/FetchUtils-1.js +1 -1
- package/dist/lib/utils/Log.js +1 -1
- package/dist/lib/utils/fetch.js +1 -1
- package/dist/lib/utils/messages.js +1 -1
- package/dist/lib/utils/utils.d.ts +9 -0
- package/dist/lib/utils/utils.js +1 -1
- package/dist/lib/xcode/index.js +1 -1
- package/dist/lib/xcode/manifestSwiftTemplate.js +1 -1
- package/dist/lib/xcode/xcodebuild.js +1 -1
- package/dist/lib/xcode/xcodeproject.js +1 -1
- package/dist/lib/xcode/xcrun.js +1 -1
- package/package.json +3 -2
- package/template/visionOSApp/Packages/RealityKitContent/.build/workspace-state.json +0 -7
- package/template/visionOSApp/Packages/RealityKitContent/.swiftpm/xcode/xcuserdata/bytedance.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- package/template/visionOSApp/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json +0 -11
- package/template/visionOSApp/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json +0 -112
- package/template/visionOSApp/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata +0 -17
- package/template/visionOSApp/Packages/RealityKitContent/Package.swift +0 -27
- package/template/visionOSApp/Packages/RealityKitContent/README.md +0 -3
- package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Immersive.usda +0 -50
- package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda +0 -216
- package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda +0 -59
- package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift +0 -4
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json +0 -12
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json +0 -6
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Contents.json +0 -17
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json +0 -12
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json +0 -6
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json +0 -12
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json +0 -6
- package/template/visionOSApp/web-spatial/Assets.xcassets/Contents.json +0 -6
- package/template/visionOSApp/web-spatial/Info.plist +0 -33
- package/template/visionOSApp/web-spatial/Preview Content/Preview Assets.xcassets/Contents.json +0 -6
- package/template/visionOSApp/web-spatial/libs/EventEmitter.swift +0 -32
- package/template/visionOSApp/web-spatial/libs/SpatialComponent.swift +0 -31
- package/template/visionOSApp/web-spatial/libs/SpatialEntity.swift +0 -179
- package/template/visionOSApp/web-spatial/libs/SpatialInputComponent.swift +0 -26
- package/template/visionOSApp/web-spatial/libs/SpatialMeshResource.swift +0 -19
- package/template/visionOSApp/web-spatial/libs/SpatialModel3DComponent.swift +0 -51
- package/template/visionOSApp/web-spatial/libs/SpatialModelComponent.swift +0 -32
- package/template/visionOSApp/web-spatial/libs/SpatialObject.swift +0 -144
- package/template/visionOSApp/web-spatial/libs/SpatialPhysicallyBasedMaterial.swift +0 -19
- package/template/visionOSApp/web-spatial/libs/SpatialViewComponent.swift +0 -15
- package/template/visionOSApp/web-spatial/libs/SpatialWindowComponent.swift +0 -420
- package/template/visionOSApp/web-spatial/libs/SpatialWindowContainer.swift +0 -149
- package/template/visionOSApp/web-spatial/libs/Utils/CommandManager.swift +0 -800
- package/template/visionOSApp/web-spatial/libs/Utils/Logger.swift +0 -36
- package/template/visionOSApp/web-spatial/libs/Utils/SceneManager.swift +0 -108
- package/template/visionOSApp/web-spatial/libs/Utils/WindowContainerMgr.swift +0 -117
- package/template/visionOSApp/web-spatial/libs/json/JsonParser.swift +0 -52
- package/template/visionOSApp/web-spatial/libs/uiKitDelegate/Window.swift +0 -34
- package/template/visionOSApp/web-spatial/libs/webView/UpdateSystem.swift +0 -33
- package/template/visionOSApp/web-spatial/libs/webView/backend/NativeWebView.swift +0 -319
- package/template/visionOSApp/web-spatial/libs/webView/manifest.swift +0 -92
- package/template/visionOSApp/web-spatial/static-web/index.html +0 -9
- package/template/visionOSApp/web-spatial/views/HideViewModifier.swift +0 -17
- package/template/visionOSApp/web-spatial/views/ImmersiveView.swift +0 -24
- package/template/visionOSApp/web-spatial/views/LoadingView.swift +0 -29
- package/template/visionOSApp/web-spatial/views/MaterialWithBorderCornerModifier.swift +0 -82
- package/template/visionOSApp/web-spatial/views/OpenDismissHandlerUI.swift +0 -52
- package/template/visionOSApp/web-spatial/views/PlainWindowContainerView.swift +0 -84
- package/template/visionOSApp/web-spatial/views/SpatialModel3DView.swift +0 -193
- package/template/visionOSApp/web-spatial/views/SpatialViewUI.swift +0 -168
- package/template/visionOSApp/web-spatial/views/SpatialWebViewUI.swift +0 -186
- package/template/visionOSApp/web-spatial/views/VolumetricWindowContainerView.swift +0 -38
- package/template/visionOSApp/web-spatial/views/ui/NavView.swift +0 -125
- package/template/visionOSApp/web-spatial/web_spatialApp.swift +0 -158
- package/template/visionOSApp/web-spatial.xcodeproj/project.pbxproj +0 -686
- package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +0 -5
- package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/xcuserdata/bytedance.xcuserdatad/WorkspaceSettings.xcsettings +0 -14
- package/template/visionOSApp/web-spatial.xcodeproj/xcshareddata/xcschemes/web-spatial.xcscheme +0 -115
- package/template/visionOSApp/web-spatial.xcodeproj/xcuserdata/bytedance.xcuserdatad/xcschemes/xcschememanagement.plist +0 -27
- package/template/visionOSApp/web-spatialTests/web_spatialTests.swift +0 -34
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// NativeWebView.swift
|
|
3
|
-
// web-spatial
|
|
4
|
-
//
|
|
5
|
-
// Created by ByteDance on 5/9/24.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import Combine
|
|
9
|
-
import Foundation
|
|
10
|
-
import RealityKit
|
|
11
|
-
import RealityKitContent
|
|
12
|
-
import SwiftUI
|
|
13
|
-
@preconcurrency import WebKit
|
|
14
|
-
|
|
15
|
-
class WebViewHolder {
|
|
16
|
-
var needsUpdate = false
|
|
17
|
-
var appleWebView: WKWebView?
|
|
18
|
-
var webViewCoordinator: Coordinator?
|
|
19
|
-
deinit {
|
|
20
|
-
appleWebView = nil
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
struct PreloadStyleSettings: Codable {
|
|
25
|
-
var cornerRadius: CornerRadius? = .init()
|
|
26
|
-
var backgroundMaterial: BackgroundMaterial? = .None
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
struct WebviewEarlyStyle {
|
|
30
|
-
let webview: WKWebView
|
|
31
|
-
let style: PreloadStyleSettings
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// event of forcestyle handler
|
|
35
|
-
var webviewGetEarlyStyleData = PassthroughSubject<WebviewEarlyStyle, Never>()
|
|
36
|
-
|
|
37
|
-
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate, UIScrollViewDelegate, WKURLSchemeHandler {
|
|
38
|
-
let decoder = JSONDecoder()
|
|
39
|
-
override public init() {
|
|
40
|
-
WKWebView.enableFileScheme() // ensure the handler is usable
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
func webView(_ webView: WKWebView, start urlSchemeTask: any WKURLSchemeTask) {
|
|
44
|
-
// Parse the style json string from url
|
|
45
|
-
let url = urlSchemeTask.request.url
|
|
46
|
-
|
|
47
|
-
// Local web projects accessing resources through relative paths will default to using the file protocol
|
|
48
|
-
if url!.absoluteString.starts(with: "file://") {
|
|
49
|
-
let resource: String = pwaManager.getLocalResourceURL(url: url!.absoluteString)
|
|
50
|
-
var urlRequest = urlSchemeTask.request
|
|
51
|
-
|
|
52
|
-
if resource != "" {
|
|
53
|
-
urlRequest = URLRequest(url: URL(string: resource)!)
|
|
54
|
-
} else {
|
|
55
|
-
return
|
|
56
|
-
}
|
|
57
|
-
let session = URLSession(configuration: URLSessionConfiguration.default)
|
|
58
|
-
let dataTask = session.dataTask(with: urlRequest) { data, response, _ in
|
|
59
|
-
urlSchemeTask.didReceive(response!)
|
|
60
|
-
urlSchemeTask.didReceive(data!)
|
|
61
|
-
urlSchemeTask.didFinish()
|
|
62
|
-
}
|
|
63
|
-
dataTask.resume()
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
var styleJsonString: String? = URLComponents(string: url!.absoluteString)?.queryItems?.first(where: { $0.name == "style" })?.value
|
|
68
|
-
|
|
69
|
-
do {
|
|
70
|
-
if styleJsonString?.contains("?") != nil {
|
|
71
|
-
// remove invalid query string
|
|
72
|
-
// before "{\"glassEffect\":true,\"cornerRadius\":50}?uniqueURL=0.0010192470591506853"
|
|
73
|
-
// after "{\"glassEffect\":true,\"cornerRadius\":50}"
|
|
74
|
-
styleJsonString = styleJsonString?
|
|
75
|
-
.components(separatedBy: "?").first
|
|
76
|
-
}
|
|
77
|
-
let styleToSet = try decoder.decode(PreloadStyleSettings.self, from: styleJsonString!.data(using: .utf8)!)
|
|
78
|
-
|
|
79
|
-
webviewGetEarlyStyleData.send(WebviewEarlyStyle(webview: webView, style: styleToSet))
|
|
80
|
-
} catch {
|
|
81
|
-
logger.warning("Style url parse failure " + error.localizedDescription)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Respond with empty css file
|
|
85
|
-
let response = ".ignoreThis{}".data(using: .utf8)
|
|
86
|
-
let mimeType = "text/css"
|
|
87
|
-
let headers = ["Content-Type": mimeType, "Cache-Control": "no-cache"]
|
|
88
|
-
let resp = HTTPURLResponse(url: url!, statusCode: 200, httpVersion: "1.1", headerFields: headers)
|
|
89
|
-
|
|
90
|
-
urlSchemeTask.didReceive(resp!)
|
|
91
|
-
urlSchemeTask.didReceive(response!)
|
|
92
|
-
urlSchemeTask.didFinish()
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
func webView(_ webView: WKWebView, stop urlSchemeTask: any WKURLSchemeTask) {}
|
|
96
|
-
|
|
97
|
-
@Environment(\.openWindow) private var openWindow
|
|
98
|
-
@Environment(\.dismissWindow) private var dismissWindow
|
|
99
|
-
@Environment(\.dismiss) private var dismiss
|
|
100
|
-
@Environment(\.openImmersiveSpace) private var openImmersiveSpace
|
|
101
|
-
|
|
102
|
-
deinit {}
|
|
103
|
-
|
|
104
|
-
weak var webViewRef: SpatialWindowComponent? = nil
|
|
105
|
-
|
|
106
|
-
func webView(_ webView: WKWebView, didStartProvisionalNavigation: WKNavigation!) {
|
|
107
|
-
webViewRef?.didStartLoadPage()
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
func webView(
|
|
111
|
-
_ webView: WKWebView,
|
|
112
|
-
didCommit navigation: WKNavigation!
|
|
113
|
-
) {
|
|
114
|
-
webViewRef?.didStartReceivePageContent()
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
|
118
|
-
webViewRef?.loadRequestWV?.didLoadChild(loadRequestID: webViewRef!.loadRequestID, resourceID: webViewRef!.id)
|
|
119
|
-
webViewRef?.loadRequestID = -1
|
|
120
|
-
webViewRef?.didFinishLoadPage()
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) {
|
|
124
|
-
if let url = navigationAction.request.url,
|
|
125
|
-
url.absoluteString == "webspatial://createWindowContext"
|
|
126
|
-
{
|
|
127
|
-
decisionHandler(.cancel)
|
|
128
|
-
return
|
|
129
|
-
}
|
|
130
|
-
var resource = navigationAction.request.url!.absoluteString
|
|
131
|
-
if pwaManager.isLocal {
|
|
132
|
-
resource = pwaManager.getLocalResourceURL(url: resource)
|
|
133
|
-
}
|
|
134
|
-
if pwaManager.checkInScope(url: navigationAction.request.url!.absoluteString) {
|
|
135
|
-
if navigationAction.navigationType == .backForward {
|
|
136
|
-
// backward/forward
|
|
137
|
-
webViewRef?.didNavBackForward()
|
|
138
|
-
}
|
|
139
|
-
decisionHandler(.allow)
|
|
140
|
-
} else {
|
|
141
|
-
decisionHandler(.cancel)
|
|
142
|
-
UIApplication.shared.open(navigationAction.request.url!, options: [:], completionHandler: nil)
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Swift.Void) {
|
|
147
|
-
decisionHandler(.allow)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
|
|
151
|
-
logger.warning("Navigation failed!!! " + error.localizedDescription)
|
|
152
|
-
if let urlError = (error as? URLError) {
|
|
153
|
-
logger.warning("URL ERROR: " + (urlError.failingURL != nil ? (urlError.failingURL!.absoluteString) : "no URL found"))
|
|
154
|
-
if urlError.code == .cannotConnectToHost {
|
|
155
|
-
webViewRef?.didFailLoadPage()
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Warning this should likeley be removed. There seems to be a bug with SSL loading on simulator https://stackoverflow.com/questions/27100540/allow-unverified-ssl-certificates-in-wkwebview
|
|
161
|
-
// NSAllowsArbitraryLoads should also be removed from Info.plist if shipping an app
|
|
162
|
-
// this is the workaround
|
|
163
|
-
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
|
|
164
|
-
guard let serverTrust = challenge.protectionSpace.serverTrust else { return completionHandler(.useCredential, nil) }
|
|
165
|
-
let exceptions = SecTrustCopyExceptions(serverTrust)
|
|
166
|
-
SecTrustSetExceptions(serverTrust, exceptions)
|
|
167
|
-
completionHandler(.useCredential, URLCredential(trust: serverTrust))
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
func webView(
|
|
171
|
-
_ webView: WKWebView,
|
|
172
|
-
createWebViewWith configuration: WKWebViewConfiguration,
|
|
173
|
-
for navigationAction: WKNavigationAction,
|
|
174
|
-
windowFeatures: WKWindowFeatures
|
|
175
|
-
) -> WKWebView? {
|
|
176
|
-
let url = navigationAction.request.url?.absoluteString ?? ""
|
|
177
|
-
|
|
178
|
-
if url != "webspatial://createWindowContext",
|
|
179
|
-
!pwaManager.checkInScope(url: url)
|
|
180
|
-
{
|
|
181
|
-
// open in safari
|
|
182
|
-
UIApplication.shared.open(navigationAction.request.url!, options: [:], completionHandler: nil)
|
|
183
|
-
return nil
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
let wvNative = WebViewNative()
|
|
187
|
-
|
|
188
|
-
_ = wvNative.createResources(configuration: configuration)
|
|
189
|
-
|
|
190
|
-
webViewRef!.didSpawnWebView(wv: wvNative)
|
|
191
|
-
|
|
192
|
-
return wvNative.webViewHolder.appleWebView
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// handle close
|
|
196
|
-
func webViewDidClose(_ webView: WKWebView) {
|
|
197
|
-
webViewRef!.didCloseWebView()
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// receive message from wkwebview
|
|
201
|
-
func userContentController(
|
|
202
|
-
_ userContentController: WKUserContentController,
|
|
203
|
-
didReceive message: WKScriptMessage
|
|
204
|
-
) {
|
|
205
|
-
let command = CommandManager.Instance.decode(jsonData: message.body as! String)
|
|
206
|
-
if let wv = webViewRef {
|
|
207
|
-
CommandManager.Instance.doCommand(target: wv, jsb: command)
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
|
212
|
-
webViewRef?.scrollOffset = scrollView.contentOffset
|
|
213
|
-
if webViewRef != nil {
|
|
214
|
-
let wg = SpatialWindowContainer.getSpatialWindowContainer(webViewRef!.parentWindowContainerID)!
|
|
215
|
-
wg.updateFrame = !(wg.updateFrame)
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
struct WebViewNative: UIViewRepresentable {
|
|
221
|
-
weak var webViewRef: SpatialWindowComponent? = nil
|
|
222
|
-
var url: URL = .init(filePath: "/")
|
|
223
|
-
var webViewHolder = WebViewHolder()
|
|
224
|
-
|
|
225
|
-
func destroy() {
|
|
226
|
-
// Remove references to Coordinator so that it gets cleaned up by arc
|
|
227
|
-
webViewHolder.appleWebView?.configuration.userContentController.removeScriptMessageHandler(forName: "bridge")
|
|
228
|
-
webViewHolder.appleWebView?.uiDelegate = nil
|
|
229
|
-
webViewHolder.appleWebView?.navigationDelegate = nil
|
|
230
|
-
webViewHolder.appleWebView?.scrollView.delegate = nil
|
|
231
|
-
webViewHolder.appleWebView = nil
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
func makeCoordinator() -> Coordinator {
|
|
235
|
-
let c = Coordinator()
|
|
236
|
-
c.webViewRef = webViewRef
|
|
237
|
-
return c
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
func createResources(configuration: WKWebViewConfiguration? = nil) -> WKWebView {
|
|
241
|
-
if webViewHolder.appleWebView == nil {
|
|
242
|
-
webViewHolder.webViewCoordinator = makeCoordinator()
|
|
243
|
-
let userContentController = WKUserContentController()
|
|
244
|
-
|
|
245
|
-
let userScript = WKUserScript(source: "window.WebSpatailEnabled = true; window.WebSpatailNativeVersion = '" + nativeAPIVersion + "';", injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
246
|
-
userContentController.addUserScript(userScript)
|
|
247
|
-
userContentController.add(webViewHolder.webViewCoordinator!, name: "bridge")
|
|
248
|
-
|
|
249
|
-
let myConfig = (configuration != nil) ? configuration! : WKWebViewConfiguration()
|
|
250
|
-
myConfig.userContentController = userContentController
|
|
251
|
-
myConfig.preferences.javaScriptCanOpenWindowsAutomatically = true
|
|
252
|
-
myConfig.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
|
|
253
|
-
|
|
254
|
-
if myConfig.urlSchemeHandler(forURLScheme: "forceStyle") == nil {
|
|
255
|
-
myConfig.setURLSchemeHandler(webViewHolder.webViewCoordinator, forURLScheme: "forceStyle")
|
|
256
|
-
}
|
|
257
|
-
if myConfig.urlSchemeHandler(forURLScheme: "file") == nil {
|
|
258
|
-
myConfig.setURLSchemeHandler(webViewHolder.webViewCoordinator, forURLScheme: "file")
|
|
259
|
-
}
|
|
260
|
-
webViewHolder.appleWebView = WKWebView(frame: .zero, configuration: myConfig)
|
|
261
|
-
webViewHolder.appleWebView!.uiDelegate = webViewHolder.webViewCoordinator
|
|
262
|
-
webViewHolder.appleWebView!.allowsBackForwardNavigationGestures = true
|
|
263
|
-
webViewHolder.appleWebView!.isInspectable = true
|
|
264
|
-
webViewHolder.appleWebView!.allowsLinkPreview = true
|
|
265
|
-
webViewHolder.appleWebView!.navigationDelegate = webViewHolder.webViewCoordinator
|
|
266
|
-
webViewHolder.appleWebView!.scrollView.delegate = webViewHolder.webViewCoordinator
|
|
267
|
-
webViewHolder.needsUpdate = (configuration != nil) ? false : true
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return webViewHolder.appleWebView!
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
func initialLoad() {
|
|
274
|
-
if webViewHolder.needsUpdate {
|
|
275
|
-
let request = URLRequest(url: url)
|
|
276
|
-
webViewHolder.appleWebView!.load(request)
|
|
277
|
-
webViewHolder.needsUpdate = false
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
func makeUIView(context: Context) -> WKWebView {
|
|
282
|
-
return createResources()
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
func updateUIView(_ webView: WKWebView, context: Context) {
|
|
286
|
-
initialLoad()
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// extend webview to support file://
|
|
291
|
-
@available(iOS 11.0, *)
|
|
292
|
-
extension WKWebView {
|
|
293
|
-
/// WKWebView, Support setting file scheme in configuration
|
|
294
|
-
public private(set) static var isEnableFileSupport = false
|
|
295
|
-
public static func enableFileScheme() {
|
|
296
|
-
/// This method supports adapting supported files through Configuration, but cannot be cancelled (Configuration is immutable).
|
|
297
|
-
if !isEnableFileSupport {
|
|
298
|
-
switchHandlesURLScheme()
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
private static func switchHandlesURLScheme() {
|
|
303
|
-
if
|
|
304
|
-
case let cls = WKWebView.self,
|
|
305
|
-
let m1 = class_getClassMethod(cls, NSSelectorFromString("handlesURLScheme:")),
|
|
306
|
-
let m2 = class_getClassMethod(cls, #selector(WKWebView.wrapHandles(urlScheme:)))
|
|
307
|
-
{
|
|
308
|
-
method_exchangeImplementations(m1, m2)
|
|
309
|
-
isEnableFileSupport = !isEnableFileSupport
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/// Return true if WKWebview supports handling this protocol, but WKWebview supports HTTP by default, so return false to support using custom HTTP Handler
|
|
314
|
-
@objc private dynamic
|
|
315
|
-
static func wrapHandles(urlScheme: String) -> Bool {
|
|
316
|
-
if urlScheme == "file" { return false }
|
|
317
|
-
return wrapHandles(urlScheme: urlScheme)
|
|
318
|
-
}
|
|
319
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import Foundation
|
|
3
|
-
|
|
4
|
-
var pwaManager = PWAManager()
|
|
5
|
-
|
|
6
|
-
struct PWAManager: Codable {
|
|
7
|
-
var isLocal: Bool = false
|
|
8
|
-
var start_url: String = "http://localhost:5173/"
|
|
9
|
-
var scope: String = ""
|
|
10
|
-
var id: String = "com.webspatial.pico"
|
|
11
|
-
|
|
12
|
-
var name: String = "WebSpatial"
|
|
13
|
-
var short_name: String = "name"
|
|
14
|
-
var description: String = ""
|
|
15
|
-
|
|
16
|
-
var display: PWADisplayMode = .minimal
|
|
17
|
-
var display_override: [PWADisplayMode] = []
|
|
18
|
-
var protocol_handlers: [PWAProtocol] = [PWAProtocol(protocolValue: "web+spatial", url: "./?cmd=%s")]
|
|
19
|
-
var mainScene: WindowContainerOptions = .init(
|
|
20
|
-
defaultSize: .init(
|
|
21
|
-
width: 1280,
|
|
22
|
-
height: 720
|
|
23
|
-
),
|
|
24
|
-
resizability: "automatic"
|
|
25
|
-
)
|
|
26
|
-
var useMainScene: Bool = true
|
|
27
|
-
|
|
28
|
-
mutating func _init() {
|
|
29
|
-
let urlType = start_url.split(separator: "://").first
|
|
30
|
-
if !(urlType == "http" || urlType == "https") {
|
|
31
|
-
start_url = Bundle.main.url(forResource: start_url, withExtension: "", subdirectory: "")!.absoluteString
|
|
32
|
-
scope = "file://" + Bundle.main.bundlePath + "/" + scope
|
|
33
|
-
scope = scope.replacingOccurrences(of: " ", with: "%20")
|
|
34
|
-
isLocal = true
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if display_override.count > 0 {
|
|
38
|
-
display = display_override[0]
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
for i in 0 ... protocol_handlers.count - 1 {
|
|
42
|
-
let item = protocol_handlers[i]
|
|
43
|
-
protocol_handlers[i].updateUrl(scope + item.url)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
func checkInScope(url: String) -> Bool {
|
|
48
|
-
return url.starts(with: scope)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// web+spatial://test
|
|
52
|
-
func checkInDeeplink(url: String) -> String {
|
|
53
|
-
var linkUrl: String = url
|
|
54
|
-
for item in protocol_handlers {
|
|
55
|
-
if linkUrl.starts(with: item.protocolValue) {
|
|
56
|
-
let queryString: String = linkUrl.replacingOccurrences(of: item.protocolValue, with: "").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
|
|
57
|
-
linkUrl = item.url.replacingOccurrences(of: "%s", with: item.protocolValue + queryString)
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
logger.debug(linkUrl)
|
|
61
|
-
return linkUrl
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
func getLocalResourceURL(url: String) -> String {
|
|
65
|
-
let path = String(url.split(separator: "file://").first!.split(separator: "?").first!)
|
|
66
|
-
let root = String(url.split(separator: "?").first!)
|
|
67
|
-
let params = String(url.split(separator: "file://" + root).first!)
|
|
68
|
-
var resource: String = Bundle.main.url(forResource: path, withExtension: "", subdirectory: "")?.absoluteString ?? ""
|
|
69
|
-
if resource == "" {
|
|
70
|
-
resource = Bundle.main.url(forResource: "static-web" + path, withExtension: "", subdirectory: "")?.absoluteString ?? ""
|
|
71
|
-
}
|
|
72
|
-
if resource == "" {
|
|
73
|
-
return url
|
|
74
|
-
}
|
|
75
|
-
resource += "?" + params
|
|
76
|
-
return resource
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
enum PWADisplayMode: Codable {
|
|
81
|
-
case minimal
|
|
82
|
-
case standalone
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
struct PWAProtocol: Codable {
|
|
86
|
-
var protocolValue: String = ""
|
|
87
|
-
var url: String = ""
|
|
88
|
-
|
|
89
|
-
mutating func updateUrl(_ str: String) {
|
|
90
|
-
url = str
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import SwiftUI
|
|
2
|
-
|
|
3
|
-
struct HideViewModifier: ViewModifier {
|
|
4
|
-
let isHidden: Bool
|
|
5
|
-
@ViewBuilder func body(content: Content) -> some View {
|
|
6
|
-
content
|
|
7
|
-
.opacity(isHidden ? 0 : 1)
|
|
8
|
-
.disabled(isHidden)
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Extending on View to apply to all Views
|
|
13
|
-
extension View {
|
|
14
|
-
func hidden(_ isHidden: Bool) -> some View {
|
|
15
|
-
modifier(HideViewModifier(isHidden: isHidden))
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// ImmersiveView.swift
|
|
3
|
-
// web-spatial
|
|
4
|
-
//
|
|
5
|
-
// Created by ByteDance on 5/8/24.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import RealityKit
|
|
9
|
-
import RealityKitContent
|
|
10
|
-
import SwiftUI
|
|
11
|
-
|
|
12
|
-
struct ImmersiveView: View {
|
|
13
|
-
var body: some View {
|
|
14
|
-
RealityView { content in
|
|
15
|
-
if let scene = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
|
|
16
|
-
content.add(scene)
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
#Preview(immersionStyle: .mixed) {
|
|
23
|
-
ImmersiveView()
|
|
24
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// LoadingView.swift
|
|
3
|
-
// web-spatial
|
|
4
|
-
//
|
|
5
|
-
// Created by ByteDance on 2025/1/24.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import SwiftUI
|
|
9
|
-
import SwiftUICore
|
|
10
|
-
|
|
11
|
-
struct LoadingView: View {
|
|
12
|
-
var body: some View {
|
|
13
|
-
GeometryReader { proxy3D in
|
|
14
|
-
let width = proxy3D.size.width
|
|
15
|
-
let height = proxy3D.size.height
|
|
16
|
-
ZStack {
|
|
17
|
-
VStack {
|
|
18
|
-
ProgressView()
|
|
19
|
-
.progressViewStyle(CircularProgressViewStyle(tint: .white))
|
|
20
|
-
.scaleEffect(2)
|
|
21
|
-
Text("Loading...")
|
|
22
|
-
.foregroundColor(.white)
|
|
23
|
-
.font(.headline)
|
|
24
|
-
.padding(.top, 16)
|
|
25
|
-
}
|
|
26
|
-
}.frame(width: width, height: height).glassBackgroundEffect()
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// MaterialWithBorderCornerModifier.swift
|
|
3
|
-
// web-spatial
|
|
4
|
-
//
|
|
5
|
-
// Created by ByteDance on 12/4/24.
|
|
6
|
-
//
|
|
7
|
-
import SwiftUI
|
|
8
|
-
|
|
9
|
-
enum BackgroundMaterial: String, Codable {
|
|
10
|
-
case None = "none"
|
|
11
|
-
case Transparent = "transparent"
|
|
12
|
-
case GlassMaterial = "translucent"
|
|
13
|
-
case ThickMaterial = "thick"
|
|
14
|
-
case RegularMaterial = "regular"
|
|
15
|
-
case ThinMaterial = "thin"
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
struct CornerRadius: Codable {
|
|
19
|
-
var topLeading: CGFloat = 0
|
|
20
|
-
var bottomLeading: CGFloat = 0
|
|
21
|
-
var topTrailing: CGFloat = 0
|
|
22
|
-
var bottomTrailing: CGFloat = 0
|
|
23
|
-
|
|
24
|
-
func toJson() -> [String: Any] {
|
|
25
|
-
return [
|
|
26
|
-
"topLeading": topLeading,
|
|
27
|
-
"bottomLeading": bottomLeading,
|
|
28
|
-
"topTrailing": topTrailing,
|
|
29
|
-
"bottomTrailing": bottomTrailing,
|
|
30
|
-
]
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
struct MaterialWithBorderCornerModifier: ViewModifier {
|
|
35
|
-
let backgroundMaterial: BackgroundMaterial
|
|
36
|
-
let cornerRadius: CornerRadius
|
|
37
|
-
|
|
38
|
-
init(_ backgroundMaterial: BackgroundMaterial, _ cornerRadius: CornerRadius) {
|
|
39
|
-
self.backgroundMaterial = backgroundMaterial
|
|
40
|
-
self.cornerRadius = cornerRadius
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
func body(content: Content) -> some View {
|
|
44
|
-
let radii = RectangleCornerRadii(topLeading: cornerRadius.topLeading, bottomLeading: cornerRadius.bottomLeading, bottomTrailing: cornerRadius.bottomTrailing, topTrailing: cornerRadius.topTrailing)
|
|
45
|
-
|
|
46
|
-
switch backgroundMaterial {
|
|
47
|
-
case .GlassMaterial:
|
|
48
|
-
content
|
|
49
|
-
.glassBackgroundEffect(
|
|
50
|
-
in: .rect(cornerRadii: radii),
|
|
51
|
-
displayMode: .always
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
case .RegularMaterial:
|
|
55
|
-
content
|
|
56
|
-
.background(Material.regularMaterial)
|
|
57
|
-
.clipShape(.rect(cornerRadii: radii))
|
|
58
|
-
|
|
59
|
-
case .ThinMaterial:
|
|
60
|
-
content
|
|
61
|
-
.background(Material.thinMaterial)
|
|
62
|
-
.clipShape(.rect(cornerRadii: radii))
|
|
63
|
-
|
|
64
|
-
case .ThickMaterial:
|
|
65
|
-
content
|
|
66
|
-
.background(Material.thickMaterial)
|
|
67
|
-
.clipShape(.rect(cornerRadii: radii))
|
|
68
|
-
|
|
69
|
-
default:
|
|
70
|
-
content
|
|
71
|
-
.clipShape(.rect(cornerRadii: radii))
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
extension View {
|
|
77
|
-
func materialWithBorderCorner(_ backgroundMaterial: BackgroundMaterial, _ cornerRadius: CornerRadius) -> some View {
|
|
78
|
-
return modifier(
|
|
79
|
-
MaterialWithBorderCornerModifier(backgroundMaterial, cornerRadius)
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// OpenDismissHandlerUI.swift
|
|
3
|
-
// web-spatial
|
|
4
|
-
//
|
|
5
|
-
// Created by ByteDance on 8/20/24.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import SwiftUI
|
|
9
|
-
|
|
10
|
-
struct OpenDismissHandlerUI: View {
|
|
11
|
-
@Environment(\.openImmersiveSpace) private var openImmersiveSpace
|
|
12
|
-
@Environment(\.dismissImmersiveSpace) private var dismissImmersiveSpace
|
|
13
|
-
@Environment(\.openWindow) private var openWindow
|
|
14
|
-
@Environment(\.dismissWindow) private var dismissWindow
|
|
15
|
-
|
|
16
|
-
@Environment(SpatialWindowContainer.self) var windowContainerContent: SpatialWindowContainer
|
|
17
|
-
|
|
18
|
-
@Environment(\.scenePhase) private var scenePhase
|
|
19
|
-
|
|
20
|
-
var body: some View {
|
|
21
|
-
VStack {}
|
|
22
|
-
.onAppear()
|
|
23
|
-
.onReceive(windowContainerContent.toggleImmersiveSpace) { v in
|
|
24
|
-
if v {
|
|
25
|
-
Task {
|
|
26
|
-
await openImmersiveSpace(id: "ImmersiveSpace")
|
|
27
|
-
}
|
|
28
|
-
} else {
|
|
29
|
-
Task {
|
|
30
|
-
await dismissImmersiveSpace()
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
.onReceive(windowContainerContent.openWindowData) { wd in
|
|
35
|
-
let _ = openWindow(id: wd.windowStyle, value: wd)
|
|
36
|
-
}
|
|
37
|
-
.onReceive(windowContainerContent.closeWindowData) { wd in
|
|
38
|
-
dismissWindow(id: wd.windowStyle, value: wd)
|
|
39
|
-
}
|
|
40
|
-
.onReceive(windowContainerContent.setLoadingWindowData) { wd in
|
|
41
|
-
if wd.method == .show {
|
|
42
|
-
openWindow(id: "loading")
|
|
43
|
-
} else if wd.method == .hide {
|
|
44
|
-
dismissWindow(id: "loading")
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.onChange(of: scenePhase) { oldValue, newValue in
|
|
49
|
-
logger.debug("OpenDismissHandlerUI: Value changed from \(oldValue) to \(newValue)")
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|