UNPKG

@swrve/smarttv-sdk

Version:

Swrve marketing engagement platform SDK for SmartTV OTT devices

419 lines (418 loc) 16.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SwrveMessageDisplayManager = void 0; const SwrveConstants = __importStar(require("../../utils/SwrveConstants")); const SwrveConstants_1 = require("../../utils/SwrveConstants"); const SwrveFocusManager_1 = __importDefault(require("../../UIElements/SwrveFocusManager")); const SwrveLogger_1 = __importDefault(require("../../utils/SwrveLogger")); const TextTemplating_1 = require("../../utils/TextTemplating"); const blacklistedCSSAttributes = [ // strip out attributes used for positioning "position", "width", "height", "top", "left", // strip out extra attributes from resources "uid", "name", "description", "thumbnail", "item_class", ].reduce((idx, prop) => { idx[prop] = true; return idx; }, {}); const defaultStyle = { opacity: "0.5", transition: "opacity 150ms ease-out", }; const defaultFocusStyle = { opacity: "1", transition: "opacity 150ms ease-out", }; class SwrveMessageDisplayManager { constructor(platform, config, resourceManager) { this.screenCenterWidth = 0; this.screenCenterHeight = 0; this.onBackButtonClickedCallback = null; this.onButtonClickedCallback = null; this.onPageViewedCallback = null; this.isOpen = false; this.justClosed = false; this.currentPageIndex = 0; this.currentMessagePages = []; this.sentPageViewEvents = []; this.sentNavigationEvents = []; this.imagesCDN = ""; this.scale = 1; this.onKeydown = (ev) => { if (!this.isOpen) { return; } ev.preventDefault(); ev.stopImmediatePropagation(); const key = this.keymap[ev.keyCode]; if (key === "Back") { this.closeMessage(); if (this.onBackButtonClickedCallback) { this.onBackButtonClickedCallback(); } } else if (key && this.focusManager) { this.focusManager.onKeyPress(key); } }; this.onKeyup = (ev) => { // Closing the message will fire up one last "keyup" event // This prevents that keyup event from spreading down to the app if (this.justClosed) { ev.preventDefault(); ev.stopImmediatePropagation(); this.justClosed = false; return; } }; this.normalStyle = config && config.inAppMessageButtonStyle; this.focusStyle = config && config.inAppMessageButtonFocusStyle; this.overrideIAMStyle = config && config.inAppMessageStyleOverride; this.keymap = platform.getKeymapping(); this.resourceManager = resourceManager; this.initListener(); } showMessage(message, parentCampaign, imagesCDN, platform, personalizationProperties) { var _a, _b; this.currentPageIndex = 0; this.currentMessagePages = []; this.sentPageViewEvents = []; this.sentNavigationEvents = []; this.screenCenterWidth = platform.screenWidth / 2; this.screenCenterHeight = platform.screenHeight / 2; this.personalizationProperties = personalizationProperties; const iam = this.getLandscapeFormat(message); if (!iam) return; this.isOpen = true; this.imagesCDN = imagesCDN || ''; this.scale = (_a = iam.scale) !== null && _a !== void 0 ? _a : 1; this.createContainer(message.name, iam.color || undefined); if (iam.pages && ((_b = iam.pages) === null || _b === void 0 ? void 0 : _b.length) > 0) { this.currentMessagePages = iam.pages; this.renderPage(this.currentPageIndex, parentCampaign); } else { this.renderContent(iam.images, iam.buttons, parentCampaign); } } onPageViewed(callback) { this.onPageViewedCallback = callback; } onButtonClicked(callback) { this.onButtonClickedCallback = callback; } onBackButtonClicked(callback) { this.onBackButtonClickedCallback = callback; } isIAMShowing() { return this.isOpen; } getSentPageViewEvents() { return this.sentPageViewEvents; } getSentNavigationEvents() { return this.sentNavigationEvents; } closeMessage() { const container = document.getElementById(SwrveConstants_1.SWRVE_IAM_CONTAINER); if (container) { document.body.removeChild(container); } this.isOpen = false; this.justClosed = true; delete this.focusManager; } initListener() { window.addEventListener("keydown", this.onKeydown, true); window.addEventListener("keyup", this.onKeyup, true); } getLandscapeFormat(message) { const formats = message.template.formats || null; if (formats) { let landscape = null; formats.forEach(format => { if (format.orientation === "landscape") { landscape = format; } }); return landscape; } else { return null; } } createFocusManager(buttons) { return new SwrveFocusManager_1.default(buttons, { direction: "bidirectional", onFocus: (btn) => this.applyElementStyle(btn.element, this.getFocusStyle(this.focusStyle, defaultFocusStyle)), onBlur: (btn) => this.applyElementStyle(btn.element, this.getFocusStyle(this.normalStyle, defaultStyle)), onKeyPress: ({ button, campaign }, key) => { if (key === "Enter") { this.handleButton(button, campaign); return true; } return false; }, }); } applyElementStyle(el, style) { for (const attr in style) { if (style.hasOwnProperty(attr)) { el.style[attr] = style[attr]; } } } getFocusStyle(style, defaults) { let ret = defaults; if (typeof style === "string") { if (this.resourceManager) { const resource = this.resourceManager.getResource(style).toJSON(); if (Object.keys(resource).length !== 0) { ret = this.sanitizeFocusStyle(resource); } } } else if (style) { ret = this.sanitizeFocusStyle(style); } return ret; } sanitizeFocusStyle(style) { const ret = {}; for (const key in style) { if (style.hasOwnProperty(key) && !blacklistedCSSAttributes[key]) { ret[key] = style[key]; } } return ret; } appendImages(images) { images.forEach((image, index) => { var _a; const imageElement = document.createElement("img"); imageElement.id = "SwrveImage" + index; if (image.dynamic_image_url && image.dynamic_image_url.length > 0) { if (this.personalizationProperties) { imageElement.src = (_a = this.personalizeText(image.dynamic_image_url, this.personalizationProperties)) !== null && _a !== void 0 ? _a : ""; } else { imageElement.src = image.dynamic_image_url; } } else { imageElement.src = this.imagesCDN + image.image.value; } this.addElement(image, imageElement); }); } appendButtons(buttons, parentCampaign) { return buttons.map((button, index) => { const buttonElement = document.createElement("img"); const buttonStyle = this.getFocusStyle(this.normalStyle, defaultStyle); const personalizedButton = this.personalizeButton(button); buttonElement.id = "SwrveButton" + index; if (personalizedButton.dynamic_image_url && personalizedButton.dynamic_image_url.length > 0) { buttonElement.src = personalizedButton.dynamic_image_url; } else { buttonElement.src = this.imagesCDN + personalizedButton.image_up.value; } buttonElement.style.border = "0px"; buttonElement.onclick = () => this.handleButton(personalizedButton, parentCampaign); this.applyElementStyle(buttonElement, buttonStyle); this.addElement(button, buttonElement); return { button, campaign: parentCampaign, element: buttonElement, }; }); } addElement(swrveItem, element) { if (typeof swrveItem.x.value === "number" && typeof swrveItem.y.value === "number") { const container = document.getElementById(SwrveConstants_1.SWRVE_IAM_CONTAINER); let width = element.naturalWidth * this.scale; let height = element.naturalHeight * this.scale; if (swrveItem.dynamic_image_url) { width = swrveItem.w.value * this.scale; height = swrveItem.h.value * this.scale; //Aspect fit const aspectRatio = element.naturalWidth / element.naturalHeight; if (width / height > aspectRatio) { width = height * aspectRatio; } else { height = width / aspectRatio; } } const yPos = swrveItem.y.value; const xPos = swrveItem.x.value; if (width > height) { element.style.width = width.toString() + "px"; } else { element.style.height = height.toString() + "px"; } element.style.position = "absolute"; element.style.top = (yPos + (this.screenCenterHeight - (height / 2))).toString() + "px"; element.style.left = (xPos + (this.screenCenterWidth - (width / 2))).toString() + "px"; if (swrveItem.accessibility_text) { if (this.personalizationProperties) { const personalizedAltText = this.personalizeText(swrveItem.accessibility_text, this.personalizationProperties); if (personalizedAltText) { element.alt = personalizedAltText; } } else { element.alt = swrveItem.accessibility_text; } } container.appendChild(element); } } handleButton(button, parentCampaign) { const type = String(button.type.value); const action = String(button.action.value); const pageId = this.getCurrentPageId(); const pageName = this.getCurrentPageName(); if (type === SwrveConstants.PAGE_LINK) { const num = Number(action); this.changePage(num, parentCampaign); } else { this.closeMessage(); } if (this.onButtonClickedCallback) { this.onButtonClickedCallback(button, parentCampaign, pageId, pageName); } } createContainer(name, color) { const iamContainer = document.createElement("div"); iamContainer.id = SwrveConstants_1.SWRVE_IAM_CONTAINER; iamContainer.className = SwrveConstants_1.IAM_CSS_CLASS_NAME; iamContainer.innerHTML = this.overrideIAMStyle || SwrveConstants_1.DEFAULT_IAM_STYLE; iamContainer.style.backgroundColor = color || ""; document.body.appendChild(iamContainer); } changePage(newPageId, parentCampaign) { const newPageIndex = this.currentMessagePages.findIndex(page => page.page_id === newPageId); if (newPageIndex !== -1) { this.currentPageIndex = newPageIndex; this.renderPage(newPageIndex, parentCampaign); } } renderPage(pageIndex, parentCampaign) { var _a; const container = document.getElementById(SwrveConstants_1.SWRVE_IAM_CONTAINER); if (!container) return; // Cache and reapply style content const styleContent = ((_a = container.querySelector("style")) === null || _a === void 0 ? void 0 : _a.outerHTML) || ""; container.innerHTML = styleContent; const page = this.currentMessagePages[pageIndex]; if (page) { this.renderContent(page.images, page.buttons, parentCampaign); } } renderContent(images, buttons, parentCampaign) { if (images && images.length > 0) { this.appendImages(images); } if (buttons && buttons.length > 0) { const buttonElements = this.appendButtons(buttons, parentCampaign); this.focusManager = this.createFocusManager(buttonElements); this.focusManager.setActiveFirst(); } if (this.onPageViewedCallback) { const messageId = parentCampaign.messages && parentCampaign.messages[0] ? parentCampaign.messages[0].id : 0; const page = this.currentMessagePages[this.currentPageIndex]; if (page) { this.onPageViewedCallback(messageId, page.page_id, page.page_name); } else { this.onPageViewedCallback(messageId, 0, ""); } } } getCurrentPageId() { if (!this.currentMessagePages || this.currentMessagePages.length === 0) { return ""; } if (this.currentPageIndex < 0 || this.currentPageIndex >= this.currentMessagePages.length) { return ""; } const page = this.currentMessagePages[this.currentPageIndex]; return page.page_id.toString(); } getCurrentPageName() { if (!this.currentMessagePages || this.currentMessagePages.length === 0) { return ""; } if (this.currentPageIndex < 0 || this.currentPageIndex >= this.currentMessagePages.length) { return ""; } const page = this.currentMessagePages[this.currentPageIndex]; return page.page_name; } personalizeButton(button) { var _a; if (this.personalizationProperties == null) { return button; } let personalizedButton = button; if (button.type.value === SwrveConstants.CUSTOM && ((_a = button.action) === null || _a === void 0 ? void 0 : _a.value) && typeof button.action.value === 'string') { const personalizedAction = this.personalizeText(button.action.value, this.personalizationProperties); if (personalizedAction) { personalizedButton = JSON.parse(JSON.stringify(button)); personalizedButton.action.value = personalizedAction; } } if (button.dynamic_image_url) { const personalizedUrl = this.personalizeText(button.dynamic_image_url, this.personalizationProperties); if (personalizedUrl) { if (!personalizedButton) { personalizedButton = JSON.parse(JSON.stringify(button)); } personalizedButton.dynamic_image_url = personalizedUrl; } } return personalizedButton; } personalizeText(text, personalizationProperties) { if (text != null) { try { return TextTemplating_1.TextTemplating.applyTextTemplatingToString(text, personalizationProperties); } catch (e) { SwrveLogger_1.default.error("Could not resolve, error with personalization", e); } } return null; } } exports.SwrveMessageDisplayManager = SwrveMessageDisplayManager;