@sightspool/sdk 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -4
- package/README.md +47 -11
- package/dist/index.cjs +241 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +241 -53
- package/dist/index.js.map +1 -1
- package/dist/release.json +9 -9
- package/dist/sdk.global.js +52 -2
- package/dist/sdk.global.js.map +1 -1
- package/dist/source.json +3 -3
- package/package.json +1 -1
- package/site/index.html +15 -5
- package/site/releases/0.4.1/116419831a4c93513a867dcb4d3b808e8802ee27f5ad732460c997cefb8c804b/release.json +21 -0
- package/site/releases/0.4.1/116419831a4c93513a867dcb4d3b808e8802ee27f5ad732460c997cefb8c804b/sdk.global.js +3 -0
- package/site/releases/0.4.1/116419831a4c93513a867dcb4d3b808e8802ee27f5ad732460c997cefb8c804b/sdk.global.js.map +1 -0
- package/site/releases/0.4.1/116419831a4c93513a867dcb4d3b808e8802ee27f5ad732460c997cefb8c804b/source.json +11 -0
- package/site/trust.html +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/research.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export type SightspoolConfig = {\n /** Public workspace widget key from Go live (UUID, not an old pk_live key). */\n key: string;\n /** Match the approved research audience. No default that widens recruitment. */\n audience: \"all_visitors\" | \"signed_in\";\n /** Sightspool origin. Defaults to the hosted application. */\n endpoint?: string;\n};\nexport type ResearchStatus =\n | \"not_initialized\" | \"signed_out\" | \"paused\" | \"checking\"\n | \"unavailable\" | \"available\" | \"error\";\n\ntype Runtime = {\n key: string; endpoint: string; audience: SightspoolConfig[\"audience\"]; identified: boolean; paused: boolean;\n disposed: boolean; generation: number; device: string; offer: string | null;\n button: HTMLButtonElement | null; panel: HTMLElement | null; frame: HTMLIFrameElement | null;\n expanded: boolean; message: ((event: MessageEvent) => void) | null;\n pending: AbortController | null; timer: number; visibility: () => void;\n status: ResearchStatus;\n};\nconst slot = Symbol.for(\"sightspool.research.runtime.v1\");\ntype Host = Window & { [slot]?: Runtime };\nconst host = (): Host | null => typeof window === \"undefined\" ? null : window as Host;\nconst current = () => host()?.[slot];\nconst eligible = (r: Runtime) => r.audience === \"all_visitors\" || r.identified;\n\nfunction remove(r: Runtime) {\n // An opened interview owns its lifetime. Recruitment changes cannot end it.\n if (r.frame) return;\n r.button?.remove(); r.button = null; r.offer = null;\n}\nfunction invalidate(r: Runtime) {\n r.generation += 1; r.pending?.abort(); r.pending = null; remove(r);\n}\nfunction status(r: Runtime, value: ResearchStatus) { r.status = value; }\n\nfunction expand(r: Runtime, expanded: boolean) {\n if (!r.panel || !r.frame || !r.button) return;\n r.expanded = expanded;\n r.panel.hidden = !expanded;\n r.panel.style.display = expanded ? \"flex\" : \"none\";\n r.button.hidden = expanded;\n r.button.setAttribute(\"aria-expanded\", String(expanded));\n if (expanded) {\n r.panel.querySelector<HTMLButtonElement>(\"button\")?.focus();\n } else r.button.focus();\n}\nfunction openPanel(r: Runtime) {\n if (r.frame) { expand(r, true); return; }\n if (!r.offer || !r.button) return;\n const panel = document.createElement(\"section\");\n panel.id = \"sightspool-interview-panel\";\n panel.setAttribute(\"role\", \"dialog\");\n panel.setAttribute(\"aria-label\", \"Sightspool interview\");\n panel.style.cssText = \"position:fixed;bottom:16px;right:16px;z-index:2147483001;box-sizing:border-box;width:420px;max-width:calc(100% - 32px);height:680px;max-height:calc(100dvh - 32px);border:1px solid #e6dfe3;border-radius:20px;background:#fff;color:#262024;box-shadow:0 12px 50px #0003;overflow:hidden;font:14px system-ui;display:flex;flex-direction:column\";\n const header = document.createElement(\"div\");\n header.style.cssText = \"display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 16px;border-bottom:1px solid #eee;flex-shrink:0\";\n const title = document.createElement(\"strong\"); title.textContent = \"Sightspool\";\n const minimize = document.createElement(\"button\");\n minimize.type = \"button\"; minimize.textContent = \"Minimize\";\n minimize.style.cssText = \"font:inherit;color:inherit;background:#fff;border:1px solid #d6cbd1;border-radius:8px;padding:8px 12px;cursor:pointer\";\n const hide = () => { expand(r, false); };\n minimize.onclick = hide;\n header.appendChild(title); header.appendChild(minimize); panel.appendChild(header);\n const frame = document.createElement(\"iframe\");\n frame.title = \"Sightspool research conversation\";\n frame.allow = \"microphone; autoplay\";\n frame.setAttribute(\"sandbox\", \"allow-scripts allow-same-origin allow-forms\");\n frame.referrerPolicy = \"no-referrer\";\n frame.style.cssText = \"display:block;width:100%;flex:1;min-height:0;border:0;background:#fff\";\n const url = new URL(r.endpoint + \"/interview-widget\");\n url.searchParams.set(\"key\", r.key);\n url.hash = new URLSearchParams({ offer: r.offer, device: r.device }).toString();\n frame.src = url.href;\n panel.appendChild(frame);\n panel.onkeydown = (event) => { if (event.key === \"Escape\") { event.preventDefault(); hide(); } };\n r.panel = panel; r.frame = frame;\n r.message = (event) => {\n // Only this exact embedded document may control its presentation. No interview\n // content, capabilities or account data cross the parent messaging boundary.\n if (event.source !== frame.contentWindow || event.origin !== r.endpoint || event.data?.type !== \"sightspool:panel:minimize\") return;\n hide();\n };\n window.addEventListener(\"message\", r.message);\n r.button.textContent = \"Return to interview\";\n r.button.setAttribute(\"aria-label\", \"Sightspool: return to your interview\");\n r.button.setAttribute(\"aria-controls\", panel.id);\n r.button.onclick = () => { expand(r, true); };\n document.body.appendChild(panel);\n expand(r, true);\n}\n\nasync function check(r: Runtime) {\n if (r.frame || r.disposed || r.paused || !eligible(r) || r.pending || document.visibilityState !== \"visible\") return;\n const generation = r.generation;\n const request = new AbortController();\n r.pending = request;\n const timeout = window.setTimeout(() => request.abort(), 10_000);\n if (!r.button) status(r, \"checking\");\n try {\n const response = await fetch(r.endpoint + \"/widget-offer\", {\n method: \"POST\", credentials: \"omit\", cache: \"no-store\", referrerPolicy: \"no-referrer\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ operation: \"offer\", key: r.key, device: r.device }),\n signal: request.signal,\n });\n if (!response.ok) throw Error(\"offer unavailable\");\n const result = await response.json();\n if (r.disposed || generation !== r.generation || r.paused || !eligible(r)) return;\n if (result.available !== true || typeof result.offer !== \"string\" || !result.offer) {\n remove(r); status(r, \"unavailable\"); return;\n }\n r.offer = result.offer;\n status(r, \"available\");\n if (r.button) return;\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.textContent = \"Share your experience · 5 min\";\n button.setAttribute(\"aria-label\", \"Sightspool: join a five-minute user interview\");\n button.style.cssText = \"position:fixed;bottom:20px;right:20px;z-index:2147483000;padding:14px 18px;border:0;border-radius:999px;background:#ad1668;color:white;font:500 14px system-ui;box-shadow:0 8px 30px #0003;cursor:pointer;max-width:calc(100vw - 40px)\";\n button.onclick = () => {\n try {\n if (r.disposed || r.paused || !eligible(r) || !r.offer) return;\n openPanel(r);\n } catch { /* Host pages remain usable if embedding is blocked. */ }\n };\n r.button = button;\n document.body.appendChild(button);\n } catch {\n if (!r.disposed && generation === r.generation) { remove(r); status(r, \"error\"); }\n } finally {\n window.clearTimeout(timeout);\n if (r.pending === request) r.pending = null;\n }\n}\n\n/** Start research for the chosen audience. Signed-in-only waits for identify(). */\nexport function init(config: SightspoolConfig): void {\n try {\n const browser = host();\n if (!browser || !config || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(config.key)) return;\n if (config.audience !== \"all_visitors\" && config.audience !== \"signed_in\") return;\n const url = new URL(config.endpoint || \"https://www.sightspool.com\");\n if (url.protocol !== \"https:\" && !(url.protocol === \"http:\" && [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname))) return;\n if (url.username || url.password) return;\n const previous = current();\n if (previous && previous.key === config.key && previous.endpoint === url.origin && previous.audience === config.audience) return;\n // A second loader/workspace must not replace a participant's open interview.\n if (previous?.frame) return;\n if (previous) destroy();\n let device = \"\";\n try { device = sessionStorage.getItem(\"sightspool-widget-device:\" + config.key) || \"\"; } catch {}\n if (!/^ss_fcd_[A-Za-z0-9_-]{43}$/.test(device)) {\n const bytes = crypto.getRandomValues(new Uint8Array(32));\n device = \"ss_fcd_\" + btoa(String.fromCharCode(...bytes)).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/, \"\");\n try { sessionStorage.setItem(\"sightspool-widget-device:\" + config.key, device); } catch {}\n }\n const r: Runtime = {\n key: config.key, endpoint: url.origin, audience: config.audience, identified: false, paused: false,\n disposed: false, generation: 0, device, offer: null, button: null,\n panel: null, frame: null, expanded: false, message: null, pending: null, timer: 0, visibility: () => {}, status: \"signed_out\",\n };\n browser[slot] = r;\n r.visibility = () => {\n try {\n if (document.visibilityState === \"visible\") void check(r);\n else { invalidate(r); status(r, r.paused ? \"paused\" : eligible(r) ? \"unavailable\" : \"signed_out\"); }\n } catch {}\n };\n document.addEventListener(\"visibilitychange\", r.visibility);\n r.timer = window.setInterval(() => { void check(r); }, 15_000);\n if (eligible(r)) void check(r);\n } catch { /* Never throw into the host application. */ }\n}\n\n/** Only the presence of an ID is retained. The ID itself is never stored or sent. */\nexport function identify(userId: string | null | undefined): void {\n try {\n const r = current();\n if (!r) return;\n const identified = typeof userId === \"string\" && userId.trim().length > 0;\n if (!identified && !r.identified) { if (!r.paused && eligible(r)) void check(r); return; }\n invalidate(r);\n r.identified = identified;\n status(r, r.paused ? \"paused\" : eligible(r) ? \"unavailable\" : \"signed_out\");\n if (eligible(r) && !r.paused) void check(r);\n } catch {}\n}\nexport function pause(): void {\n try { const r = current(); if (r) { r.paused = true; invalidate(r); status(r, \"paused\"); } } catch {}\n}\nexport function resume(): void {\n try { const r = current(); if (r) { r.paused = false; if (!eligible(r)) status(r, \"signed_out\"); void check(r); } } catch {}\n}\n/** Stop recruitment and remove listeners/UI. Does not end an already opened interview. */\nexport function destroy(): void {\n try {\n const r = current();\n if (!r) return;\n r.disposed = true; invalidate(r);\n window.clearInterval(r.timer);\n document.removeEventListener(\"visibilitychange\", r.visibility);\n // Keep the session panel and its launcher reachable until the page is left.\n // Minimize is presentation only; end/withdraw remain explicit inside the frame.\n if (!r.frame) delete host()![slot];\n } catch {}\n}\nexport function getStatus(): ResearchStatus {\n try { return current()?.status ?? \"not_initialized\"; } catch { return \"error\"; }\n}\n","// Research is the public SDK. The former capture engine is parked.\nexport { init, identify, pause, resume, destroy, getStatus } from \"./research\";\nexport type { SightspoolConfig, ResearchStatus } from \"./research\";\nimport { init, identify, pause, resume, destroy, getStatus } from \"./research\";\nexport default { init, identify, pause, resume, destroy, getStatus };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/research.ts","../src/index.ts"],"names":["check"],"mappings":"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","file":"index.cjs","sourcesContent":["export type SightspoolConfig = {\n /** Public workspace widget key from Go live (UUID, not an old pk_live key). */\n key: string;\n /** Match the approved research audience. No default that widens recruitment. */\n audience: \"all_visitors\" | \"signed_in\";\n /** Sightspool origin. Defaults to the hosted application. */\n endpoint?: string;\n /** Match the client site, or follow the visitor’s system preference. */\n theme?: \"light\" | \"dark\" | \"auto\";\n};\nexport type ResearchStatus =\n | \"not_initialized\" | \"signed_out\" | \"paused\" | \"checking\"\n | \"unavailable\" | \"available\" | \"error\";\n\ntype Runtime = {\n theme: \"light\" | \"dark\" | \"auto\";\n key: string; endpoint: string; audience: SightspoolConfig[\"audience\"]; identity: string | null; paused: boolean;\n disposed: boolean; generation: number; device: string; offer: string | null;\n button: HTMLButtonElement | null; panel: HTMLElement | null; frame: HTMLIFrameElement | null;\n attention: boolean; dismissed: boolean; completed: boolean; restoring: boolean; copy: {title:string;subtitle:string}; shell: HTMLElement | null; dismiss: HTMLButtonElement | null;\n expanded: boolean; message: ((event: MessageEvent) => void) | null;\n pending: AbortController | null; timer: number; visibility: () => void;\n status: ResearchStatus;\n};\n// The server accepts a trimmed, non-empty id of at most this length\n// (apps/web/lib/cohortIdentity.ts). Trimming before the bound is applied keeps\n// both sides agreeing on exactly which ids are valid.\nconst MAX_IDENTITY_LENGTH = 200;\nconst slot = Symbol.for(\"sightspool.research.runtime.v1\");\ntype Host = Window & { [slot]?: Runtime };\nconst host = (): Host | null => typeof window === \"undefined\" ? null : window as Host;\nconst current = () => host()?.[slot];\nconst markerKey = (r: Runtime) => \"sightspool-widget-session:\" + r.key;\nfunction saveMarker(r: Runtime, value: string) { try { sessionStorage.setItem(markerKey(r), value); } catch {} }\nconst eligible = (r: Runtime) => r.audience === \"all_visitors\" || r.identity !== null;\n\nfunction remove(r: Runtime) {\n // An opened interview owns its lifetime. Recruitment changes cannot end it.\n if (r.frame || r.restoring) return;\n r.shell?.remove(); r.shell = null; r.dismiss = null; r.button = null; r.offer = null;\n}\nfunction invalidate(r: Runtime) {\n r.generation += 1; r.pending?.abort(); r.pending = null; remove(r);\n}\nfunction status(r: Runtime, value: ResearchStatus) { r.status = value; }\n\nfunction renderLauncher(r: Runtime) {\n if (!r.button) return;\n const iconOnly = r.completed || (r.dismissed && !r.expanded);\n r.button.className = \"ss-launcher\" + (iconOnly ? \" ss-iconOnly\" : !r.frame && r.attention ? \" ss-attention\" : \"\");\n const fresh = r.button.children.length === 0;\n const mark = (r.button.children[0] as HTMLElement) ?? document.createElement(\"span\"); mark.className = \"ss-launcherMark\";\n if (fresh) {const logo = document.createElement(\"img\"); logo.src = r.endpoint + \"/sightspool-monomark-dark-bg.svg\"; logo.width = 29; logo.height = 29; logo.alt = \"\"; mark.appendChild(logo);}\n const copy = (r.button.children[1] as HTMLElement) ?? document.createElement(\"span\"); copy.className = \"ss-launcherCopy\"; copy.setAttribute(\"aria-hidden\", String(iconOnly));\n const title = (copy.children[0] as HTMLElement) ?? document.createElement(\"strong\"); title.textContent = r.completed ? \"Your thank-you\" : r.expanded ? \"Minimise conversation\" : r.frame ? \"Back to your conversation\" : r.copy.title;\n const subtitle = (copy.children[1] as HTMLElement) ?? document.createElement(\"small\"); subtitle.textContent = r.completed ? \"Your accepted offer is saved here\" : r.frame ? \"Return to your interview\" : r.copy.subtitle;\n if(fresh){copy.appendChild(title); copy.appendChild(subtitle);}\n const arrow = (r.button.children[2] as HTMLElement) ?? document.createElement(\"span\"); arrow.className = \"ss-launcherAction\"; arrow.textContent = r.expanded ? \"−\" : \"→\"; arrow.setAttribute(\"aria-hidden\", \"true\");\n if(fresh){r.button.appendChild(mark); r.button.appendChild(copy); r.button.appendChild(arrow);}\n r.button.setAttribute(\"aria-label\", r.completed ? \"View your accepted thank-you\" : iconOnly ? \"Show invitation message\" : title.textContent + \". \" + subtitle.textContent);\n if (r.completed && !r.button.children[3]) { const check = document.createElement(\"span\"); check.className=\"ss-receiptCheck\"; check.textContent=\"✓\"; check.setAttribute(\"aria-hidden\",\"true\"); r.button.appendChild(check); }\n if (r.dismiss) { r.dismiss.disabled = Boolean(r.frame || r.dismissed); r.dismiss.setAttribute(\"data-visible\", String(!r.frame && !r.dismissed)); }\n}\nfunction mountLauncher(r: Runtime) {\n if (r.button) { renderLauncher(r); return; }\n const shell = document.createElement(\"aside\"); shell.className=\"ss-widgetPosition\"; shell.setAttribute(\"data-theme\",r.theme); shell.setAttribute(\"aria-label\",\"Sightspool research\");\n const style = document.createElement(\"style\"); style.textContent = `.ss-widgetPosition { position: fixed; bottom: max(22px,env(safe-area-inset-bottom)); right: max(24px,env(safe-area-inset-right)); z-index: 60; width: min(366px,calc(100vw - 32px)); pointer-events: none; }\n.ss-widgetPosition > section[data-open=\"true\"], .ss-launcher, .ss-dismissInvitation[data-visible=\"true\"] { pointer-events: auto; }\n.ss-launcherRow { display: flex; align-items: center; justify-content: flex-end; margin-top: 12px; }\n.ss-launcher { position: relative; width: max-content; max-width: 100%; interpolate-size: allow-keywords; height: 64px; min-height: 54px; display: grid; grid-template-columns: 44px minmax(0,1fr) 18px; align-items: center; gap: 12px; padding: 8px 19px 8px 9px; color: #fff; background: #18181b; border: 1px solid #ffffff20; border-radius: 999px; box-shadow: 0 8px 32px #18101d30,0 2px 6px #18101d18; text-align: left; transition: width 460ms cubic-bezier(.22,1,.36,1), height 360ms cubic-bezier(.22,1,.36,1), padding 460ms cubic-bezier(.22,1,.36,1), gap 460ms cubic-bezier(.22,1,.36,1), grid-template-columns 460ms cubic-bezier(.22,1,.36,1), transform 180ms, box-shadow 240ms; }\n.ss-launcherGroup { position: relative; max-width: 100%; }\n.ss-dismissInvitation { position: absolute; top: -12px; right: 0; width: 28px; height: 28px; display: grid; place-items: center; border: 1px solid #dfdbe0; border-radius: 50%; background: #fcfaf9; color: #6e6470; box-shadow: 0 2px 8px #18101d15; opacity: 0; transform: scale(.7); visibility: hidden; transition: opacity 140ms, transform 240ms, visibility 0s 240ms; }\n.ss-dismissInvitation[data-visible=\"true\"] { opacity: 1; transform: scale(1); visibility: visible; transition-delay: 220ms,220ms,0s; }\n.ss-dismissInvitation:hover { color: #241e25; background: #eee8ed; }\n.ss-launcher.ss-attention { animation: invitation-enter 450ms cubic-bezier(.2,.8,.2,1) both, invitation-glow 2400ms 450ms ease-in-out; }\n@keyframes invitation-enter { from { opacity: 0; transform: translateY(12px) scale(.96); } to { opacity: 1; transform: translateY(0) scale(1); } }\n@keyframes invitation-glow { 0%,100% { box-shadow: 0 8px 32px #18101d30,0 0 0 0 #c6fa6400; } 25%,70% { box-shadow: 0 8px 32px #18101d30,0 0 0 5px #c6fa6440,0 0 28px #a8176830; } 48% { box-shadow: 0 8px 32px #18101d30,0 0 0 1px #c6fa6410; } }\n.ss-launcher.ss-iconOnly { position: relative; min-height: 54px; width: 54px; height: 54px; padding: 4px; gap: 0; grid-template-columns: 44px minmax(0,0fr) 0px; box-shadow: 0 3px 14px #18101d20; }\n.ss-compactActiveBadge { position: absolute; right: 1px; top: 1px; width: 10px; height: 10px; border: 2px solid #18181b; border-radius: 50%; background: #c6fa64; }\n.ss-launcher::after { content: \"\"; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0; box-shadow: -5px 0 20px #a8176830,5px 0 18px #c6fa641c,inset 0 0 0 1px #ffffff12; transition: opacity 280ms ease; }\n@media (hover: hover) {\n .ss-launcher:not(.ss-iconOnly):hover::after { opacity: 1; animation: hover-halo 2200ms ease-in-out infinite; }\n .ss-launcher:not(.ss-iconOnly):hover .ss-launcherMark::before { animation: hover-logo-glow 2200ms ease-in-out infinite; }\n}\n.ss-launcher:focus-visible::after { opacity: 1; }\n@keyframes hover-halo { 0%,100% { opacity: .4; } 50% { opacity: 1; } }\n@keyframes hover-logo-glow { 0%,100% { opacity: .925; transform: scale(1); } 50% { opacity: 1; transform: scale(1.08); filter: brightness(1.18); } }\n.ss-launcherMark { position: relative; isolation: isolate; display: grid; place-items: center; width: 44px; height: 44px; flex-shrink: 0; border-radius: 50%; }\n.ss-launcherMark::before { content: \"\"; position: absolute; inset: -8px; border-radius: 50%; pointer-events: none; background: radial-gradient(ellipse at 30% 30%,rgb(168 23 104 / 87%),transparent 72%),radial-gradient(ellipse at 74% 68%,rgb(198 250 100 / 50%),transparent 70%); mask-image: radial-gradient(closest-side,#000 59%,transparent 100%); opacity: .925; }\n.ss-launcherMark img { position: relative; }\n.ss-launcherCopy { min-width: 0; overflow: hidden; white-space: nowrap; opacity: 1; transform: translateX(0); transition: opacity 200ms 100ms, transform 360ms cubic-bezier(.22,1,.36,1); }\n.ss-iconOnly .ss-launcherCopy { opacity: 0; transform: translateX(12px); transition-delay: 0s; }\n.ss-launcherAction { display: grid; place-items: center; overflow: hidden; color: #c6fa64; opacity: 1; transition: opacity 180ms 140ms, transform 360ms; }\n.ss-iconOnly .ss-launcherAction { opacity: 0; transform: translateX(8px); transition-delay: 0s; }\n.ss-launcherCopy strong { display: block; font-size: 13px; font-weight: 600; line-height: 1.4; }\n.ss-launcherCopy small { display: block; margin-top: 4px; font-size: 12px; color: #d5d0d8; line-height: 1.4; }\n.ss-launcher > svg { flex-shrink: 0; color: #c6fa64; }\n.ss-activeBadge { flex-shrink: 0; width: 8px; height: 8px; background: #c6fa64; border-radius: 50%; box-shadow: 0 0 0 4px #c6fa6418; }\n\n.ss-widgetPosition{z-index:2147483000;font:14px Arial,Helvetica,sans-serif;line-height:1.5}\n.ss-widgetPosition *{box-sizing:border-box}\n.ss-widgetPosition button{font:inherit;cursor:pointer;outline-offset:4px}\n.ss-panel{position:absolute;bottom:calc(100% + 12px);right:0;width:100%;height:610px;max-height:calc(100dvh - max(22px,env(safe-area-inset-bottom)) - 104px);border:1px solid #e7e0e6;border-radius:20px;background:#fcfaf9;color:#241e25;box-shadow:0 16px 64px #18101d26;overflow:hidden;display:flex;flex-direction:column;transform-origin:bottom right;opacity:0;visibility:hidden;transform:translateY(18px) scale(.82,.2);transition:transform 340ms cubic-bezier(.4,0,.6,1),opacity 180ms,visibility 0s 340ms;pointer-events:none}\n.ss-panel[data-open=\"true\"]{opacity:1;visibility:visible;transform:translateY(0) scale(1);transition:transform 480ms cubic-bezier(.16,1,.3,1),opacity 200ms,visibility 0s;pointer-events:auto}\n.ss-panel>div,.ss-panel>iframe{opacity:0;transition:opacity 120ms}\n.ss-panel[data-open=\"true\"]>div,.ss-panel[data-open=\"true\"]>iframe{opacity:1;transition:opacity 240ms 170ms}\n.ss-panel>div{display:flex;align-items:center;justify-content:space-between;padding:12px 18px;border-bottom:1px solid #e7e0e6}\n.ss-panel>div>button{border:0;background:transparent;color:#554b58;padding:8px;border-radius:8px}\n.ss-panel iframe{display:block;width:100%;flex:1;min-height:0;border:0;background:#fcfaf9}\n[data-theme=\"dark\"] .ss-panel{background:#18181b;color:#fff;border-color:#ffffff1c}\n[data-theme=\"dark\"] .ss-panel>div{border-color:#ffffff1c}\n[data-theme=\"dark\"] .ss-panel>div>button{color:#cbc5cd}\n@media(prefers-color-scheme:dark){[data-theme=\"auto\"] .ss-panel{background:#18181b;color:#fff;border-color:#ffffff1c}[data-theme=\"auto\"] .ss-panel>div{border-color:#ffffff1c}[data-theme=\"auto\"] .ss-panel>div>button{color:#cbc5cd}}\n.ss-receiptCheck{position:absolute;right:0;top:0;display:grid;place-items:center;width:16px;height:16px;border:2px solid #18181b;border-radius:50%;background:#c6fa64;color:#18181b;font-size:10px}\n@media(max-width:560px){.ss-widgetPosition{bottom:max(12px,env(safe-area-inset-bottom));right:auto;left:50%;transform:translateX(-50%);width:min(366px,calc(100vw - 24px))}.ss-panel{max-height:calc(100dvh - max(12px,env(safe-area-inset-bottom)) - 100px);transform-origin:bottom center}.ss-launcher{gap:10px;padding-right:15px;height:80px}.ss-launcherCopy{white-space:normal}.ss-launcherRow{justify-content:center}}\n@media(prefers-reduced-motion:reduce){.ss-widgetPosition *,.ss-widgetPosition *::before,.ss-widgetPosition *::after{animation:none!important;transition:none!important}}\n`;\n shell.appendChild(style);\n const row = document.createElement(\"div\"); row.className=\"ss-launcherRow\";\n const group = document.createElement(\"div\"); group.className=\"ss-launcherGroup\";\n const button = document.createElement(\"button\"); button.type=\"button\";\n const dismiss = document.createElement(\"button\"); dismiss.type=\"button\"; dismiss.className=\"ss-dismissInvitation\"; dismiss.textContent=\"×\";\n dismiss.setAttribute(\"aria-label\",\"Dismiss invitation and keep a small button\");\n dismiss.onclick=()=>{r.attention=false;r.dismissed=true;try{sessionStorage.setItem(\"sightspool-widget-dismissed:\"+r.key,\"1\");}catch{}renderLauncher(r);button.focus();};\n button.onanimationend=(event)=>{if(event.animationName.includes(\"invitation-glow\")){r.attention=false;renderLauncher(r);}};\n button.onclick=()=>{\n if(r.completed || r.frame || r.restoring){if(r.frame)expand(r,!r.expanded);else openPanel(r);return;}\n if(r.dismissed){r.attention=false;r.dismissed=false;try{sessionStorage.setItem(\"sightspool-widget-dismissed:\"+r.key,\"0\");}catch{}renderLauncher(r);return;}\n if(!r.disposed&&!r.paused&&eligible(r))openPanel(r);\n };\n group.appendChild(button);group.appendChild(dismiss);row.appendChild(group);shell.appendChild(row);\n r.shell=shell;r.button=button;r.dismiss=dismiss;document.body.appendChild(shell);renderLauncher(r);\n}\nfunction expand(r: Runtime, expanded: boolean) {\n if (!r.panel || !r.frame || !r.button) return;\n if (r.expanded === expanded) return;\n const ownedFocus = r.panel.contains(document.activeElement);\n r.expanded = expanded;\n r.panel.setAttribute(\"data-open\", String(expanded));\n r.panel.setAttribute(\"aria-hidden\", String(!expanded));\n r.panel.inert = !expanded;\n r.button.setAttribute(\"aria-expanded\", String(expanded));\n renderLauncher(r);\n if (expanded) r.panel.querySelector<HTMLButtonElement>(\"button\")?.focus();\n else if (ownedFocus) r.button.focus();\n}\nfunction openPanel(r: Runtime) {\n if (r.frame) { expand(r, true); return; }\n if ((!r.offer && !r.restoring) || !r.button || !r.shell) return;\n const panel = document.createElement(\"section\"); panel.className=\"ss-panel\";\n panel.id=\"sightspool-interview-panel\";panel.setAttribute(\"role\",\"dialog\");panel.setAttribute(\"aria-label\",\"Sightspool interview\");\n const header=document.createElement(\"div\");const title=document.createElement(\"strong\");title.textContent=\"Sightspool\";\n const minimize=document.createElement(\"button\");minimize.type=\"button\";minimize.textContent=\"Minimise\";\n const hide=()=>expand(r,false);minimize.onclick=hide;header.appendChild(title);header.appendChild(minimize);panel.appendChild(header);\n const frame=document.createElement(\"iframe\");frame.title=\"Sightspool research conversation\";frame.allow=\"microphone; autoplay; clipboard-write\";\n frame.setAttribute(\"sandbox\",\"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox\");frame.referrerPolicy=\"no-referrer\";\n const url=new URL(r.endpoint+\"/interview-widget\");url.searchParams.set(\"key\",r.key);url.searchParams.set(\"theme\",r.theme);\n url.hash=new URLSearchParams(r.restoring ? {device:r.device,restore:\"1\"} : {offer:r.offer!,device:r.device}).toString();frame.src=url.href;\n panel.appendChild(frame);panel.onkeydown=(event)=>{if(event.key===\"Escape\"){event.preventDefault();hide();}};\n r.panel=panel;r.frame=frame;\n r.message=(event)=>{\n if(event.source!==frame.contentWindow||event.origin!==r.endpoint)return;\n if(event.data?.type===\"sightspool:panel:minimize\")hide();\n if(event.data?.type===\"sightspool:interview:accepted\"){saveMarker(r,\"active\");}\n if(event.data?.type===\"sightspool:interview:ended\"){r.completed=true;saveMarker(r,\"ended\");renderLauncher(r);}\n };\n window.addEventListener(\"message\",r.message);r.button.setAttribute(\"aria-controls\",panel.id);r.shell.appendChild(panel);expand(r,true);\n}\n\nasync function check(r: Runtime) {\n if (r.frame || r.restoring || r.disposed || r.paused || !eligible(r) || r.pending || document.visibilityState !== \"visible\") return;\n const generation = r.generation;\n const request = new AbortController();\n r.pending = request;\n const timeout = window.setTimeout(() => request.abort(), 10_000);\n if (!r.button) status(r, \"checking\");\n // Only the offer call carries the identity. The interview page is served by\n // Sightspool itself and is handed nothing but the offer and device, so the\n // cohort decision is frozen into the signed offer instead (SIG-122 §10).\n const payload: { operation: string; key: string; device: string; identity?: string } =\n { operation: \"offer\", key: r.key, device: r.device };\n if (r.identity) payload.identity = r.identity;\n try {\n const response = await fetch(r.endpoint + \"/widget-offer\", {\n method: \"POST\", credentials: \"omit\", cache: \"no-store\", referrerPolicy: \"no-referrer\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n signal: request.signal,\n });\n if (!response.ok) throw Error(\"offer unavailable\");\n const result = await response.json();\n if (r.disposed || generation !== r.generation || r.paused || !eligible(r)) return;\n if (result.available !== true || typeof result.offer !== \"string\" || !result.offer) {\n remove(r); status(r, \"unavailable\"); return;\n }\n r.offer = result.offer;\n status(r, \"available\");\n if (result.invitation && typeof result.invitation.title === \"string\" && typeof result.invitation.subtitle === \"string\") {\n r.copy={title:result.invitation.title.slice(0,200),subtitle:result.invitation.subtitle.slice(0,240)};\n }\n mountLauncher(r);\n } catch {\n if (!r.disposed && generation === r.generation) { remove(r); status(r, \"error\"); }\n } finally {\n window.clearTimeout(timeout);\n if (r.pending === request) r.pending = null;\n }\n}\n\n/** Start research for the chosen audience. Signed-in-only waits for identify(). */\nexport function init(config: SightspoolConfig): void {\n try {\n const browser = host();\n if (!browser || !config || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(config.key)) return;\n if (config.audience !== \"all_visitors\" && config.audience !== \"signed_in\") return;\n const url = new URL(config.endpoint || \"https://www.sightspool.com\");\n if (url.protocol !== \"https:\" && !(url.protocol === \"http:\" && [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname))) return;\n if (url.username || url.password) return;\n const previous = current();\n if (previous && previous.key === config.key && previous.endpoint === url.origin && previous.audience === config.audience) return;\n // A second loader/workspace must not replace a participant's open interview.\n if (previous?.frame || previous?.restoring) return;\n if (previous) destroy();\n let device = \"\";\n try { device = sessionStorage.getItem(\"sightspool-widget-device:\" + config.key) || \"\"; } catch {}\n if (!/^ss_fcd_[A-Za-z0-9_-]{43}$/.test(device)) {\n const bytes = crypto.getRandomValues(new Uint8Array(32));\n device = \"ss_fcd_\" + btoa(String.fromCharCode(...bytes)).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/, \"\");\n try { sessionStorage.setItem(\"sightspool-widget-device:\" + config.key, device); } catch {}\n }\n const r: Runtime = {\n theme: config.theme === \"light\" || config.theme === \"auto\" ? config.theme : \"dark\",\n key: config.key, endpoint: url.origin, audience: config.audience, identity: null, paused: false,\n attention: true, dismissed: false, completed: false, restoring: false, copy:{title:\"Share your experience\",subtitle:\"A research conversation\"}, shell:null,dismiss:null,\n disposed: false, generation: 0, device, offer: null, button: null,\n panel: null, frame: null, expanded: false, message: null, pending: null, timer: 0, visibility: () => {}, status: \"signed_out\",\n };\n try {\n r.dismissed=sessionStorage.getItem(\"sightspool-widget-dismissed:\"+r.key)===\"1\";\n const marker=sessionStorage.getItem(markerKey(r));\n r.restoring=marker===\"active\"||marker===\"ended\";r.completed=marker===\"ended\";\n } catch {}\n browser[slot] = r;\n if(r.restoring){mountLauncher(r);return;}\n\n r.visibility = () => {\n try {\n if (document.visibilityState === \"visible\") void check(r);\n else { invalidate(r); status(r, r.paused ? \"paused\" : eligible(r) ? \"unavailable\" : \"signed_out\"); }\n } catch {}\n };\n document.addEventListener(\"visibilitychange\", r.visibility);\n r.timer = window.setInterval(() => { void check(r); }, 15_000);\n if (eligible(r)) void check(r);\n } catch { /* Never throw into the host application. */ }\n}\n\n/**\n * Identify the signed-in user, and carry that id to the offer request so a\n * cohort-gated research card can tell whether this person is in its cohort.\n *\n * The id is held in memory for the page's lifetime and sent, over TLS, only to\n * this workspace's own Sightspool endpoint, only on `operation: \"offer\"`. It is\n * hashed workspace-scoped on arrival and never stored raw in any table, log or\n * payload. The SDK never writes it to sessionStorage, localStorage, a cookie, a\n * URL, a fragment or a log.\n *\n * `null` clears it, as does any value that is not a non-empty string of at most\n * 200 characters after trimming. An over-length id is never truncated: a\n * truncated id is a different person, and on a gated card that invites the\n * wrong one. Failing as unidentified is the safe direction.\n */\nexport function identify(userId: string | null | undefined): void {\n try {\n const r = current();\n if (!r) return;\n const trimmed = typeof userId === \"string\" ? userId.trim() : \"\";\n const identity = trimmed.length > 0 && trimmed.length <= MAX_IDENTITY_LENGTH ? trimmed : null;\n // Re-stating the same person leaves their live invitation alone. Any change,\n // including to unidentified, takes the previous person's pending check and\n // minted offer with it, so an account switch never inherits an invitation.\n if (identity === r.identity) { if (!r.paused && eligible(r)) void check(r); return; }\n invalidate(r);\n r.identity = identity;\n status(r, r.paused ? \"paused\" : eligible(r) ? \"unavailable\" : \"signed_out\");\n if (eligible(r) && !r.paused) void check(r);\n } catch {}\n}\nexport function pause(): void {\n try { const r = current(); if (r) { r.paused = true; invalidate(r); status(r, \"paused\"); } } catch {}\n}\nexport function resume(): void {\n try { const r = current(); if (r) { r.paused = false; if (!eligible(r)) status(r, \"signed_out\"); void check(r); } } catch {}\n}\n/** Stop recruitment and remove listeners/UI. Does not end an already opened interview. */\nexport function destroy(): void {\n try {\n const r = current();\n if (!r) return;\n r.disposed = true; invalidate(r);\n window.clearInterval(r.timer);\n document.removeEventListener(\"visibilitychange\", r.visibility);\n // Keep the session panel and its launcher reachable until the page is left.\n // Minimize is presentation only; end/withdraw remain explicit inside the frame.\n if (!r.frame && !r.restoring) delete host()![slot];\n } catch {}\n}\nexport function getStatus(): ResearchStatus {\n try { return current()?.status ?? \"not_initialized\"; } catch { return \"error\"; }\n}\n","// Research is the public SDK. The former capture engine is parked.\nexport { init, identify, pause, resume, destroy, getStatus } from \"./research\";\nexport type { SightspoolConfig, ResearchStatus } from \"./research\";\nimport { init, identify, pause, resume, destroy, getStatus } from \"./research\";\nexport default { init, identify, pause, resume, destroy, getStatus };\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -5,11 +5,27 @@ type SightspoolConfig = {
|
|
|
5
5
|
audience: "all_visitors" | "signed_in";
|
|
6
6
|
/** Sightspool origin. Defaults to the hosted application. */
|
|
7
7
|
endpoint?: string;
|
|
8
|
+
/** Match the client site, or follow the visitor’s system preference. */
|
|
9
|
+
theme?: "light" | "dark" | "auto";
|
|
8
10
|
};
|
|
9
11
|
type ResearchStatus = "not_initialized" | "signed_out" | "paused" | "checking" | "unavailable" | "available" | "error";
|
|
10
12
|
/** Start research for the chosen audience. Signed-in-only waits for identify(). */
|
|
11
13
|
declare function init(config: SightspoolConfig): void;
|
|
12
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Identify the signed-in user, and carry that id to the offer request so a
|
|
16
|
+
* cohort-gated research card can tell whether this person is in its cohort.
|
|
17
|
+
*
|
|
18
|
+
* The id is held in memory for the page's lifetime and sent, over TLS, only to
|
|
19
|
+
* this workspace's own Sightspool endpoint, only on `operation: "offer"`. It is
|
|
20
|
+
* hashed workspace-scoped on arrival and never stored raw in any table, log or
|
|
21
|
+
* payload. The SDK never writes it to sessionStorage, localStorage, a cookie, a
|
|
22
|
+
* URL, a fragment or a log.
|
|
23
|
+
*
|
|
24
|
+
* `null` clears it, as does any value that is not a non-empty string of at most
|
|
25
|
+
* 200 characters after trimming. An over-length id is never truncated: a
|
|
26
|
+
* truncated id is a different person, and on a gated card that invites the
|
|
27
|
+
* wrong one. Failing as unidentified is the safe direction.
|
|
28
|
+
*/
|
|
13
29
|
declare function identify(userId: string | null | undefined): void;
|
|
14
30
|
declare function pause(): void;
|
|
15
31
|
declare function resume(): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,11 +5,27 @@ type SightspoolConfig = {
|
|
|
5
5
|
audience: "all_visitors" | "signed_in";
|
|
6
6
|
/** Sightspool origin. Defaults to the hosted application. */
|
|
7
7
|
endpoint?: string;
|
|
8
|
+
/** Match the client site, or follow the visitor’s system preference. */
|
|
9
|
+
theme?: "light" | "dark" | "auto";
|
|
8
10
|
};
|
|
9
11
|
type ResearchStatus = "not_initialized" | "signed_out" | "paused" | "checking" | "unavailable" | "available" | "error";
|
|
10
12
|
/** Start research for the chosen audience. Signed-in-only waits for identify(). */
|
|
11
13
|
declare function init(config: SightspoolConfig): void;
|
|
12
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Identify the signed-in user, and carry that id to the offer request so a
|
|
16
|
+
* cohort-gated research card can tell whether this person is in its cohort.
|
|
17
|
+
*
|
|
18
|
+
* The id is held in memory for the page's lifetime and sent, over TLS, only to
|
|
19
|
+
* this workspace's own Sightspool endpoint, only on `operation: "offer"`. It is
|
|
20
|
+
* hashed workspace-scoped on arrival and never stored raw in any table, log or
|
|
21
|
+
* payload. The SDK never writes it to sessionStorage, localStorage, a cookie, a
|
|
22
|
+
* URL, a fragment or a log.
|
|
23
|
+
*
|
|
24
|
+
* `null` clears it, as does any value that is not a non-empty string of at most
|
|
25
|
+
* 200 characters after trimming. An over-length id is never truncated: a
|
|
26
|
+
* truncated id is a different person, and on a gated card that invites the
|
|
27
|
+
* wrong one. Failing as unidentified is the safe direction.
|
|
28
|
+
*/
|
|
13
29
|
declare function identify(userId: string | null | undefined): void;
|
|
14
30
|
declare function pause(): void;
|
|
15
31
|
declare function resume(): void;
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
// src/research.ts
|
|
2
|
+
var MAX_IDENTITY_LENGTH = 200;
|
|
2
3
|
var slot = /* @__PURE__ */ Symbol.for("sightspool.research.runtime.v1");
|
|
3
4
|
var host = () => typeof window === "undefined" ? null : window;
|
|
4
5
|
var current = () => {
|
|
5
6
|
var _a;
|
|
6
7
|
return (_a = host()) == null ? void 0 : _a[slot];
|
|
7
8
|
};
|
|
8
|
-
var
|
|
9
|
+
var markerKey = (r) => "sightspool-widget-session:" + r.key;
|
|
10
|
+
function saveMarker(r, value) {
|
|
11
|
+
try {
|
|
12
|
+
sessionStorage.setItem(markerKey(r), value);
|
|
13
|
+
} catch (e) {
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
var eligible = (r) => r.audience === "all_visitors" || r.identity !== null;
|
|
9
17
|
function remove(r) {
|
|
10
18
|
var _a;
|
|
11
|
-
if (r.frame) return;
|
|
12
|
-
(_a = r.
|
|
19
|
+
if (r.frame || r.restoring) return;
|
|
20
|
+
(_a = r.shell) == null ? void 0 : _a.remove();
|
|
21
|
+
r.shell = null;
|
|
22
|
+
r.dismiss = null;
|
|
13
23
|
r.button = null;
|
|
14
24
|
r.offer = null;
|
|
15
25
|
}
|
|
@@ -23,53 +33,217 @@ function invalidate(r) {
|
|
|
23
33
|
function status(r, value) {
|
|
24
34
|
r.status = value;
|
|
25
35
|
}
|
|
36
|
+
function renderLauncher(r) {
|
|
37
|
+
var _a, _b, _c, _d, _e;
|
|
38
|
+
if (!r.button) return;
|
|
39
|
+
const iconOnly = r.completed || r.dismissed && !r.expanded;
|
|
40
|
+
r.button.className = "ss-launcher" + (iconOnly ? " ss-iconOnly" : !r.frame && r.attention ? " ss-attention" : "");
|
|
41
|
+
const fresh = r.button.children.length === 0;
|
|
42
|
+
const mark = (_a = r.button.children[0]) != null ? _a : document.createElement("span");
|
|
43
|
+
mark.className = "ss-launcherMark";
|
|
44
|
+
if (fresh) {
|
|
45
|
+
const logo = document.createElement("img");
|
|
46
|
+
logo.src = r.endpoint + "/sightspool-monomark-dark-bg.svg";
|
|
47
|
+
logo.width = 29;
|
|
48
|
+
logo.height = 29;
|
|
49
|
+
logo.alt = "";
|
|
50
|
+
mark.appendChild(logo);
|
|
51
|
+
}
|
|
52
|
+
const copy = (_b = r.button.children[1]) != null ? _b : document.createElement("span");
|
|
53
|
+
copy.className = "ss-launcherCopy";
|
|
54
|
+
copy.setAttribute("aria-hidden", String(iconOnly));
|
|
55
|
+
const title = (_c = copy.children[0]) != null ? _c : document.createElement("strong");
|
|
56
|
+
title.textContent = r.completed ? "Your thank-you" : r.expanded ? "Minimise conversation" : r.frame ? "Back to your conversation" : r.copy.title;
|
|
57
|
+
const subtitle = (_d = copy.children[1]) != null ? _d : document.createElement("small");
|
|
58
|
+
subtitle.textContent = r.completed ? "Your accepted offer is saved here" : r.frame ? "Return to your interview" : r.copy.subtitle;
|
|
59
|
+
if (fresh) {
|
|
60
|
+
copy.appendChild(title);
|
|
61
|
+
copy.appendChild(subtitle);
|
|
62
|
+
}
|
|
63
|
+
const arrow = (_e = r.button.children[2]) != null ? _e : document.createElement("span");
|
|
64
|
+
arrow.className = "ss-launcherAction";
|
|
65
|
+
arrow.textContent = r.expanded ? "\u2212" : "\u2192";
|
|
66
|
+
arrow.setAttribute("aria-hidden", "true");
|
|
67
|
+
if (fresh) {
|
|
68
|
+
r.button.appendChild(mark);
|
|
69
|
+
r.button.appendChild(copy);
|
|
70
|
+
r.button.appendChild(arrow);
|
|
71
|
+
}
|
|
72
|
+
r.button.setAttribute("aria-label", r.completed ? "View your accepted thank-you" : iconOnly ? "Show invitation message" : title.textContent + ". " + subtitle.textContent);
|
|
73
|
+
if (r.completed && !r.button.children[3]) {
|
|
74
|
+
const check2 = document.createElement("span");
|
|
75
|
+
check2.className = "ss-receiptCheck";
|
|
76
|
+
check2.textContent = "\u2713";
|
|
77
|
+
check2.setAttribute("aria-hidden", "true");
|
|
78
|
+
r.button.appendChild(check2);
|
|
79
|
+
}
|
|
80
|
+
if (r.dismiss) {
|
|
81
|
+
r.dismiss.disabled = Boolean(r.frame || r.dismissed);
|
|
82
|
+
r.dismiss.setAttribute("data-visible", String(!r.frame && !r.dismissed));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function mountLauncher(r) {
|
|
86
|
+
if (r.button) {
|
|
87
|
+
renderLauncher(r);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const shell = document.createElement("aside");
|
|
91
|
+
shell.className = "ss-widgetPosition";
|
|
92
|
+
shell.setAttribute("data-theme", r.theme);
|
|
93
|
+
shell.setAttribute("aria-label", "Sightspool research");
|
|
94
|
+
const style = document.createElement("style");
|
|
95
|
+
style.textContent = `.ss-widgetPosition { position: fixed; bottom: max(22px,env(safe-area-inset-bottom)); right: max(24px,env(safe-area-inset-right)); z-index: 60; width: min(366px,calc(100vw - 32px)); pointer-events: none; }
|
|
96
|
+
.ss-widgetPosition > section[data-open="true"], .ss-launcher, .ss-dismissInvitation[data-visible="true"] { pointer-events: auto; }
|
|
97
|
+
.ss-launcherRow { display: flex; align-items: center; justify-content: flex-end; margin-top: 12px; }
|
|
98
|
+
.ss-launcher { position: relative; width: max-content; max-width: 100%; interpolate-size: allow-keywords; height: 64px; min-height: 54px; display: grid; grid-template-columns: 44px minmax(0,1fr) 18px; align-items: center; gap: 12px; padding: 8px 19px 8px 9px; color: #fff; background: #18181b; border: 1px solid #ffffff20; border-radius: 999px; box-shadow: 0 8px 32px #18101d30,0 2px 6px #18101d18; text-align: left; transition: width 460ms cubic-bezier(.22,1,.36,1), height 360ms cubic-bezier(.22,1,.36,1), padding 460ms cubic-bezier(.22,1,.36,1), gap 460ms cubic-bezier(.22,1,.36,1), grid-template-columns 460ms cubic-bezier(.22,1,.36,1), transform 180ms, box-shadow 240ms; }
|
|
99
|
+
.ss-launcherGroup { position: relative; max-width: 100%; }
|
|
100
|
+
.ss-dismissInvitation { position: absolute; top: -12px; right: 0; width: 28px; height: 28px; display: grid; place-items: center; border: 1px solid #dfdbe0; border-radius: 50%; background: #fcfaf9; color: #6e6470; box-shadow: 0 2px 8px #18101d15; opacity: 0; transform: scale(.7); visibility: hidden; transition: opacity 140ms, transform 240ms, visibility 0s 240ms; }
|
|
101
|
+
.ss-dismissInvitation[data-visible="true"] { opacity: 1; transform: scale(1); visibility: visible; transition-delay: 220ms,220ms,0s; }
|
|
102
|
+
.ss-dismissInvitation:hover { color: #241e25; background: #eee8ed; }
|
|
103
|
+
.ss-launcher.ss-attention { animation: invitation-enter 450ms cubic-bezier(.2,.8,.2,1) both, invitation-glow 2400ms 450ms ease-in-out; }
|
|
104
|
+
@keyframes invitation-enter { from { opacity: 0; transform: translateY(12px) scale(.96); } to { opacity: 1; transform: translateY(0) scale(1); } }
|
|
105
|
+
@keyframes invitation-glow { 0%,100% { box-shadow: 0 8px 32px #18101d30,0 0 0 0 #c6fa6400; } 25%,70% { box-shadow: 0 8px 32px #18101d30,0 0 0 5px #c6fa6440,0 0 28px #a8176830; } 48% { box-shadow: 0 8px 32px #18101d30,0 0 0 1px #c6fa6410; } }
|
|
106
|
+
.ss-launcher.ss-iconOnly { position: relative; min-height: 54px; width: 54px; height: 54px; padding: 4px; gap: 0; grid-template-columns: 44px minmax(0,0fr) 0px; box-shadow: 0 3px 14px #18101d20; }
|
|
107
|
+
.ss-compactActiveBadge { position: absolute; right: 1px; top: 1px; width: 10px; height: 10px; border: 2px solid #18181b; border-radius: 50%; background: #c6fa64; }
|
|
108
|
+
.ss-launcher::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0; box-shadow: -5px 0 20px #a8176830,5px 0 18px #c6fa641c,inset 0 0 0 1px #ffffff12; transition: opacity 280ms ease; }
|
|
109
|
+
@media (hover: hover) {
|
|
110
|
+
.ss-launcher:not(.ss-iconOnly):hover::after { opacity: 1; animation: hover-halo 2200ms ease-in-out infinite; }
|
|
111
|
+
.ss-launcher:not(.ss-iconOnly):hover .ss-launcherMark::before { animation: hover-logo-glow 2200ms ease-in-out infinite; }
|
|
112
|
+
}
|
|
113
|
+
.ss-launcher:focus-visible::after { opacity: 1; }
|
|
114
|
+
@keyframes hover-halo { 0%,100% { opacity: .4; } 50% { opacity: 1; } }
|
|
115
|
+
@keyframes hover-logo-glow { 0%,100% { opacity: .925; transform: scale(1); } 50% { opacity: 1; transform: scale(1.08); filter: brightness(1.18); } }
|
|
116
|
+
.ss-launcherMark { position: relative; isolation: isolate; display: grid; place-items: center; width: 44px; height: 44px; flex-shrink: 0; border-radius: 50%; }
|
|
117
|
+
.ss-launcherMark::before { content: ""; position: absolute; inset: -8px; border-radius: 50%; pointer-events: none; background: radial-gradient(ellipse at 30% 30%,rgb(168 23 104 / 87%),transparent 72%),radial-gradient(ellipse at 74% 68%,rgb(198 250 100 / 50%),transparent 70%); mask-image: radial-gradient(closest-side,#000 59%,transparent 100%); opacity: .925; }
|
|
118
|
+
.ss-launcherMark img { position: relative; }
|
|
119
|
+
.ss-launcherCopy { min-width: 0; overflow: hidden; white-space: nowrap; opacity: 1; transform: translateX(0); transition: opacity 200ms 100ms, transform 360ms cubic-bezier(.22,1,.36,1); }
|
|
120
|
+
.ss-iconOnly .ss-launcherCopy { opacity: 0; transform: translateX(12px); transition-delay: 0s; }
|
|
121
|
+
.ss-launcherAction { display: grid; place-items: center; overflow: hidden; color: #c6fa64; opacity: 1; transition: opacity 180ms 140ms, transform 360ms; }
|
|
122
|
+
.ss-iconOnly .ss-launcherAction { opacity: 0; transform: translateX(8px); transition-delay: 0s; }
|
|
123
|
+
.ss-launcherCopy strong { display: block; font-size: 13px; font-weight: 600; line-height: 1.4; }
|
|
124
|
+
.ss-launcherCopy small { display: block; margin-top: 4px; font-size: 12px; color: #d5d0d8; line-height: 1.4; }
|
|
125
|
+
.ss-launcher > svg { flex-shrink: 0; color: #c6fa64; }
|
|
126
|
+
.ss-activeBadge { flex-shrink: 0; width: 8px; height: 8px; background: #c6fa64; border-radius: 50%; box-shadow: 0 0 0 4px #c6fa6418; }
|
|
127
|
+
|
|
128
|
+
.ss-widgetPosition{z-index:2147483000;font:14px Arial,Helvetica,sans-serif;line-height:1.5}
|
|
129
|
+
.ss-widgetPosition *{box-sizing:border-box}
|
|
130
|
+
.ss-widgetPosition button{font:inherit;cursor:pointer;outline-offset:4px}
|
|
131
|
+
.ss-panel{position:absolute;bottom:calc(100% + 12px);right:0;width:100%;height:610px;max-height:calc(100dvh - max(22px,env(safe-area-inset-bottom)) - 104px);border:1px solid #e7e0e6;border-radius:20px;background:#fcfaf9;color:#241e25;box-shadow:0 16px 64px #18101d26;overflow:hidden;display:flex;flex-direction:column;transform-origin:bottom right;opacity:0;visibility:hidden;transform:translateY(18px) scale(.82,.2);transition:transform 340ms cubic-bezier(.4,0,.6,1),opacity 180ms,visibility 0s 340ms;pointer-events:none}
|
|
132
|
+
.ss-panel[data-open="true"]{opacity:1;visibility:visible;transform:translateY(0) scale(1);transition:transform 480ms cubic-bezier(.16,1,.3,1),opacity 200ms,visibility 0s;pointer-events:auto}
|
|
133
|
+
.ss-panel>div,.ss-panel>iframe{opacity:0;transition:opacity 120ms}
|
|
134
|
+
.ss-panel[data-open="true"]>div,.ss-panel[data-open="true"]>iframe{opacity:1;transition:opacity 240ms 170ms}
|
|
135
|
+
.ss-panel>div{display:flex;align-items:center;justify-content:space-between;padding:12px 18px;border-bottom:1px solid #e7e0e6}
|
|
136
|
+
.ss-panel>div>button{border:0;background:transparent;color:#554b58;padding:8px;border-radius:8px}
|
|
137
|
+
.ss-panel iframe{display:block;width:100%;flex:1;min-height:0;border:0;background:#fcfaf9}
|
|
138
|
+
[data-theme="dark"] .ss-panel{background:#18181b;color:#fff;border-color:#ffffff1c}
|
|
139
|
+
[data-theme="dark"] .ss-panel>div{border-color:#ffffff1c}
|
|
140
|
+
[data-theme="dark"] .ss-panel>div>button{color:#cbc5cd}
|
|
141
|
+
@media(prefers-color-scheme:dark){[data-theme="auto"] .ss-panel{background:#18181b;color:#fff;border-color:#ffffff1c}[data-theme="auto"] .ss-panel>div{border-color:#ffffff1c}[data-theme="auto"] .ss-panel>div>button{color:#cbc5cd}}
|
|
142
|
+
.ss-receiptCheck{position:absolute;right:0;top:0;display:grid;place-items:center;width:16px;height:16px;border:2px solid #18181b;border-radius:50%;background:#c6fa64;color:#18181b;font-size:10px}
|
|
143
|
+
@media(max-width:560px){.ss-widgetPosition{bottom:max(12px,env(safe-area-inset-bottom));right:auto;left:50%;transform:translateX(-50%);width:min(366px,calc(100vw - 24px))}.ss-panel{max-height:calc(100dvh - max(12px,env(safe-area-inset-bottom)) - 100px);transform-origin:bottom center}.ss-launcher{gap:10px;padding-right:15px;height:80px}.ss-launcherCopy{white-space:normal}.ss-launcherRow{justify-content:center}}
|
|
144
|
+
@media(prefers-reduced-motion:reduce){.ss-widgetPosition *,.ss-widgetPosition *::before,.ss-widgetPosition *::after{animation:none!important;transition:none!important}}
|
|
145
|
+
`;
|
|
146
|
+
shell.appendChild(style);
|
|
147
|
+
const row = document.createElement("div");
|
|
148
|
+
row.className = "ss-launcherRow";
|
|
149
|
+
const group = document.createElement("div");
|
|
150
|
+
group.className = "ss-launcherGroup";
|
|
151
|
+
const button = document.createElement("button");
|
|
152
|
+
button.type = "button";
|
|
153
|
+
const dismiss = document.createElement("button");
|
|
154
|
+
dismiss.type = "button";
|
|
155
|
+
dismiss.className = "ss-dismissInvitation";
|
|
156
|
+
dismiss.textContent = "\xD7";
|
|
157
|
+
dismiss.setAttribute("aria-label", "Dismiss invitation and keep a small button");
|
|
158
|
+
dismiss.onclick = () => {
|
|
159
|
+
r.attention = false;
|
|
160
|
+
r.dismissed = true;
|
|
161
|
+
try {
|
|
162
|
+
sessionStorage.setItem("sightspool-widget-dismissed:" + r.key, "1");
|
|
163
|
+
} catch (e) {
|
|
164
|
+
}
|
|
165
|
+
renderLauncher(r);
|
|
166
|
+
button.focus();
|
|
167
|
+
};
|
|
168
|
+
button.onanimationend = (event) => {
|
|
169
|
+
if (event.animationName.includes("invitation-glow")) {
|
|
170
|
+
r.attention = false;
|
|
171
|
+
renderLauncher(r);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
button.onclick = () => {
|
|
175
|
+
if (r.completed || r.frame || r.restoring) {
|
|
176
|
+
if (r.frame) expand(r, !r.expanded);
|
|
177
|
+
else openPanel(r);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (r.dismissed) {
|
|
181
|
+
r.attention = false;
|
|
182
|
+
r.dismissed = false;
|
|
183
|
+
try {
|
|
184
|
+
sessionStorage.setItem("sightspool-widget-dismissed:" + r.key, "0");
|
|
185
|
+
} catch (e) {
|
|
186
|
+
}
|
|
187
|
+
renderLauncher(r);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (!r.disposed && !r.paused && eligible(r)) openPanel(r);
|
|
191
|
+
};
|
|
192
|
+
group.appendChild(button);
|
|
193
|
+
group.appendChild(dismiss);
|
|
194
|
+
row.appendChild(group);
|
|
195
|
+
shell.appendChild(row);
|
|
196
|
+
r.shell = shell;
|
|
197
|
+
r.button = button;
|
|
198
|
+
r.dismiss = dismiss;
|
|
199
|
+
document.body.appendChild(shell);
|
|
200
|
+
renderLauncher(r);
|
|
201
|
+
}
|
|
26
202
|
function expand(r, expanded) {
|
|
27
203
|
var _a;
|
|
28
204
|
if (!r.panel || !r.frame || !r.button) return;
|
|
205
|
+
if (r.expanded === expanded) return;
|
|
206
|
+
const ownedFocus = r.panel.contains(document.activeElement);
|
|
29
207
|
r.expanded = expanded;
|
|
30
|
-
r.panel.
|
|
31
|
-
r.panel.
|
|
32
|
-
r.
|
|
208
|
+
r.panel.setAttribute("data-open", String(expanded));
|
|
209
|
+
r.panel.setAttribute("aria-hidden", String(!expanded));
|
|
210
|
+
r.panel.inert = !expanded;
|
|
33
211
|
r.button.setAttribute("aria-expanded", String(expanded));
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
212
|
+
renderLauncher(r);
|
|
213
|
+
if (expanded) (_a = r.panel.querySelector("button")) == null ? void 0 : _a.focus();
|
|
214
|
+
else if (ownedFocus) r.button.focus();
|
|
37
215
|
}
|
|
38
216
|
function openPanel(r) {
|
|
39
217
|
if (r.frame) {
|
|
40
218
|
expand(r, true);
|
|
41
219
|
return;
|
|
42
220
|
}
|
|
43
|
-
if (!r.offer || !r.button) return;
|
|
221
|
+
if (!r.offer && !r.restoring || !r.button || !r.shell) return;
|
|
44
222
|
const panel = document.createElement("section");
|
|
223
|
+
panel.className = "ss-panel";
|
|
45
224
|
panel.id = "sightspool-interview-panel";
|
|
46
225
|
panel.setAttribute("role", "dialog");
|
|
47
226
|
panel.setAttribute("aria-label", "Sightspool interview");
|
|
48
|
-
panel.style.cssText = "position:fixed;bottom:16px;right:16px;z-index:2147483001;box-sizing:border-box;width:420px;max-width:calc(100% - 32px);height:680px;max-height:calc(100dvh - 32px);border:1px solid #e6dfe3;border-radius:20px;background:#fff;color:#262024;box-shadow:0 12px 50px #0003;overflow:hidden;font:14px system-ui;display:flex;flex-direction:column";
|
|
49
227
|
const header = document.createElement("div");
|
|
50
|
-
header.style.cssText = "display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 16px;border-bottom:1px solid #eee;flex-shrink:0";
|
|
51
228
|
const title = document.createElement("strong");
|
|
52
229
|
title.textContent = "Sightspool";
|
|
53
230
|
const minimize = document.createElement("button");
|
|
54
231
|
minimize.type = "button";
|
|
55
|
-
minimize.textContent = "
|
|
56
|
-
|
|
57
|
-
const hide = () => {
|
|
58
|
-
expand(r, false);
|
|
59
|
-
};
|
|
232
|
+
minimize.textContent = "Minimise";
|
|
233
|
+
const hide = () => expand(r, false);
|
|
60
234
|
minimize.onclick = hide;
|
|
61
235
|
header.appendChild(title);
|
|
62
236
|
header.appendChild(minimize);
|
|
63
237
|
panel.appendChild(header);
|
|
64
238
|
const frame = document.createElement("iframe");
|
|
65
239
|
frame.title = "Sightspool research conversation";
|
|
66
|
-
frame.allow = "microphone; autoplay";
|
|
67
|
-
frame.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms");
|
|
240
|
+
frame.allow = "microphone; autoplay; clipboard-write";
|
|
241
|
+
frame.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox");
|
|
68
242
|
frame.referrerPolicy = "no-referrer";
|
|
69
|
-
frame.style.cssText = "display:block;width:100%;flex:1;min-height:0;border:0;background:#fff";
|
|
70
243
|
const url = new URL(r.endpoint + "/interview-widget");
|
|
71
244
|
url.searchParams.set("key", r.key);
|
|
72
|
-
url.
|
|
245
|
+
url.searchParams.set("theme", r.theme);
|
|
246
|
+
url.hash = new URLSearchParams(r.restoring ? { device: r.device, restore: "1" } : { offer: r.offer, device: r.device }).toString();
|
|
73
247
|
frame.src = url.href;
|
|
74
248
|
panel.appendChild(frame);
|
|
75
249
|
panel.onkeydown = (event) => {
|
|
@@ -81,27 +255,32 @@ function openPanel(r) {
|
|
|
81
255
|
r.panel = panel;
|
|
82
256
|
r.frame = frame;
|
|
83
257
|
r.message = (event) => {
|
|
84
|
-
var _a;
|
|
85
|
-
if (event.source !== frame.contentWindow || event.origin !== r.endpoint
|
|
86
|
-
hide();
|
|
258
|
+
var _a, _b, _c;
|
|
259
|
+
if (event.source !== frame.contentWindow || event.origin !== r.endpoint) return;
|
|
260
|
+
if (((_a = event.data) == null ? void 0 : _a.type) === "sightspool:panel:minimize") hide();
|
|
261
|
+
if (((_b = event.data) == null ? void 0 : _b.type) === "sightspool:interview:accepted") {
|
|
262
|
+
saveMarker(r, "active");
|
|
263
|
+
}
|
|
264
|
+
if (((_c = event.data) == null ? void 0 : _c.type) === "sightspool:interview:ended") {
|
|
265
|
+
r.completed = true;
|
|
266
|
+
saveMarker(r, "ended");
|
|
267
|
+
renderLauncher(r);
|
|
268
|
+
}
|
|
87
269
|
};
|
|
88
270
|
window.addEventListener("message", r.message);
|
|
89
|
-
r.button.textContent = "Return to interview";
|
|
90
|
-
r.button.setAttribute("aria-label", "Sightspool: return to your interview");
|
|
91
271
|
r.button.setAttribute("aria-controls", panel.id);
|
|
92
|
-
r.
|
|
93
|
-
expand(r, true);
|
|
94
|
-
};
|
|
95
|
-
document.body.appendChild(panel);
|
|
272
|
+
r.shell.appendChild(panel);
|
|
96
273
|
expand(r, true);
|
|
97
274
|
}
|
|
98
275
|
async function check(r) {
|
|
99
|
-
if (r.frame || r.disposed || r.paused || !eligible(r) || r.pending || document.visibilityState !== "visible") return;
|
|
276
|
+
if (r.frame || r.restoring || r.disposed || r.paused || !eligible(r) || r.pending || document.visibilityState !== "visible") return;
|
|
100
277
|
const generation = r.generation;
|
|
101
278
|
const request = new AbortController();
|
|
102
279
|
r.pending = request;
|
|
103
280
|
const timeout = window.setTimeout(() => request.abort(), 1e4);
|
|
104
281
|
if (!r.button) status(r, "checking");
|
|
282
|
+
const payload = { operation: "offer", key: r.key, device: r.device };
|
|
283
|
+
if (r.identity) payload.identity = r.identity;
|
|
105
284
|
try {
|
|
106
285
|
const response = await fetch(r.endpoint + "/widget-offer", {
|
|
107
286
|
method: "POST",
|
|
@@ -109,7 +288,7 @@ async function check(r) {
|
|
|
109
288
|
cache: "no-store",
|
|
110
289
|
referrerPolicy: "no-referrer",
|
|
111
290
|
headers: { "Content-Type": "application/json" },
|
|
112
|
-
body: JSON.stringify(
|
|
291
|
+
body: JSON.stringify(payload),
|
|
113
292
|
signal: request.signal
|
|
114
293
|
});
|
|
115
294
|
if (!response.ok) throw Error("offer unavailable");
|
|
@@ -122,21 +301,10 @@ async function check(r) {
|
|
|
122
301
|
}
|
|
123
302
|
r.offer = result.offer;
|
|
124
303
|
status(r, "available");
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
button.setAttribute("aria-label", "Sightspool: join a five-minute user interview");
|
|
130
|
-
button.style.cssText = "position:fixed;bottom:20px;right:20px;z-index:2147483000;padding:14px 18px;border:0;border-radius:999px;background:#ad1668;color:white;font:500 14px system-ui;box-shadow:0 8px 30px #0003;cursor:pointer;max-width:calc(100vw - 40px)";
|
|
131
|
-
button.onclick = () => {
|
|
132
|
-
try {
|
|
133
|
-
if (r.disposed || r.paused || !eligible(r) || !r.offer) return;
|
|
134
|
-
openPanel(r);
|
|
135
|
-
} catch (e) {
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
r.button = button;
|
|
139
|
-
document.body.appendChild(button);
|
|
304
|
+
if (result.invitation && typeof result.invitation.title === "string" && typeof result.invitation.subtitle === "string") {
|
|
305
|
+
r.copy = { title: result.invitation.title.slice(0, 200), subtitle: result.invitation.subtitle.slice(0, 240) };
|
|
306
|
+
}
|
|
307
|
+
mountLauncher(r);
|
|
140
308
|
} catch (e) {
|
|
141
309
|
if (!r.disposed && generation === r.generation) {
|
|
142
310
|
remove(r);
|
|
@@ -157,7 +325,7 @@ function init(config) {
|
|
|
157
325
|
if (url.username || url.password) return;
|
|
158
326
|
const previous = current();
|
|
159
327
|
if (previous && previous.key === config.key && previous.endpoint === url.origin && previous.audience === config.audience) return;
|
|
160
|
-
if (previous == null ? void 0 : previous.frame) return;
|
|
328
|
+
if ((previous == null ? void 0 : previous.frame) || (previous == null ? void 0 : previous.restoring)) return;
|
|
161
329
|
if (previous) destroy();
|
|
162
330
|
let device = "";
|
|
163
331
|
try {
|
|
@@ -173,11 +341,19 @@ function init(config) {
|
|
|
173
341
|
}
|
|
174
342
|
}
|
|
175
343
|
const r = {
|
|
344
|
+
theme: config.theme === "light" || config.theme === "auto" ? config.theme : "dark",
|
|
176
345
|
key: config.key,
|
|
177
346
|
endpoint: url.origin,
|
|
178
347
|
audience: config.audience,
|
|
179
|
-
|
|
348
|
+
identity: null,
|
|
180
349
|
paused: false,
|
|
350
|
+
attention: true,
|
|
351
|
+
dismissed: false,
|
|
352
|
+
completed: false,
|
|
353
|
+
restoring: false,
|
|
354
|
+
copy: { title: "Share your experience", subtitle: "A research conversation" },
|
|
355
|
+
shell: null,
|
|
356
|
+
dismiss: null,
|
|
181
357
|
disposed: false,
|
|
182
358
|
generation: 0,
|
|
183
359
|
device,
|
|
@@ -193,7 +369,18 @@ function init(config) {
|
|
|
193
369
|
},
|
|
194
370
|
status: "signed_out"
|
|
195
371
|
};
|
|
372
|
+
try {
|
|
373
|
+
r.dismissed = sessionStorage.getItem("sightspool-widget-dismissed:" + r.key) === "1";
|
|
374
|
+
const marker = sessionStorage.getItem(markerKey(r));
|
|
375
|
+
r.restoring = marker === "active" || marker === "ended";
|
|
376
|
+
r.completed = marker === "ended";
|
|
377
|
+
} catch (e) {
|
|
378
|
+
}
|
|
196
379
|
browser[slot] = r;
|
|
380
|
+
if (r.restoring) {
|
|
381
|
+
mountLauncher(r);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
197
384
|
r.visibility = () => {
|
|
198
385
|
try {
|
|
199
386
|
if (document.visibilityState === "visible") void check(r);
|
|
@@ -216,13 +403,14 @@ function identify(userId) {
|
|
|
216
403
|
try {
|
|
217
404
|
const r = current();
|
|
218
405
|
if (!r) return;
|
|
219
|
-
const
|
|
220
|
-
|
|
406
|
+
const trimmed = typeof userId === "string" ? userId.trim() : "";
|
|
407
|
+
const identity = trimmed.length > 0 && trimmed.length <= MAX_IDENTITY_LENGTH ? trimmed : null;
|
|
408
|
+
if (identity === r.identity) {
|
|
221
409
|
if (!r.paused && eligible(r)) void check(r);
|
|
222
410
|
return;
|
|
223
411
|
}
|
|
224
412
|
invalidate(r);
|
|
225
|
-
r.
|
|
413
|
+
r.identity = identity;
|
|
226
414
|
status(r, r.paused ? "paused" : eligible(r) ? "unavailable" : "signed_out");
|
|
227
415
|
if (eligible(r) && !r.paused) void check(r);
|
|
228
416
|
} catch (e) {
|
|
@@ -258,7 +446,7 @@ function destroy() {
|
|
|
258
446
|
invalidate(r);
|
|
259
447
|
window.clearInterval(r.timer);
|
|
260
448
|
document.removeEventListener("visibilitychange", r.visibility);
|
|
261
|
-
if (!r.frame) delete host()[slot];
|
|
449
|
+
if (!r.frame && !r.restoring) delete host()[slot];
|
|
262
450
|
} catch (e) {
|
|
263
451
|
}
|
|
264
452
|
}
|