UNPKG

@zootools/waitlist-js

Version:

Viral whitelists / waitlists for nfts and web3 projects

353 lines (312 loc) 9.83 kB
const FORM_ENDPOINT = "https://form.waitlistpanda.com/go"; const API_ENDPOINT = "https://api.waitlistpanda.com"; const WRAPPER_ID = "WaitlistPanda-wrapper"; const SPINNER_ID = "WaitlistPanda-spinner"; const IFRAME_ID = "WaitlistPanda-form"; const OVERLAY_ID = "WaitlistPanda-overlay"; const FORM_DATA_KEY = "waitlist-id"; async function checkUser(email: string, listId: string) { // API on Waitlist panda... Protect this endpoint and only have this endpoint for a given domain. const hasAccess = await fetch( `${API_ENDPOINT}/lists/${listId}/members/${email}/has_access` ).catch((error) => console.log(error)); return hasAccess; } function addGlobalStyles() { const styles = ` @-webkit-keyframes hinge { 0% { opacity: 0; -webkit-transform: scale3d(0.8, 0.8, 0.8); transform: scale3d(0.8, 0.8, 0.8); } 75% { opacity: 1; -webkit-transform: scale3d(1.05, 1.05, 1.05); transform: scale3d(1.05, 1.05, 1.05); } 100% { opacity: 1; -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } @keyframes hinge { 0% { opacity: 0; -webkit-transform: scale3d(0.8, 0.8, 0.8); transform: scale3d(0.8, 0.8, 0.8); } 75% { opacity: 1; -webkit-transform: scale3d(1.05, 1.05, 1.05); transform: scale3d(1.05, 1.05, 1.05); } 100% { opacity: 1; -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } @-webkit-keyframes load8 { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } @keyframes load8 { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } @-webkit-keyframes wrapperAnimation { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } @keyframes wrapperAnimation { 0% { opacity: 0; } 100% { opacity: 1; } } #${SPINNER_ID}, #${SPINNER_ID}:after { border-radius: 50%; width: 50px; height: 50px; } #${SPINNER_ID} { margin: 60px auto; font-size: 10px; position: relative; z-index: 2; text-indent: -9999em; border-top: 7px solid rgba(255, 255, 255, 0.6); border-right: 7px solid rgba(255, 255, 255, 0.6); border-bottom: 7px solid rgba(255, 255, 255, 0.6); border-left: 7px solid #ffffff; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); -webkit-animation: load8 1.1s infinite linear; animation: load8 1.1s infinite linear; } `; const styleSheet = document.createElement("style"); styleSheet.innerText = styles; document.head.appendChild(styleSheet); } interface PopupOptions { showSpinner?: boolean; } function showPopup( iframe: HTMLIFrameElement, options: PopupOptions = { showSpinner: true } ) { const wrapper = document.getElementById(WRAPPER_ID) as HTMLIFrameElement; const overlay = document.getElementById(OVERLAY_ID) as HTMLIFrameElement; const spinner = document.getElementById(SPINNER_ID) as HTMLIFrameElement; iframe.style.opacity = "0"; wrapper.style.display = "flex"; overlay.style.opacity = "1"; wrapper.style.animation = "wrapperAnimation 200ms ease-in-out"; if (options.showSpinner) { spinner.style.display = "block"; } } function showIframe(iframe: HTMLIFrameElement) { iframe.style.animation = "hinge 400ms ease-in-out"; iframe.style.opacity = "1"; const spinner = document.getElementById(SPINNER_ID); setTimeout(() => { if (spinner) { spinner.style.display = "none"; } }, 250); } function hideIframe(iframe: HTMLIFrameElement) { iframe.style.animation = ""; iframe.style.opacity = "0"; } function hidePopup(iframe: HTMLIFrameElement) { const wrapper = document.getElementById(WRAPPER_ID) as HTMLIFrameElement; const overlay = document.getElementById(OVERLAY_ID) as HTMLIFrameElement; const spinner = document.getElementById(SPINNER_ID) as HTMLIFrameElement; hideIframe(iframe); wrapper.style.animation = ""; wrapper.style.display = "none"; overlay.style.opacity = "0"; spinner.style.display = "none"; } function createPopup(url: string) { var wrapper = document.createElement("div"); wrapper.style.alignItems = "center"; wrapper.style.backgroundColor = "100%"; wrapper.style.display = "flex"; wrapper.style.height = "100%"; wrapper.style.justifyContent = "center"; wrapper.style.left = "0"; wrapper.style.position = "fixed"; wrapper.style.top = "0"; wrapper.style.width = "100%"; wrapper.style.zIndex = "100"; wrapper.id = WRAPPER_ID; var overlay = document.createElement("div"); overlay.style.width = "100%"; overlay.style.height = "100%"; overlay.style.backgroundColor = "#333333c4"; overlay.style.position = "absolute"; overlay.style.inset = "0"; overlay.style.opacity = "0"; overlay.style.animation = ""; overlay.style.zIndex = "1"; overlay.style.transition = "opacity 0.25s ease-in-out"; overlay.id = OVERLAY_ID; wrapper.appendChild(overlay); var spinner = buildLoaderIcon(); wrapper.appendChild(spinner); var ifrm = document.createElement("iframe"); ifrm.setAttribute("src", url); ifrm.allow = "autoplay; clipboard-read; picture-in-picture; clipboard-write"; ifrm.allowFullscreen = true; ifrm.style.maxWidth = "540px"; ifrm.style.width = "100%"; ifrm.style.height = "520px"; ifrm.style.position = "absolute"; ifrm.style.background = "#fff"; ifrm.style.zIndex = "3"; ifrm.style.border = "none"; ifrm.style.borderRadius = "8px"; ifrm.style.overflow = "hidden"; ifrm.style.opacity = "0"; ifrm.id = IFRAME_ID; ifrm.onclose = () => { }; ifrm.onload = () => { // console.log("iframe onloaded!"); showIframe(ifrm); }; wrapper.appendChild(ifrm); // Event listenters for the modal overlay.onclick = () => { const isLoading = window.getComputedStyle(spinner, null).display === "block"; if (!isLoading) { hidePopup(ifrm); } }; // Add the whole wrapper into the UI... document.body.appendChild(wrapper); showPopup(ifrm); addGlobalStyles(); } function updateIframeUrl(iframe: HTMLIFrameElement, url: string) { iframe.setAttribute("src", url); } function hasIframeTargetUrl(iframe: HTMLIFrameElement, url: string) { return iframe.src === url; } function launchAndCreatePopup(url: string) { const popup = document.getElementById(WRAPPER_ID) as HTMLIFrameElement; if (popup) { const iframe = document.getElementById(IFRAME_ID) as HTMLIFrameElement; if (!hasIframeTargetUrl(iframe, url)) { showPopup(iframe); updateIframeUrl(iframe, url); } else { showPopup(iframe, { showSpinner: false }); showIframe(iframe); } } else { createPopup(url); } } function handleClickButton(event: any, url: string) { event.preventDefault(); launchAndCreatePopup(url) } const buildLoaderIcon = () => { // const fillColor = "#fff" const loaderIcon = document.createElement("div"); loaderIcon.id = SPINNER_ID; return loaderIcon; }; function getButtons() { return document.querySelectorAll(`[data-${FORM_DATA_KEY}]`); } function runWaitlistScript() { const elements = getButtons(); elements.forEach((element: any) => { const { waitlistId } = element.dataset; const listId = waitlistId; const formUrl = `${FORM_ENDPOINT}/${listId}`; element.onclick = function (event: any) { handleClickButton(event, formUrl); }; element.dataset.wlLoaded = "true"; }); } function loadScript() { // https://stackoverflow.com/a/807997 // @ts-ignore: Unreachable code error if (window.attachEvent as any) { // @ts-ignore: Unreachable code error window.attachEvent("onload", runWaitlistScript); } else { if (window.onload) { var curronload = window.onload; var newonload = (evt: any) => { // @ts-ignore: Unreachable code error curronload(evt); // @ts-ignore: Unreachable code error runWaitlistScript(evt); }; window.onload = newonload; // @ts-ignore: Unreachable code error } else { window.onload = runWaitlistScript; } } } function listenEvents() { document.addEventListener("DOMContentLoaded", runWaitlistScript, false); if ( document.readyState === "interactive" || document.readyState === "complete" ) { runWaitlistScript(); } } function init() { if (typeof window === "undefined") { return; } loadScript(); // Listen events to re-create the popup actions on page change. listenEvents(); } function openPopup(listId: string) { const formUrl = `${FORM_ENDPOINT}/${listId}`; launchAndCreatePopup(formUrl) } export default { checkUser, init, openPopup, };