UNPKG

@nitrogenbuilder/client-php

Version:

Nitrogen Builder PHP Client

223 lines (189 loc) 5.83 kB
import type * as nitrogenTypes from '@nitrogenbuilder/types'; import type { RequestedPageData } from '@nitrogenbuilder/types/socket-server'; import { logger } from './utils/logger.js'; // USED IN CLIENT SIDE PHP apps declare global { interface Window { /** * This type is available within the client, not the editor or server. */ nitrogenPHPClient?: { pageRequestURL?: string; pageId?: string | number; }; } } // Host, token come from window.location type Params = Omit<RequestedPageData, 'id' | 'host' | 'token'>; // TODO: This should change depending on what we are editing in nitrogen (page, header, footer, etc.) const nitrogenLocation = 'page'; function init(requestedData: Params) { // if we are not in builder return and use the data passed in (page data from server) const urlParams = new URLSearchParams(window.location.search); const isBuilder = urlParams.get('nitrogen-builder'); // TODO: Add isPreview urlParams thing or something here to also get live updates when previewing. if (!isBuilder) { return; } function debouncedRequestPageUrl(timeout = 750) { let timer: NodeJS.Timeout; let locationElement = document.querySelector( '[data-nitrogen-location="' + nitrogenLocation + '"]' ) as HTMLDivElement; let preOpacity = locationElement.style.opacity; return (newData: { data: any }) => { if (!locationElement) { locationElement = document.querySelector( '[data-nitrogen-location="' + nitrogenLocation + '"]' ) as HTMLDivElement; } if (locationElement) { locationElement.style.opacity = '.5'; } clearTimeout(timer); timer = setTimeout(() => { requestPageUrl2(newData); if (locationElement) { if (preOpacity) locationElement.style.opacity = preOpacity; else locationElement.style.removeProperty('opacity'); } }, timeout); }; } const requestPageUrl = debouncedRequestPageUrl(); async function requestPageUrl2(newData: { data: any }) { if (!window.nitrogenPHPClient?.pageRequestURL) { throw new Error('No pageRequestURL found in window.nitrogenPHPClient'); } if (!window.nitrogenPHPClient?.pageId) { throw new Error('No pageId found in window.nitrogenPHPClient'); } const locationElement = document.querySelector( '[data-nitrogen-location="' + nitrogenLocation + '"]' ); if (!locationElement) { logger.error( 'No location element found for nitrogenLocation', nitrogenLocation ); return; } const res = await fetch(window.nitrogenPHPClient.pageRequestURL, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ pageData: newData.data, requestedData: { ...requestedData, id: window.nitrogenPHPClient.pageId, }, }), }); if (!res.ok) { throw new Error('Failed to fetch page data'); } const html = await res.text(); locationElement.innerHTML = html; window.dispatchEvent(new CustomEvent('nitrogen-page-data')); } async function windowOnMessage(event: MessageEvent<any>) { logger.log('windowOnMessage', event); if (!event.data) { return; } let data; try { data = JSON.parse(event.data); } catch (e) { return; } if (data.channel !== 'nitrogen-builder') { return; } if (data.type === 'corePageData') { logger.log('got corePageData from iframe', data.data); if (typeof window !== 'undefined') { window.dispatchEvent( new CustomEvent('nitrogen-page-data', { detail: { data: data.data, requestedData }, }) ); } // TODO: Reload page with new data. try { requestPageUrl(data); } catch (e) { logger.error(e instanceof Error ? e.message : e); } } else if (data.type === 'patchPageData') { logger.log('got patchPageData from iframe', data.page); if (typeof window !== 'undefined') { window.dispatchEvent( new CustomEvent('nitrogen-page-data', { detail: { data: data.data, requestedData }, }) ); } // TODO: Reload page with new data. try { requestPageUrl(data); } catch (e) { logger.error(e instanceof Error ? e.message : e); } } else if (data.type === 'patchDynamicData') { const dynamicData = data.dynamicData; // TODO: Reload page with new data. const newData = { ...data, dynamicData: { ...data.dynamicData, ...dynamicData.dynamicData, }, }; try { requestPageUrl(newData); } catch (e) { logger.error(e instanceof Error ? e.message : e); } } else if (data.type === 'usersJoined') { if (!window.nitrogen) return; window.nitrogen.users = { ...window.nitrogen.users, ...data.users }; } else if (data.type === 'userLeft') { if (!window.nitrogen) return; const newUsers = { ...window.nitrogen.users }; delete newUsers[data.userSocketId]; window.nitrogen.users = newUsers; } else if (data.type === 'startScreenUsage') { if (!window.nitrogen) return; const newScreenUsage = [...window.nitrogen.screenUsage, data.screenUsage]; window.nitrogen.screenUsage = newScreenUsage; } else if (data.type === 'setScreenUsage') { if (!window.nitrogen) return; window.nitrogen.screenUsage = data.screenUsage; } else if (data.type === 'stopScreenUsage') { if (!window.nitrogen) return; const newScreenUsage = window.nitrogen.screenUsage.filter((usage) => { return !( usage.screen === data.screenUsage.screen && usage.socketId === data.screenUsage.socketId ); }); window.nitrogen.screenUsage = newScreenUsage; } } function setup() { if (!window.nitrogen) { logger.log('window.nitrogen is undefined'); setTimeout(setup, 100); return; } logger.log('connecting window to iFrame message listener'); window.addEventListener('message', windowOnMessage); } setup(); } init({ type: nitrogenLocation, });