script>
(function() {
// ---------- Config ----------
const DEFAULT_BACK_TEXT = 'Close'; // change if you want a different default label
// Single video config (shared across plans)
const SHARED_CONTENT = [
{
id: 'welcome',
headline: 'Look At You Go!',
videoUrl: 'https://player.vimeo.com/video/1145016192?h=1f7fa29654',
maxVisits: 3,
// backText: 'Close',
// aspect: '9/16'
// bodyHtml: 'Optional extra HTML content below the video'
}
];
const CONTENT_BY_PLAN = {
'9d8bee4e-34ed-4438-ae64-878dd047bb66': SHARED_CONTENT,
'6225df57-7bf3-4c65-b6f4-2a2c03ec2d56': SHARED_CONTENT,
'da843023-ccd0-4891-becd-cfbe8df0fdb6': SHARED_CONTENT,
'e99cb98c-6658-440e-b363-ca65523c294a': SHARED_CONTENT,
'16732d29-0e38-4916-a4bd-bd825e4665a2': SHARED_CONTENT,
'1733413b-dbf3-4a0b-9c44-fbcb785ecd95': SHARED_CONTENT,
// 'ADD_ANOTHER_PLAN_UUID': SHARED_CONTENT,
};
// ---------- Key prefixes (scoped per user) ----------
const PLAN_COUNT_PREFIX = 'welcomePopupCount_forUserPlan_';
const SESSION_SHOWN_PREFIX = 'welcomePopupShown_forUser_';
// ---------- Utils ----------
const readCount = k => (isNaN(parseInt(localStorage.getItem(k),10)) ? 0 : parseInt(localStorage.getItem(k),10));
const incrementCount = k => localStorage.setItem(k, String(readCount(k)+1));
function getUserKey(me){
const parts=[me && (me.uuid||me.user_uuid||me.id), me && (me.email||me.username)].filter(Boolean);
return (parts.join('_')||'unknownUser').toLowerCase();
}
// ---------- Aspect helpers ----------
function parseAspect(s){
const m = (s||'16/9').match(/^\s*(\d+)\s*\/\s*(\d+)\s*$/);
return {w: +m[1], h:+m[2]};
}
const aspectToPaddingPercent = ({w,h}) => (h / w) * 100;
// ---------- Media helpers ----------
// Keeps Vimeo player URLs (incl. ?h= token) intact; still normalizes watch/short YouTube links.
function normalizeEmbedUrl(url){
let u = url;
if (u.includes('player.vimeo.com/')) return u; // keep query string
if (u.includes('youtube.com/watch?v=')) u = u.replace('watch?v=','embed/');
else if (u.includes('youtu.be/')) u = u.replace('youtu.be/','www.youtube.com/embed/');
else if (u.includes('vimeo.com/')) {
const m = /vimeo\.com\/(\d+)/.exec(u);
if (m && m[1]) u = 'https://player.vimeo.com/video/' + m[1];
}
return u;
}
// ---------- Render body ----------
function renderPopupBody(pkg) {
const ar = parseAspect(pkg.aspect);
const padding = aspectToPaddingPercent(ar).toFixed(6);
const embedUrl = normalizeEmbedUrl(pkg.videoUrl);
const mediaHtml = (embedUrl.includes('youtube.com') || embedUrl.includes('vimeo.com'))
? ``
: ``;
return `
${pkg.bodyHtml || ''}
`;
}
// ---------- Post-render enforcement ----------
function enforceEmbedSizing(root=document){
root.querySelectorAll('.ma-embed-AR').forEach(wrap=>{
wrap.style.setProperty('position','relative','important');
wrap.style.setProperty('width','100%','important');
wrap.style.setProperty('height','300px','important');
wrap.style.setProperty('overflow','hidden','important');
const media = wrap.querySelector('.ma-embed-media');
if(media){
media.style.setProperty('position','absolute','important');
media.style.setProperty('top','0','important');
media.style.setProperty('left','0','important');
media.style.setProperty('width','100%','important');
media.style.setProperty('height','100%','important');
media.style.setProperty('border','0','important');
media.style.setProperty('display','block','important');
media.style.setProperty('max-width','none','important');
media.style.setProperty('max-height','none','important');
media.removeAttribute('width');
media.removeAttribute('height');
}
});
}
// ---------- Relax popup body height (fixes 376px cap) ----------
function relaxPopupHeight() {
const sel = '.gc-popup-dynamic-message .gc-popup__dialog .gc-popup__content .gc-popup-sub-text-body.gc-popup-dynamic-message__description';
const el = document.querySelector(sel);
if (!el) return;
el.style.setProperty('height', 'auto', 'important');
el.style.setProperty('max-height', 'calc(100vh - 220px)', 'important');
el.style.setProperty('overflow', 'visible', 'important');
el.style.setProperty('overflow-x', 'visible', 'important');
el.style.setProperty('width', '100%', 'important');
el.style.setProperty('max-width', 'none', 'important');
}
// ---------- Back button label & styling helper (bold +2px, no size change) ----------
function renameBackButton(text, attempts = 10, sizeDeltaPx = 2) {
const root = document.querySelector('.gc-popup-dynamic-message');
const footer = root && root.querySelector('.gc-popup__dialog .gc-popup__footer');
if (!footer) {
if (attempts > 0) setTimeout(() => renameBackButton(text, attempts - 1, sizeDeltaPx), 60);
return;
}
let btn = Array.from(footer.querySelectorAll('button, a[role="button"], a.gc-button, .gc-button, input[type="button"], input[type="submit"]'))
.find(el => /back|close/i.test((el.value || el.textContent || '').trim()));
if (!btn) btn = footer.querySelector('button, a[role="button"], a.gc-button, .gc-button, input[type="button"], input[type="submit"]');
if (!btn) {
if (attempts > 0) setTimeout(() => renameBackButton(text, attempts - 1, sizeDeltaPx), 60);
return;
}
if (btn.tagName === 'INPUT') {
btn.value = text;
} else {
const labelSpan = btn.querySelector('span, .gc-button__text');
if (labelSpan) labelSpan.textContent = text; else btn.textContent = text;
}
btn.setAttribute('aria-label', text);
const labelEl = btn.querySelector('span, .gc-button__text') || btn;
const cs = window.getComputedStyle(labelEl);
const baseSize = parseFloat(cs.fontSize) || 16;
labelEl.style.setProperty('font-size', (baseSize + sizeDeltaPx) + 'px', 'important');
labelEl.style.setProperty('font-weight', '700', 'important');
labelEl.style.setProperty('line-height', cs.lineHeight, 'important');
}
// ---------- NLAF popup ----------
function showViaNLAF(userKey, planUuid, popup) {
// Count is per user + plan + popup id
const visitKey = PLAN_COUNT_PREFIX + userKey + '_' + planUuid + '_' + popup.id;
const count = readCount(visitKey);
if (count >= popup.maxVisits) return; // stop after 5
incrementCount(visitKey);
const sessionKey = SESSION_SHOWN_PREFIX + userKey;
sessionStorage.setItem(sessionKey, 'true');
const fullBody = renderPopupBody(popup);
setTimeout(() => {
NLAF.showDynamicContentPopup('/dashboard', popup.headline, null, fullBody);
setTimeout(() => {
const modal = document.querySelector('.gc-popup-dynamic-message__description');
modal && enforceEmbedSizing(modal);
relaxPopupHeight();
renameBackButton(popup.backText || DEFAULT_BACK_TEXT);
}, 100);
}, 2050);
}
function findMatchingPlan(subs){
for (let i=0;i fetch('/api/me', {
method:'GET',
credentials:'include',
headers:{ 'Accept':'application/json', 'Authorization':'Bearer '+token }
}))
.then(res => res.ok ? res.json() : {})
.catch(() => ({}));
}
// ---------- Boot ----------
document.addEventListener('app-ready', () => {
if (window.location.pathname !== '/dashboard') return;
fetchMe().then(me => {
const subs = me.subscriptions || [];
const planUuid = findMatchingPlan(subs);
if (!planUuid) return;
const userKey = getUserKey(me);
const sessionKey = SESSION_SHOWN_PREFIX + userKey;
// Only once per session
if (sessionStorage.getItem(sessionKey)) return;
const popupList = CONTENT_BY_PLAN[planUuid] || [];
const popup = popupList[0]; // our single shared video
if (!popup) return;
showViaNLAF(userKey, planUuid, popup);
});
});
})();