@plattar/plattar-ar-adapter
Version:
Plattar AR Adapter for interfacing with Google & Apple WebAR
328 lines (327 loc) • 14.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfiguratorController = void 0;
const plattar_api_1 = require("@plattar/plattar-api");
const scene_product_ar_1 = require("../../ar/scene-product-ar");
const util_1 = require("../../util/util");
const plattar_controller_1 = require("./plattar-controller");
const configurator_ar_1 = require("../../ar/configurator-ar");
const scene_graph_ar_1 = require("../../ar/scene-graph-ar");
/**
* Manages an instance of the <plattar-configurator> HTML Element
*/
class ConfiguratorController extends plattar_controller_1.PlattarController {
constructor() {
super(...arguments);
this._cachedConfigState = null;
}
async getConfiguratorState() {
if (this._cachedConfigState) {
return this._cachedConfigState;
}
this._cachedConfigState = this.createConfiguratorState();
return this._cachedConfigState;
}
async onAttributesUpdated(attributeName) {
const state = this._state;
if (state === plattar_controller_1.ControllerState.Renderer) {
const viewer = this.element;
if (viewer) {
if (attributeName === "variation-id") {
const variationIDs = this.getAttribute("variation-id");
const variationIDsList = variationIDs ? variationIDs.split(",") : [];
if (variationIDsList.length > 0) {
await viewer.messenger.selectVariationID(variationIDsList);
}
}
if (attributeName === "variation-sku") {
const variationSKUs = this.getAttribute("variation-sku");
const variationSKUList = variationSKUs ? variationSKUs.split(",") : [];
if (variationSKUList.length > 0) {
await viewer.messenger.selectVariationSKU(variationSKUList);
}
}
}
return;
}
// re-render the QR Code when attributes have changed
if (state === plattar_controller_1.ControllerState.QRCode) {
if (attributeName === "variation-id") {
const configState = await this.getConfiguratorState();
const variationIDs = this.getAttribute("variation-id");
const variationIDsList = variationIDs ? variationIDs.split(",") : [];
variationIDsList.forEach((variationID) => {
configState.state.setVariationID(variationID);
});
}
if (attributeName === "variation-sku") {
const configState = await this.getConfiguratorState();
const variationSKUs = this.getAttribute("variation-sku");
const variationSKUList = variationSKUs ? variationSKUs.split(",") : [];
variationSKUList.forEach((variationSKU) => {
configState.state.setVariationSKU(variationSKU);
});
}
this.startQRCode(this._prevQROpt);
return;
}
}
async startARQRCode(options) {
try {
const dState = await this.getConfiguratorState();
// if this is declared, we have a furniture scene that we need to re-create the embed
// with new attributes
const product = dState.state.firstOfType("product");
if (product) {
this.parent.lockObserver();
this.parent.destroy();
this.setAttribute("product-id", product.scene_product_id);
this.removeAttribute("scene-id");
this.parent.unlockObserver();
const controller = this.parent.create();
if (controller) {
return controller.startARQRCode(options);
}
return Promise.reject(new Error("ConfiguratorController.startARQRCode() - legacy product transition failed"));
}
}
catch (_err) {
}
return super.startARQRCode(options);
}
async startViewerQRCode(options) {
const opt = this._GetDefaultQROptions(options);
// remove the old renderer instance if any
if (!opt.detached) {
this.removeRenderer();
}
const sceneID = this.getAttribute("scene-id");
if (!sceneID) {
throw new Error("ConfiguratorController.startViewerQRCode() - minimum required attributes not set, use scene-id as a minimum");
}
// optional attributes
let configState = null;
try {
const dState = await this.getConfiguratorState();
// if this is declared, we have a furniture scene that we need to re-create the embed
// with new attributes
const product = dState.state.firstOfType("product");
if (product) {
this.parent.lockObserver();
this.parent.destroy();
this.setAttribute("product-id", product.scene_product_id);
this.removeAttribute("scene-id");
this.parent.unlockObserver();
const controller = this.parent.create();
if (controller) {
return controller.startViewerQRCode(options);
}
return Promise.reject(new Error("ConfiguratorController.startViewerQRCode() - legacy product transition failed"));
}
configState = dState.state.encode();
}
catch (_err) {
// config state is not available
configState = null;
}
const viewer = document.createElement("plattar-qrcode");
if (!opt.detached) {
this._element = viewer;
}
// required attributes with defaults for plattar-viewer node
const width = this.getAttribute("width") || "500px";
const height = this.getAttribute("height") || "500px";
viewer.setAttribute("width", width);
viewer.setAttribute("height", height);
if (opt.color) {
viewer.setAttribute("color", opt.color);
}
if (opt.margin) {
viewer.setAttribute("margin", "" + opt.margin);
}
if (opt.qrType) {
viewer.setAttribute("qr-type", opt.qrType);
}
viewer.setAttribute("shorten", (opt.shorten && (opt.shorten === true || opt.shorten === "true")) ? "true" : "false");
let dst = plattar_api_1.Server.location().base + "renderer/configurator.html?scene_id=" + sceneID;
const showAR = this.getAttribute("show-ar");
const showUI = this.getAttribute("show-ui");
const showBanner = this.getAttribute("show-ar-banner");
const sceneGraphID = this.getAttribute("scene-graph-id");
if (showUI && showUI === "true") {
dst = plattar_api_1.Server.location().base + "configurator/dist/index.html?scene_id=" + sceneID;
}
if (configState) {
dst += "&config_state=" + configState;
}
if (showAR) {
dst += "&show_ar=" + showAR;
}
if (showBanner) {
dst += "&show_ar_banner=" + showBanner;
}
if (sceneGraphID) {
dst += "&scene_graph_id=" + sceneGraphID;
}
viewer.setAttribute("url", opt.url || dst);
this._prevQROpt = opt;
if (!opt.detached) {
this._state = plattar_controller_1.ControllerState.QRCode;
return new Promise((accept, reject) => {
viewer.onload = () => {
return accept(viewer);
};
this.append(viewer);
});
}
return new Promise((accept, reject) => {
return accept(viewer);
});
}
async startRenderer() {
// remove the old renderer instance if any
this.removeRenderer();
const sceneID = this.getAttribute("scene-id");
if (!sceneID) {
throw new Error("ConfiguratorController.startRenderer() - minimum required attributes not set, use scene-id as a minimum");
}
// optional attributes
let configState = null;
this._state = plattar_controller_1.ControllerState.Renderer;
try {
const dState = await this.getConfiguratorState();
// if this is declared, we have a furniture scene that we need to re-create the embed
// with new attributes
const product = dState.state.firstOfType("product");
if (product) {
this.parent.lockObserver();
this.parent.destroy();
this.setAttribute("product-id", product.scene_product_id);
this.removeAttribute("scene-id");
this.parent.unlockObserver();
const controller = this.parent.create();
if (controller) {
return controller.startRenderer();
}
return Promise.reject(new Error("ConfiguratorController.startRenderer() - legacy product transition failed"));
}
configState = dState;
}
catch (_err) {
// config state is not available
configState = null;
}
// required attributes with defaults for plattar-configurator node
const width = this.getAttribute("width") || "500px";
const height = this.getAttribute("height") || "500px";
const server = this.getAttribute("server") || "production";
const viewer = document.createElement("plattar-configurator");
this._element = viewer;
viewer.setAttribute("width", width);
viewer.setAttribute("height", height);
viewer.setAttribute("server", server);
viewer.setAttribute("scene-id", sceneID);
const showAR = this.getAttribute("show-ar");
const showUI = this.getAttribute("show-ui");
if (configState) {
const encodedState = configState.state.encode();
if (encodedState.length < 6000) {
viewer.setAttribute("config-state", encodedState);
}
}
if (showAR) {
viewer.setAttribute("show-ar", showAR);
}
if (showUI) {
viewer.setAttribute("show-ui", showUI);
}
return new Promise((accept, reject) => {
this.append(viewer);
if (configState) {
this.setupMessengerObservers(viewer, configState);
}
return accept(viewer);
});
}
async initAR() {
if (!util_1.Util.canAugment()) {
throw new Error("ConfiguratorController.initAR() - cannot proceed as AR not available in context");
}
try {
const dState = await this.getConfiguratorState();
// if this is declared, we have a furniture scene that we need to re-create the embed
// with new attributes
const product = dState.state.firstOfType("product");
if (product) {
this.parent.lockObserver();
this.parent.destroy();
this.setAttribute("product-id", product.scene_product_id);
this.removeAttribute("scene-id");
this.parent.unlockObserver();
const controller = this.parent.create();
if (controller) {
return controller.initAR();
}
return Promise.reject(new Error("ConfiguratorController.initAR() - legacy product transition failed"));
}
}
catch (_err) {
// config state is not available
}
const arMode = this.getAttribute("ar-mode") || "generated";
switch (arMode.toLowerCase()) {
case "inherited":
return this._InitARInherited();
case "generated":
default:
return this._InitARGenerated();
}
}
/**
* Private Function - This launches the Static/Inherited AR Mode
*/
async _InitARInherited() {
const sceneID = this.getAttribute("scene-id");
if (!sceneID) {
throw new Error("ConfiguratorController.initAR() - inherited AR minimum required attributes not set, use scene-id as a minimum");
}
const state = (await this.getConfiguratorState()).state;
const first = state.firstActiveOfType("sceneproduct");
if (first) {
//const sceneProductAR: SceneProductAR = new SceneProductAR(first.scene_product_id, first.product_variation_id);
const sceneProductAR = new scene_product_ar_1.SceneProductAR({
productID: first.scene_product_id,
variationID: first.product_variation_id,
variationSKU: null,
useARBanner: this.getBooleanAttribute("show-ar-banner")
});
return sceneProductAR.init();
}
throw new Error("ConfiguratorController.initAR() - invalid decoded config-state does not have any product states");
}
/**
* Private Function - This launches the Dynamic/Generated AR Mode
*/
async _InitARGenerated() {
const sceneID = this.getAttribute("scene-id");
if (!sceneID) {
throw new Error("VTOController.initAR() - generated AR minimum required attributes not set, use scene-id as a minimum");
}
const graphID = this.getAttribute("scene-graph-id");
// use the scene-graph route if available
if (graphID) {
const configAR = new scene_graph_ar_1.SceneGraphAR({
useARBanner: this.getBooleanAttribute("show-ar-banner"),
id: graphID,
sceneID: sceneID
});
return configAR.init();
}
const configAR = new configurator_ar_1.ConfiguratorAR({ state: await this.getConfiguratorState(), useARBanner: this.getBooleanAttribute("show-ar-banner") });
return configAR.init();
}
get element() {
return this._element;
}
}
exports.ConfiguratorController = ConfiguratorController;