@plattar/plattar-ar-adapter 2.7.1 → 2.7.3
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/build/es2015/plattar-ar-adapter.js +1660 -1878
- package/build/es2015/plattar-ar-adapter.min.js +1 -1
- package/build/es2019/plattar-ar-adapter.js +413 -570
- package/build/es2019/plattar-ar-adapter.min.js +1 -1
- package/dist/ar/configurator-ar.js +2 -0
- package/dist/ar/model-ar.js +2 -0
- package/dist/ar/product-ar.js +2 -2
- package/dist/ar/raw-ar.js +2 -0
- package/dist/ar/scene-ar.js +76 -47
- package/dist/ar/scene-graph-ar.d.ts +1 -0
- package/dist/ar/scene-graph-ar.js +31 -25
- package/dist/embed/controllers/configurator-controller.d.ts +5 -0
- package/dist/embed/controllers/configurator-controller.js +50 -18
- package/dist/embed/controllers/gallery-controller.js +3 -9
- package/dist/embed/controllers/launcher-controller.js +9 -4
- package/dist/embed/controllers/plattar-controller.d.ts +9 -2
- package/dist/embed/controllers/plattar-controller.js +30 -12
- package/dist/embed/controllers/vto-controller.js +4 -10
- package/dist/embed/controllers/webxr-controller.js +4 -10
- package/dist/embed/plattar-embed.d.ts +6 -0
- package/dist/embed/plattar-embed.js +12 -0
- package/dist/util/configurator-state.d.ts +13 -1
- package/dist/util/configurator-state.js +74 -35
- package/dist/util/util.d.ts +1 -0
- package/dist/util/util.js +74 -22
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +14 -5
package/dist/ar/model-ar.js
CHANGED
|
@@ -35,6 +35,8 @@ class ModelAR extends launcher_ar_1.LauncherAR {
|
|
|
35
35
|
return this._options.modelID;
|
|
36
36
|
}
|
|
37
37
|
_SetupAnalytics(model) {
|
|
38
|
+
if (this._analytics !== null)
|
|
39
|
+
return;
|
|
38
40
|
let analytics = null;
|
|
39
41
|
const project = model.relationships.find(plattar_api_1.Project);
|
|
40
42
|
// setup scene stuff (if any)
|
package/dist/ar/product-ar.js
CHANGED
|
@@ -40,6 +40,8 @@ class ProductAR extends launcher_ar_1.LauncherAR {
|
|
|
40
40
|
return this._options.variationSKU;
|
|
41
41
|
}
|
|
42
42
|
_SetupAnalytics(product, variation) {
|
|
43
|
+
if (this._analytics !== null)
|
|
44
|
+
return;
|
|
43
45
|
let analytics = null;
|
|
44
46
|
const scene = product.relationships.find(plattar_api_1.Scene);
|
|
45
47
|
// setup scene stuff (if any)
|
|
@@ -89,9 +91,7 @@ class ProductAR extends launcher_ar_1.LauncherAR {
|
|
|
89
91
|
return reject(new Error("ProductAR.init() - cannot proceed as AR not available in context"));
|
|
90
92
|
}
|
|
91
93
|
const product = new plattar_api_1.Product(this.productID);
|
|
92
|
-
product.include(plattar_api_1.ProductVariation);
|
|
93
94
|
product.include(plattar_api_1.ProductVariation.include(plattar_api_1.FileModel));
|
|
94
|
-
product.include(plattar_api_1.Scene);
|
|
95
95
|
product.include(plattar_api_1.Scene.include(plattar_api_1.Project));
|
|
96
96
|
product.get().then((product) => {
|
|
97
97
|
// find the required variation from our product
|
package/dist/ar/raw-ar.js
CHANGED
package/dist/ar/scene-ar.js
CHANGED
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.SceneAR = void 0;
|
|
7
7
|
const plattar_analytics_1 = require("@plattar/plattar-analytics");
|
|
8
8
|
const plattar_api_1 = require("@plattar/plattar-api");
|
|
9
|
-
const plattar_services_1 = require("@plattar/plattar-services");
|
|
10
9
|
const util_1 = require("../util/util");
|
|
11
10
|
const quicklook_viewer_1 = __importDefault(require("../viewers/quicklook-viewer"));
|
|
12
11
|
const scene_viewer_1 = __importDefault(require("../viewers/scene-viewer"));
|
|
@@ -35,6 +34,8 @@ class SceneAR extends launcher_ar_1.LauncherAR {
|
|
|
35
34
|
return this._options.sceneID;
|
|
36
35
|
}
|
|
37
36
|
_SetupAnalytics(scene) {
|
|
37
|
+
if (this._analytics !== null)
|
|
38
|
+
return;
|
|
38
39
|
let analytics = null;
|
|
39
40
|
// setup scene stuff (if any)
|
|
40
41
|
if (scene) {
|
|
@@ -64,58 +65,87 @@ class SceneAR extends launcher_ar_1.LauncherAR {
|
|
|
64
65
|
* Composes a Scene into an AR Model (remote operation) that can be used to launch
|
|
65
66
|
* an AR File
|
|
66
67
|
*/
|
|
67
|
-
_ComposeScene(scene, output) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
async _ComposeScene(scene, output) {
|
|
69
|
+
const sceneProducts = scene.relationships.filter(plattar_api_1.SceneProduct);
|
|
70
|
+
const sceneModels = scene.relationships.filter(plattar_api_1.SceneModel);
|
|
71
|
+
// nothing to do if no AR components can be found
|
|
72
|
+
if ((sceneProducts.length + sceneModels.length) <= 0) {
|
|
73
|
+
throw new Error("SceneAR.ComposeScene() - cannot proceed as scene does not contain AR components");
|
|
74
|
+
}
|
|
75
|
+
const url = `${plattar_api_1.Server.location().type === 'staging' ? 'https://converter.plattar.space' : 'https://converter.plattar.com'}/v3/converter/config-to-model`;
|
|
76
|
+
const payload = {
|
|
77
|
+
data: {
|
|
78
|
+
attributes: {
|
|
79
|
+
quality: 100,
|
|
80
|
+
output: output,
|
|
81
|
+
maps: new Array()
|
|
82
|
+
}
|
|
74
83
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
};
|
|
85
|
+
let totalARObjectCount = 0;
|
|
86
|
+
// add our scene products
|
|
87
|
+
sceneProducts.forEach((sceneProduct) => {
|
|
88
|
+
const product = sceneProduct.relationships.find(plattar_api_1.Product);
|
|
89
|
+
const selection = this._options.variationSelection;
|
|
90
|
+
// we have a specific product selection
|
|
91
|
+
if (sceneProduct.attributes.include_in_augment) {
|
|
92
|
+
// check if this product is the one we want (from selection optionally)
|
|
93
|
+
if (product && (product.id === selection.productID) && selection.variationID) {
|
|
94
|
+
payload.data.attributes.maps.push({
|
|
95
|
+
sceneproduct: sceneProduct.id,
|
|
96
|
+
productvariation: selection.variationID
|
|
97
|
+
});
|
|
98
|
+
totalARObjectCount++;
|
|
99
|
+
}
|
|
100
|
+
else if (product) {
|
|
101
|
+
// check if this scene-product is the one we want (from selection)
|
|
102
|
+
if ((sceneProduct.id === selection.sceneProductID) && selection.variationID) {
|
|
103
|
+
payload.data.attributes.maps.push({
|
|
104
|
+
sceneproduct: sceneProduct.id,
|
|
105
|
+
productvariation: selection.variationID
|
|
106
|
+
});
|
|
89
107
|
totalARObjectCount++;
|
|
90
108
|
}
|
|
91
|
-
else if (product) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
else if (product.attributes.product_variation_id) {
|
|
98
|
-
configurator.addSceneProduct(sceneProduct.id, product.attributes.product_variation_id);
|
|
99
|
-
totalARObjectCount++;
|
|
100
|
-
}
|
|
109
|
+
else if (product.attributes.product_variation_id) {
|
|
110
|
+
payload.data.attributes.maps.push({
|
|
111
|
+
sceneproduct: sceneProduct.id,
|
|
112
|
+
productvariation: product.attributes.product_variation_id
|
|
113
|
+
});
|
|
114
|
+
totalARObjectCount++;
|
|
101
115
|
}
|
|
102
116
|
}
|
|
103
|
-
});
|
|
104
|
-
// add our scene models
|
|
105
|
-
sceneModels.forEach((sceneModel) => {
|
|
106
|
-
if (sceneModel.attributes.include_in_augment) {
|
|
107
|
-
configurator.addModel(sceneModel.id);
|
|
108
|
-
totalARObjectCount++;
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
// ensure we have actually added AR objects
|
|
112
|
-
if (totalARObjectCount <= 0) {
|
|
113
|
-
return reject(new Error("SceneAR.ComposeScene() - cannot proceed as scene does not contain any enabled AR components"));
|
|
114
117
|
}
|
|
115
|
-
return configurator.get().then((result) => {
|
|
116
|
-
accept(result.filename);
|
|
117
|
-
}).catch(reject);
|
|
118
118
|
});
|
|
119
|
+
// add our scene models
|
|
120
|
+
sceneModels.forEach((sceneModel) => {
|
|
121
|
+
if (sceneModel.attributes.include_in_augment) {
|
|
122
|
+
payload.data.attributes.maps.push({
|
|
123
|
+
scenemodel: sceneModel.id
|
|
124
|
+
});
|
|
125
|
+
totalARObjectCount++;
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
// ensure we have actually added AR objects
|
|
129
|
+
if (totalARObjectCount <= 0) {
|
|
130
|
+
throw new Error("SceneAR.ComposeScene() - cannot proceed as scene does not contain any enabled AR components");
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
const response = await fetch(url, {
|
|
134
|
+
method: "POST",
|
|
135
|
+
headers: {
|
|
136
|
+
"Content-Type": "application/json"
|
|
137
|
+
},
|
|
138
|
+
body: JSON.stringify(payload)
|
|
139
|
+
});
|
|
140
|
+
if (!response.ok) {
|
|
141
|
+
throw new Error(`SceneAR.ComposeScene() - network response was not ok ${response.status}`);
|
|
142
|
+
}
|
|
143
|
+
const data = await response.json();
|
|
144
|
+
return data.data.attributes.filename;
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
throw new Error(`SceneAR.ComposeScene() - there was a request error to ${url}, error was ${error.message}`);
|
|
148
|
+
}
|
|
119
149
|
}
|
|
120
150
|
/**
|
|
121
151
|
* Initialise the SceneAR instance. This returns a Promise that resolves
|
|
@@ -131,7 +161,6 @@ class SceneAR extends launcher_ar_1.LauncherAR {
|
|
|
131
161
|
}
|
|
132
162
|
const scene = new plattar_api_1.Scene(this.sceneID);
|
|
133
163
|
scene.include(plattar_api_1.Project);
|
|
134
|
-
scene.include(plattar_api_1.SceneProduct);
|
|
135
164
|
scene.include(plattar_api_1.SceneProduct.include(plattar_api_1.Product));
|
|
136
165
|
scene.include(plattar_api_1.SceneModel);
|
|
137
166
|
scene.get().then((scene) => {
|
|
@@ -17,6 +17,7 @@ const version_1 = __importDefault(require("../version"));
|
|
|
17
17
|
class SceneGraphAR extends launcher_ar_1.LauncherAR {
|
|
18
18
|
// analytics instance
|
|
19
19
|
_analytics = null;
|
|
20
|
+
_analyticsSetup = null;
|
|
20
21
|
_options;
|
|
21
22
|
// this thing controls the actual AR view
|
|
22
23
|
// this is setup via .init() function
|
|
@@ -26,32 +27,37 @@ class SceneGraphAR extends launcher_ar_1.LauncherAR {
|
|
|
26
27
|
this._options = options;
|
|
27
28
|
this._ar = null;
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
30
|
+
_SetupAnalytics() {
|
|
31
|
+
if (this._analyticsSetup !== null)
|
|
32
|
+
return this._analyticsSetup;
|
|
33
|
+
this._analyticsSetup = (async () => {
|
|
34
|
+
const scene = new plattar_api_1.Scene(this._options.sceneID);
|
|
35
|
+
scene.include(plattar_api_1.Project);
|
|
36
|
+
const fetchedScene = await scene.get();
|
|
37
|
+
let analytics = null;
|
|
38
|
+
analytics = new plattar_analytics_1.Analytics(fetchedScene.attributes.application_id);
|
|
39
|
+
analytics.origin = plattar_api_1.Server.location().type;
|
|
40
|
+
this._analytics = analytics;
|
|
41
|
+
analytics.data.push("type", "scene-graph-ar");
|
|
42
|
+
analytics.data.push("sdkVersion", version_1.default);
|
|
43
|
+
analytics.data.push("sceneId", fetchedScene.id);
|
|
44
|
+
analytics.data.push("sceneTitle", fetchedScene.attributes.title);
|
|
45
|
+
const application = fetchedScene.relationships.find(plattar_api_1.Project);
|
|
46
|
+
// setup application stuff (if any)
|
|
47
|
+
if (application) {
|
|
48
|
+
analytics.data.push("applicationId", application.id);
|
|
49
|
+
analytics.data.push("applicationTitle", application.attributes.title);
|
|
50
|
+
if (this._options.useARBanner) {
|
|
51
|
+
this.options.banner = {
|
|
52
|
+
title: application.attributes.title,
|
|
53
|
+
subtitle: fetchedScene.attributes.title,
|
|
54
|
+
button: 'Visit'
|
|
55
|
+
};
|
|
56
|
+
}
|
|
52
57
|
}
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
return fetchedScene;
|
|
59
|
+
})();
|
|
60
|
+
return this._analyticsSetup;
|
|
55
61
|
}
|
|
56
62
|
/**
|
|
57
63
|
* Composes a Scene into an AR Model (remote operation) that can be used to launch
|
|
@@ -11,6 +11,11 @@ export declare class ConfiguratorController extends PlattarController {
|
|
|
11
11
|
startARQRCode(options: any): Promise<HTMLElement>;
|
|
12
12
|
startViewerQRCode(options: QRCodeOptions): Promise<HTMLElement>;
|
|
13
13
|
startRenderer(): Promise<HTMLElement>;
|
|
14
|
+
/**
|
|
15
|
+
* Legacy furniture scenes carry a "product" state entry — the embed is
|
|
16
|
+
* re-created with product attributes and rendering restarts there
|
|
17
|
+
*/
|
|
18
|
+
private _transitionLegacyProduct;
|
|
14
19
|
initAR(): Promise<LauncherAR>;
|
|
15
20
|
/**
|
|
16
21
|
* Private Function - This launches the Static/Inherited AR Mode
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ConfiguratorController = void 0;
|
|
4
4
|
const plattar_api_1 = require("@plattar/plattar-api");
|
|
5
5
|
const scene_product_ar_1 = require("../../ar/scene-product-ar");
|
|
6
|
+
const configurator_state_1 = require("../../util/configurator-state");
|
|
6
7
|
const util_1 = require("../../util/util");
|
|
7
8
|
const plattar_controller_1 = require("./plattar-controller");
|
|
8
9
|
const configurator_ar_1 = require("../../ar/configurator-ar");
|
|
@@ -81,6 +82,11 @@ class ConfiguratorController extends plattar_controller_1.PlattarController {
|
|
|
81
82
|
}
|
|
82
83
|
return Promise.reject(new Error("ConfiguratorController.startARQRCode() - legacy product transition failed"));
|
|
83
84
|
}
|
|
85
|
+
// Kick off scene-graph encoding immediately while we proceed to the base
|
|
86
|
+
// implementation — the result is Promise-cached so no duplicate request is fired
|
|
87
|
+
if (!this.getAttribute("scene-graph-id")) {
|
|
88
|
+
dState.state.encodeSceneGraphID().catch(() => null);
|
|
89
|
+
}
|
|
84
90
|
}
|
|
85
91
|
catch (_err) {
|
|
86
92
|
}
|
|
@@ -202,28 +208,38 @@ class ConfiguratorController extends plattar_controller_1.PlattarController {
|
|
|
202
208
|
// optional attributes
|
|
203
209
|
let configState = null;
|
|
204
210
|
this._state = plattar_controller_1.ControllerState.Renderer;
|
|
205
|
-
|
|
206
|
-
|
|
211
|
+
const suppliedState = this.getAttribute("config-state");
|
|
212
|
+
if (suppliedState) {
|
|
213
|
+
// the state was supplied by the host page — decode it locally
|
|
214
|
+
// rather than paying for the scene fetch getConfiguratorState()
|
|
215
|
+
// performs before the renderer iframe can even be created. The
|
|
216
|
+
// renderer only needs the re-encoded state; the flows that do
|
|
217
|
+
// need the scene (QR/AR) decode on demand and reuse this same
|
|
218
|
+
// instance via _bootConfigState, keeping user mutations.
|
|
219
|
+
configState = configurator_state_1.ConfiguratorState.decode(suppliedState);
|
|
220
|
+
this._bootConfigState = configState;
|
|
207
221
|
// if this is declared, we have a furniture scene that we need to re-create the embed
|
|
208
222
|
// with new attributes
|
|
209
|
-
const product =
|
|
223
|
+
const product = configState.firstOfType("product");
|
|
210
224
|
if (product) {
|
|
211
|
-
this.
|
|
212
|
-
this.parent.destroy();
|
|
213
|
-
this.setAttribute("product-id", product.scene_product_id);
|
|
214
|
-
this.removeAttribute("scene-id");
|
|
215
|
-
this.parent.unlockObserver();
|
|
216
|
-
const controller = this.parent.create();
|
|
217
|
-
if (controller) {
|
|
218
|
-
return controller.startRenderer();
|
|
219
|
-
}
|
|
220
|
-
return Promise.reject(new Error("ConfiguratorController.startRenderer() - legacy product transition failed"));
|
|
225
|
+
return this._transitionLegacyProduct(product);
|
|
221
226
|
}
|
|
222
|
-
configState = dState;
|
|
223
227
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
228
|
+
else {
|
|
229
|
+
try {
|
|
230
|
+
const dState = await this.getConfiguratorState();
|
|
231
|
+
// if this is declared, we have a furniture scene that we need to re-create the embed
|
|
232
|
+
// with new attributes
|
|
233
|
+
const product = dState.state.firstOfType("product");
|
|
234
|
+
if (product) {
|
|
235
|
+
return this._transitionLegacyProduct(product);
|
|
236
|
+
}
|
|
237
|
+
configState = dState.state;
|
|
238
|
+
}
|
|
239
|
+
catch (_err) {
|
|
240
|
+
// config state is not available
|
|
241
|
+
configState = null;
|
|
242
|
+
}
|
|
227
243
|
}
|
|
228
244
|
// required attributes with defaults for plattar-configurator node
|
|
229
245
|
const width = this.getAttribute("width") || "500px";
|
|
@@ -238,7 +254,7 @@ class ConfiguratorController extends plattar_controller_1.PlattarController {
|
|
|
238
254
|
const showAR = this.getAttribute("show-ar");
|
|
239
255
|
const showUI = this.getAttribute("show-ui");
|
|
240
256
|
if (configState) {
|
|
241
|
-
const encodedState = configState.
|
|
257
|
+
const encodedState = configState.encode();
|
|
242
258
|
if (encodedState.length < 6000) {
|
|
243
259
|
viewer.setAttribute("config-state", encodedState);
|
|
244
260
|
}
|
|
@@ -257,6 +273,22 @@ class ConfiguratorController extends plattar_controller_1.PlattarController {
|
|
|
257
273
|
return accept(viewer);
|
|
258
274
|
});
|
|
259
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Legacy furniture scenes carry a "product" state entry — the embed is
|
|
278
|
+
* re-created with product attributes and rendering restarts there
|
|
279
|
+
*/
|
|
280
|
+
async _transitionLegacyProduct(product) {
|
|
281
|
+
this.parent.lockObserver();
|
|
282
|
+
this.parent.destroy();
|
|
283
|
+
this.setAttribute("product-id", product.scene_product_id);
|
|
284
|
+
this.removeAttribute("scene-id");
|
|
285
|
+
this.parent.unlockObserver();
|
|
286
|
+
const controller = this.parent.create();
|
|
287
|
+
if (controller) {
|
|
288
|
+
return controller.startRenderer();
|
|
289
|
+
}
|
|
290
|
+
return Promise.reject(new Error("ConfiguratorController.startRenderer() - legacy product transition failed"));
|
|
291
|
+
}
|
|
260
292
|
async initAR() {
|
|
261
293
|
if (!util_1.Util.canAugment()) {
|
|
262
294
|
throw new Error("ConfiguratorController.initAR() - cannot proceed as AR not available in context");
|
|
@@ -82,16 +82,10 @@ class GalleryController extends plattar_controller_1.PlattarController {
|
|
|
82
82
|
this._prevQROpt = opt;
|
|
83
83
|
if (!opt.detached) {
|
|
84
84
|
this._state = plattar_controller_1.ControllerState.QRCode;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return accept(viewer);
|
|
88
|
-
};
|
|
89
|
-
this.append(viewer);
|
|
90
|
-
});
|
|
85
|
+
this.append(viewer);
|
|
86
|
+
return this._awaitLoad(viewer);
|
|
91
87
|
}
|
|
92
|
-
return
|
|
93
|
-
return accept(viewer);
|
|
94
|
-
});
|
|
88
|
+
return Promise.resolve(viewer);
|
|
95
89
|
}
|
|
96
90
|
async startRenderer() {
|
|
97
91
|
// remove the old renderer instance if any
|
|
@@ -60,6 +60,11 @@ class LauncherController extends plattar_controller_1.PlattarController {
|
|
|
60
60
|
}
|
|
61
61
|
return Promise.reject(new Error("LauncherController.startARQRCode() - legacy product transition failed"));
|
|
62
62
|
}
|
|
63
|
+
// Kick off scene-graph encoding immediately while we proceed to the base
|
|
64
|
+
// implementation — the result is Promise-cached so no duplicate request is fired
|
|
65
|
+
if (!this.getAttribute("scene-graph-id")) {
|
|
66
|
+
dState.state.encodeSceneGraphID().catch(() => null);
|
|
67
|
+
}
|
|
63
68
|
}
|
|
64
69
|
catch (_err) {
|
|
65
70
|
}
|
|
@@ -122,10 +127,10 @@ class LauncherController extends plattar_controller_1.PlattarController {
|
|
|
122
127
|
if (sceneGraphID) {
|
|
123
128
|
viewer.setAttribute("scene-graph-id", sceneGraphID);
|
|
124
129
|
}
|
|
125
|
-
else {
|
|
130
|
+
else if (configState) {
|
|
126
131
|
try {
|
|
127
|
-
const
|
|
128
|
-
viewer.setAttribute("scene-graph-id",
|
|
132
|
+
const encodedID = await configState.state.encodeSceneGraphID();
|
|
133
|
+
viewer.setAttribute("scene-graph-id", encodedID);
|
|
129
134
|
}
|
|
130
135
|
catch (_err) {
|
|
131
136
|
// scene graph ID not available for some reason
|
|
@@ -136,7 +141,7 @@ class LauncherController extends plattar_controller_1.PlattarController {
|
|
|
136
141
|
return new Promise((accept, reject) => {
|
|
137
142
|
this.append(viewer);
|
|
138
143
|
if (configState) {
|
|
139
|
-
this.setupMessengerObservers(viewer, configState);
|
|
144
|
+
this.setupMessengerObservers(viewer, configState.state);
|
|
140
145
|
}
|
|
141
146
|
return accept(viewer);
|
|
142
147
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LauncherAR } from "../../ar/launcher-ar";
|
|
2
|
-
import { DecodedConfiguratorState } from "../../util/configurator-state";
|
|
2
|
+
import { ConfiguratorState, DecodedConfiguratorState } from "../../util/configurator-state";
|
|
3
3
|
import type PlattarEmbed from "../plattar-embed";
|
|
4
4
|
export declare enum ControllerState {
|
|
5
5
|
None = 0,
|
|
@@ -26,6 +26,7 @@ export declare abstract class PlattarController {
|
|
|
26
26
|
protected _state: ControllerState;
|
|
27
27
|
protected _element: HTMLElement | null;
|
|
28
28
|
protected _prevQROpt: any;
|
|
29
|
+
protected _bootConfigState: ConfiguratorState | null;
|
|
29
30
|
private _selectVariationObserver;
|
|
30
31
|
private _selectVariationIDObserver;
|
|
31
32
|
private _selectVariationSKUObserver;
|
|
@@ -51,7 +52,7 @@ export declare abstract class PlattarController {
|
|
|
51
52
|
* Setup messenger observers to detect variation changes and apply to the internal
|
|
52
53
|
* configuration state
|
|
53
54
|
*/
|
|
54
|
-
protected setupMessengerObservers(viewer: any, configState:
|
|
55
|
+
protected setupMessengerObservers(viewer: any, configState: ConfiguratorState): void;
|
|
55
56
|
/**
|
|
56
57
|
* Remove all pre-existing observers
|
|
57
58
|
*/
|
|
@@ -81,6 +82,12 @@ export declare abstract class PlattarController {
|
|
|
81
82
|
* Initialise and return a launcher that can be used to start AR
|
|
82
83
|
*/
|
|
83
84
|
abstract initAR(): Promise<LauncherAR>;
|
|
85
|
+
/**
|
|
86
|
+
* Appends the viewer to the shadow DOM and waits for its onload event.
|
|
87
|
+
* Rejects if onload does not fire within timeoutMs (default 30 s) so
|
|
88
|
+
* callers are never left with a permanently-pending Promise.
|
|
89
|
+
*/
|
|
90
|
+
protected _awaitLoad(viewer: HTMLElement, timeoutMs?: number): Promise<HTMLElement>;
|
|
84
91
|
/**
|
|
85
92
|
* Removes the currently active renderer view from the DOM
|
|
86
93
|
*/
|
|
@@ -32,6 +32,11 @@ class PlattarController {
|
|
|
32
32
|
_state = ControllerState.None;
|
|
33
33
|
_element = null;
|
|
34
34
|
_prevQROpt = null;
|
|
35
|
+
// when the renderer was booted from a supplied config-state attribute the
|
|
36
|
+
// state is decoded locally without the scene fetch — this keeps that live
|
|
37
|
+
// instance (mutated by the messenger observers as the user configures) so
|
|
38
|
+
// a later full decode for QR/AR reuses it instead of losing those changes
|
|
39
|
+
_bootConfigState = null;
|
|
35
40
|
_selectVariationObserver = null;
|
|
36
41
|
_selectVariationIDObserver = null;
|
|
37
42
|
_selectVariationSKUObserver = null;
|
|
@@ -53,7 +58,7 @@ class PlattarController {
|
|
|
53
58
|
// get a list of variation SKU's to use for initialising
|
|
54
59
|
const variationSKUs = this.getAttribute("variation-sku");
|
|
55
60
|
// generate the decoded configurator state
|
|
56
|
-
const decodedState = configState ? await configurator_state_1.ConfiguratorState.decodeState(sceneID, configState) : await configurator_state_1.ConfiguratorState.decodeScene(sceneID);
|
|
61
|
+
const decodedState = configState ? await configurator_state_1.ConfiguratorState.decodeState(sceneID, configState, this._bootConfigState) : await configurator_state_1.ConfiguratorState.decodeScene(sceneID);
|
|
57
62
|
// change the ID's and SKU's (if any) of the default configuration state
|
|
58
63
|
const variationIDList = variationIDs ? variationIDs.split(",") : [];
|
|
59
64
|
const variationSKUList = variationSKUs ? variationSKUs.split(",") : [];
|
|
@@ -76,7 +81,7 @@ class PlattarController {
|
|
|
76
81
|
const args = cd.data[0];
|
|
77
82
|
const variations = args ? (Array.isArray(args) ? args : [args]) : [];
|
|
78
83
|
variations.forEach((variationID) => {
|
|
79
|
-
configState.
|
|
84
|
+
configState.setVariationID(variationID);
|
|
80
85
|
});
|
|
81
86
|
}
|
|
82
87
|
});
|
|
@@ -85,7 +90,7 @@ class PlattarController {
|
|
|
85
90
|
const args = cd.data[0];
|
|
86
91
|
const variations = args ? (Array.isArray(args) ? args : [args]) : [];
|
|
87
92
|
variations.forEach((variationID) => {
|
|
88
|
-
configState.
|
|
93
|
+
configState.setVariationID(variationID);
|
|
89
94
|
});
|
|
90
95
|
}
|
|
91
96
|
});
|
|
@@ -94,7 +99,7 @@ class PlattarController {
|
|
|
94
99
|
const args = cd.data[0];
|
|
95
100
|
const variations = args ? (Array.isArray(args) ? args : [args]) : [];
|
|
96
101
|
variations.forEach((variationSKU) => {
|
|
97
|
-
configState.
|
|
102
|
+
configState.setVariationSKU(variationSKU);
|
|
98
103
|
});
|
|
99
104
|
}
|
|
100
105
|
});
|
|
@@ -216,8 +221,9 @@ class PlattarController {
|
|
|
216
221
|
}
|
|
217
222
|
else {
|
|
218
223
|
try {
|
|
219
|
-
const
|
|
220
|
-
|
|
224
|
+
const configState = await this.getConfiguratorState();
|
|
225
|
+
const encodedID = await configState.state.encodeSceneGraphID();
|
|
226
|
+
dst += "&scene_graph_id=" + encodedID;
|
|
221
227
|
}
|
|
222
228
|
catch (_err) {
|
|
223
229
|
// scene graph ID not available for some reason
|
|
@@ -229,17 +235,29 @@ class PlattarController {
|
|
|
229
235
|
this._prevQROpt = opt;
|
|
230
236
|
if (!opt.detached) {
|
|
231
237
|
this._state = ControllerState.QRCode;
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
viewer.onload = () => {
|
|
235
|
-
return accept(viewer);
|
|
236
|
-
};
|
|
237
|
-
});
|
|
238
|
+
this.append(viewer);
|
|
239
|
+
return this._awaitLoad(viewer);
|
|
238
240
|
}
|
|
239
241
|
return new Promise((accept, reject) => {
|
|
240
242
|
return accept(viewer);
|
|
241
243
|
});
|
|
242
244
|
}
|
|
245
|
+
/**
|
|
246
|
+
* Appends the viewer to the shadow DOM and waits for its onload event.
|
|
247
|
+
* Rejects if onload does not fire within timeoutMs (default 30 s) so
|
|
248
|
+
* callers are never left with a permanently-pending Promise.
|
|
249
|
+
*/
|
|
250
|
+
_awaitLoad(viewer, timeoutMs = 30000) {
|
|
251
|
+
return new Promise((accept, reject) => {
|
|
252
|
+
const timeout = setTimeout(() => {
|
|
253
|
+
reject(new Error("PlattarController._awaitLoad() - element did not fire onload within " + timeoutMs + "ms"));
|
|
254
|
+
}, timeoutMs);
|
|
255
|
+
viewer.onload = () => {
|
|
256
|
+
clearTimeout(timeout);
|
|
257
|
+
accept(viewer);
|
|
258
|
+
};
|
|
259
|
+
});
|
|
260
|
+
}
|
|
243
261
|
/**
|
|
244
262
|
* Removes the currently active renderer view from the DOM
|
|
245
263
|
*/
|
|
@@ -133,16 +133,10 @@ class VTOController extends plattar_controller_1.PlattarController {
|
|
|
133
133
|
this._prevQROpt = opt;
|
|
134
134
|
if (!opt.detached) {
|
|
135
135
|
this._state = plattar_controller_1.ControllerState.QRCode;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
return accept(viewer);
|
|
139
|
-
};
|
|
140
|
-
this.append(viewer);
|
|
141
|
-
});
|
|
136
|
+
this.append(viewer);
|
|
137
|
+
return this._awaitLoad(viewer);
|
|
142
138
|
}
|
|
143
|
-
return
|
|
144
|
-
return accept(viewer);
|
|
145
|
-
});
|
|
139
|
+
return Promise.resolve(viewer);
|
|
146
140
|
}
|
|
147
141
|
async startRenderer() {
|
|
148
142
|
// remove the old renderer instance if any
|
|
@@ -193,7 +187,7 @@ class VTOController extends plattar_controller_1.PlattarController {
|
|
|
193
187
|
return new Promise((accept, reject) => {
|
|
194
188
|
this.append(viewer);
|
|
195
189
|
if (configState) {
|
|
196
|
-
this.setupMessengerObservers(viewer, configState);
|
|
190
|
+
this.setupMessengerObservers(viewer, configState.state);
|
|
197
191
|
}
|
|
198
192
|
return accept(viewer);
|
|
199
193
|
});
|