@lookalike/widget 1.1.0 → 1.2.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/dist/README.md +2 -2
- package/dist/lookalike-widget.js +137 -15
- package/dist/lookalike-widget.min.js +1 -1
- package/package.json +1 -1
package/dist/README.md
CHANGED
package/dist/lookalike-widget.js
CHANGED
|
@@ -36,11 +36,15 @@ class LookalikeWidget extends HTMLElement {
|
|
|
36
36
|
this.currentIframe = null;
|
|
37
37
|
this.shadow = null;
|
|
38
38
|
this.messageHandler = null;
|
|
39
|
+
this.isInWixEmbed = false;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
connectedCallback() {
|
|
42
43
|
console.log('🚀 Lookalike Widget initializing...');
|
|
43
44
|
|
|
45
|
+
// Detect if we're in a Wix custom code embed (or similar constrained iframe)
|
|
46
|
+
this.detectWixEmbed();
|
|
47
|
+
|
|
44
48
|
// Create shadow DOM for encapsulation
|
|
45
49
|
this.shadow = this.attachShadow({ mode: 'closed' });
|
|
46
50
|
|
|
@@ -51,6 +55,34 @@ class LookalikeWidget extends HTMLElement {
|
|
|
51
55
|
this.initLive();
|
|
52
56
|
}
|
|
53
57
|
|
|
58
|
+
detectWixEmbed() {
|
|
59
|
+
try {
|
|
60
|
+
// Check if we're in an iframe and can't access parent
|
|
61
|
+
const inIframe = window !== window.parent;
|
|
62
|
+
|
|
63
|
+
// Check for Wix-specific indicators
|
|
64
|
+
const hasWixIndicators =
|
|
65
|
+
window.location.hostname.includes('wix.com') ||
|
|
66
|
+
window.location.hostname.includes('wixsite.com') ||
|
|
67
|
+
window.location.search.includes('wix') ||
|
|
68
|
+
document.referrer.includes('wix') ||
|
|
69
|
+
(inIframe && (
|
|
70
|
+
window.innerWidth < 500 || // Typical small embed size
|
|
71
|
+
window.innerHeight < 300
|
|
72
|
+
));
|
|
73
|
+
|
|
74
|
+
this.isInWixEmbed = inIframe && hasWixIndicators;
|
|
75
|
+
|
|
76
|
+
if (this.isInWixEmbed) {
|
|
77
|
+
console.log('🔍 Detected Wix embed environment - using full-screen overlay mode');
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
// If we can't access parent due to cross-origin, assume we're in an embed
|
|
81
|
+
this.isInWixEmbed = true;
|
|
82
|
+
console.log('🔍 Cross-origin iframe detected - using full-screen overlay mode');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
54
86
|
loadConfiguration() {
|
|
55
87
|
// Read configuration from HTML attributes
|
|
56
88
|
if (this.hasAttribute('uuid')) {
|
|
@@ -117,7 +149,41 @@ class LookalikeWidget extends HTMLElement {
|
|
|
117
149
|
initLive() {
|
|
118
150
|
console.log('🚀 Initializing live widget with config:', this.config);
|
|
119
151
|
|
|
120
|
-
|
|
152
|
+
if (this.isInWixEmbed) {
|
|
153
|
+
this.initWixEmbedMode();
|
|
154
|
+
} else {
|
|
155
|
+
this.initStandardMode();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
this.injectShadowContent();
|
|
159
|
+
this.injectIframe();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
initWixEmbedMode() {
|
|
163
|
+
console.log('📱 Initializing Wix embed mode with full-screen overlay');
|
|
164
|
+
|
|
165
|
+
// Make the host element a full-screen transparent overlay
|
|
166
|
+
this.style.cssText = `
|
|
167
|
+
position: fixed;
|
|
168
|
+
top: 0;
|
|
169
|
+
left: 0;
|
|
170
|
+
width: 100vw;
|
|
171
|
+
height: 100vh;
|
|
172
|
+
border: 0;
|
|
173
|
+
z-index: 9999;
|
|
174
|
+
background: transparent;
|
|
175
|
+
pointer-events: none;
|
|
176
|
+
display: block;
|
|
177
|
+
`;
|
|
178
|
+
|
|
179
|
+
// Add collapsed class initially
|
|
180
|
+
this.className = 'collapsed wix-embed';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
initStandardMode() {
|
|
184
|
+
console.log('💻 Initializing standard mode');
|
|
185
|
+
|
|
186
|
+
// Set host element positioning and initial size (original behavior)
|
|
121
187
|
this.style.cssText = `
|
|
122
188
|
position: fixed;
|
|
123
189
|
bottom: 16px;
|
|
@@ -136,9 +202,6 @@ class LookalikeWidget extends HTMLElement {
|
|
|
136
202
|
|
|
137
203
|
// Add collapsed class initially
|
|
138
204
|
this.className = 'collapsed';
|
|
139
|
-
|
|
140
|
-
this.injectShadowContent();
|
|
141
|
-
this.injectIframe();
|
|
142
205
|
}
|
|
143
206
|
|
|
144
207
|
injectShadowContent() {
|
|
@@ -151,18 +214,43 @@ class LookalikeWidget extends HTMLElement {
|
|
|
151
214
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
152
215
|
}
|
|
153
216
|
|
|
154
|
-
|
|
217
|
+
/* Standard mode styles */
|
|
218
|
+
:host(.collapsed:not(.wix-embed)) {
|
|
155
219
|
height: 60px !important;
|
|
156
220
|
max-height: 60px !important;
|
|
157
221
|
}
|
|
158
222
|
|
|
159
|
-
:host(.expanded) {
|
|
223
|
+
:host(.expanded:not(.wix-embed)) {
|
|
224
|
+
height: 520px;
|
|
225
|
+
max-height: calc(100vh - 32px);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* Wix embed mode: container for positioned widget */
|
|
229
|
+
.wix-widget-container {
|
|
230
|
+
position: absolute;
|
|
231
|
+
bottom: 16px;
|
|
232
|
+
right: 16px;
|
|
233
|
+
width: 380px;
|
|
234
|
+
height: 60px;
|
|
235
|
+
max-width: calc(100vw - 32px);
|
|
236
|
+
border-radius: 16px;
|
|
237
|
+
box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
|
|
238
|
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
239
|
+
background: transparent;
|
|
240
|
+
pointer-events: auto;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
:host(.wix-embed.collapsed) .wix-widget-container {
|
|
244
|
+
height: 60px;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
:host(.wix-embed.expanded) .wix-widget-container {
|
|
160
248
|
height: 520px;
|
|
161
249
|
max-height: calc(100vh - 32px);
|
|
162
250
|
}
|
|
163
251
|
|
|
164
252
|
@media (max-width: 639px) {
|
|
165
|
-
:host(.expanded) {
|
|
253
|
+
:host(.expanded:not(.wix-embed)) {
|
|
166
254
|
width: 100vw;
|
|
167
255
|
height: 100vh;
|
|
168
256
|
max-width: none;
|
|
@@ -173,13 +261,13 @@ class LookalikeWidget extends HTMLElement {
|
|
|
173
261
|
box-shadow: none;
|
|
174
262
|
}
|
|
175
263
|
|
|
176
|
-
:host {
|
|
264
|
+
:host(:not(.wix-embed)) {
|
|
177
265
|
width: calc(100vw - 16px);
|
|
178
266
|
right: 8px;
|
|
179
267
|
bottom: 8px;
|
|
180
268
|
}
|
|
181
269
|
|
|
182
|
-
:host(.collapsed) {
|
|
270
|
+
:host(.collapsed:not(.wix-embed)) {
|
|
183
271
|
height: 60px !important;
|
|
184
272
|
max-height: 60px !important;
|
|
185
273
|
width: calc(100vw - 16px);
|
|
@@ -188,6 +276,33 @@ class LookalikeWidget extends HTMLElement {
|
|
|
188
276
|
border-radius: 16px;
|
|
189
277
|
box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
|
|
190
278
|
}
|
|
279
|
+
|
|
280
|
+
/* Wix embed mobile styles */
|
|
281
|
+
:host(.wix-embed.expanded) .wix-widget-container {
|
|
282
|
+
width: 100vw;
|
|
283
|
+
height: 100vh;
|
|
284
|
+
max-width: none;
|
|
285
|
+
max-height: none;
|
|
286
|
+
bottom: 0;
|
|
287
|
+
right: 0;
|
|
288
|
+
border-radius: 0;
|
|
289
|
+
box-shadow: none;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.wix-widget-container {
|
|
293
|
+
width: calc(100vw - 16px);
|
|
294
|
+
right: 8px;
|
|
295
|
+
bottom: 8px;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
:host(.wix-embed.collapsed) .wix-widget-container {
|
|
299
|
+
height: 60px !important;
|
|
300
|
+
width: calc(100vw - 16px);
|
|
301
|
+
right: 8px;
|
|
302
|
+
bottom: 8px;
|
|
303
|
+
border-radius: 16px;
|
|
304
|
+
box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
|
|
305
|
+
}
|
|
191
306
|
}
|
|
192
307
|
|
|
193
308
|
.loading {
|
|
@@ -256,11 +371,18 @@ class LookalikeWidget extends HTMLElement {
|
|
|
256
371
|
|
|
257
372
|
// Create container for iframe
|
|
258
373
|
const container = document.createElement('div');
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
374
|
+
|
|
375
|
+
if (this.isInWixEmbed) {
|
|
376
|
+
// In Wix embed mode, create a positioned container within the full-screen overlay
|
|
377
|
+
container.className = 'wix-widget-container';
|
|
378
|
+
} else {
|
|
379
|
+
// In standard mode, container fills the host element
|
|
380
|
+
container.style.cssText = `
|
|
381
|
+
width: 100%;
|
|
382
|
+
height: 100%;
|
|
383
|
+
border-radius: inherit;
|
|
384
|
+
`;
|
|
385
|
+
}
|
|
264
386
|
|
|
265
387
|
this.shadow.appendChild(container);
|
|
266
388
|
}
|
|
@@ -296,7 +418,7 @@ class LookalikeWidget extends HTMLElement {
|
|
|
296
418
|
}
|
|
297
419
|
|
|
298
420
|
injectIframe() {
|
|
299
|
-
const container = this.shadow.querySelector('div:last-child');
|
|
421
|
+
const container = this.shadow.querySelector(this.isInWixEmbed ? '.wix-widget-container' : 'div:last-child');
|
|
300
422
|
|
|
301
423
|
// Remove existing iframe if present
|
|
302
424
|
const existingIframe = container.querySelector('iframe');
|
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
* Copy/paste embed widget for conversational AI avatars
|
|
6
6
|
* Usage: <lookalike-widget uuid="your-uuid"></lookalike-widget>
|
|
7
7
|
*/
|
|
8
|
-
const DEFAULT_UUID="019b4c51-7701-726a-8f59-e89a854682f3";function getBaseUrl(){const e=window.location.hostname;return"localhost"===e||"127.0.0.1"===e?(console.log("🏠 Local development detected"),"http://localhost:3000"):(console.log("🌐 Using production URL"),"https://lookalike.com")}const BASE_URL=getBaseUrl();class LookalikeWidget extends HTMLElement{constructor(){super(),this.config={storyfileUuid:null,primaryColor:"#2563eb",enableText:!0,enableVideo:!0,enableAudio:!0},this.currentIframe=null,this.shadow=null,this.messageHandler=null}connectedCallback(){console.log("🚀 Lookalike Widget initializing..."),this.shadow=this.attachShadow({mode:"closed"}),this.loadConfiguration(),this.initLive()}loadConfiguration(){this.hasAttribute("uuid")&&(this.config.storyfileUuid=this.getAttribute("uuid")),this.hasAttribute("color")&&(this.config.primaryColor=this.getAttribute("color")),this.hasAttribute("text")&&(this.config.enableText="false"!==this.getAttribute("text")),this.hasAttribute("video")&&(this.config.enableVideo="false"!==this.getAttribute("video")),this.hasAttribute("audio")&&(this.config.enableAudio="false"!==this.getAttribute("audio")),this.config.storyfileUuid||(this.config.storyfileUuid=DEFAULT_UUID,console.log("🔧 Using default UUID:",DEFAULT_UUID)),console.log("📥 Loaded config from attributes:",this.config)}static get observedAttributes(){return["uuid","color","text","video","audio"]}attributeChangedCallback(e,t,n){if(t!==n&&this.shadow){switch(console.log(`🔄 Attribute changed: ${e} = ${n}`),e){case"uuid":this.config.storyfileUuid=n;break;case"color":this.config.primaryColor=n;break;case"text":this.config.enableText="false"!==n;break;case"video":this.config.enableVideo="false"!==n;break;case"audio":this.config.enableAudio="false"!==n}console.log("🔄 Updated config after attribute change:",this.config),this.isConnected&&(this.shadow.innerHTML="",this.initLive())}}initLive(){console.log("🚀 Initializing live widget with config:",this.config),this.style.cssText="\n position: fixed;\n bottom: 16px;\n right: 16px;\n width: 380px;\n height: 60px;\n max-width: calc(100vw - 32px);\n border: 0;\n border-radius: 16px;\n z-index: 9999;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n background: transparent;\n display: block;\n ",this.className="collapsed",this.injectShadowContent(),this.injectIframe()}injectShadowContent(){const e=document.createElement("style");e.textContent="\n @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');\n \n :host {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n }\n\n :host(.collapsed) {\n height: 60px !important;\n max-height: 60px !important;\n }\n\n :host(.expanded) {\n height: 520px;\n max-height: calc(100vh - 32px);\n }\n\n @media (max-width: 639px) {\n :host(.expanded) {\n width: 100vw;\n height: 100vh;\n max-width: none;\n max-height: none;\n bottom: 0;\n right: 0;\n border-radius: 0;\n box-shadow: none;\n }\n \n :host {\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n }\n \n :host(.collapsed) {\n height: 60px !important;\n max-height: 60px !important;\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n }\n }\n \n .loading {\n background: #f3f4f6;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n border-radius: inherit;\n }\n \n .loading::after {\n content: 'Loading chat...';\n color: #6b7280;\n font-size: 14px;\n }\n\n .error-container {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n background: #f9fafb;\n border-radius: inherit;\n border: 2px dashed #d1d5db;\n color: #6b7280;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n text-align: center;\n padding: 20px;\n box-sizing: border-box;\n }\n\n .error-icon {\n font-size: 24px;\n margin-bottom: 8px;\n }\n\n .error-title {\n font-size: 14px;\n font-weight: 500;\n margin-bottom: 4px;\n }\n\n .error-message {\n font-size: 12px;\n }\n\n .error-uuid {\n font-size: 11px;\n margin-top: 8px;\n opacity: 0.7;\n }\n\n iframe {\n width: 100%;\n height: 100%;\n border: 0;\n border-radius: inherit;\n }\n ",this.shadow.appendChild(e);const t=document.createElement("div");t.style.cssText="\n width: 100%;\n height: 100%;\n border-radius: inherit;\n ",this.shadow.appendChild(t)}buildIframeSrc(){if(!this.config.storyfileUuid)return console.error("❌ No storyfile UUID configured"),null;const e=new URL(`/${this.config.storyfileUuid}/chat`,BASE_URL);e.searchParams.set("embed",""),e.searchParams.set("variant","floating"),e.searchParams.set("anchor","bottom-right");const t=[];return this.config.enableText&&t.push("text"),this.config.enableAudio&&t.push("audio"),this.config.enableVideo&&t.push("video"),t.length>0&&t.length<3&&e.searchParams.set("modes",t.join(",")),this.config.primaryColor&&"#2563eb"!==this.config.primaryColor&&e.searchParams.set("theme",`primary:${this.config.primaryColor}`),console.log("🔗 Built iframe URL:",e.toString()),e.toString()}injectIframe(){const e=this.shadow.querySelector("div:last-child"),t=e.querySelector("iframe");t&&t.remove();const n=this.buildIframeSrc();if(!n)return void this.showConfigurationError(e);const i=document.createElement("iframe");i.className="loading",i.src=n,i.allow="microphone; camera",i.loading="lazy",i.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-presentation"),i.onerror=()=>{console.error("❌ Failed to load widget iframe"),this.showLoadingError(e)},i.onload=()=>{console.log("✅ Iframe loaded successfully"),i.classList.remove("loading")},this.currentIframe=i,this.setupMessageHandling(i),e.appendChild(i)}setupMessageHandling(e){this.messageHandler&&window.removeEventListener("message",this.messageHandler),this.messageHandler=t=>{if(t.source===e.contentWindow&&"lookalike-widget-ready"===t.data?.type){console.log("🎉 Widget ready, setting up communication");const t=new MessageChannel;t.port1.onmessage=e=>{if(console.log("📏 Received resize message:",e.data),"lookalike-widget-resize"===e.data?.type){const t=e.data.collapsed?"collapsed":"expanded";console.log(`📏 Widget resize: ${this.className} → ${t}`),this.className=t}},e.contentWindow.postMessage({type:"lookalike-init-channel"},BASE_URL,[t.port2])}},window.addEventListener("message",this.messageHandler)}showConfigurationError(e){e.innerHTML='\n <div class="error-container">\n <div class="error-icon">⚠️</div>\n <div class="error-title">Configuration Error</div>\n <div class="error-message">No UUID configured. Please add a uuid attribute.</div>\n <div class="error-uuid">Expected: <lookalike-widget uuid="your-uuid"></div>\n </div>\n '}showLoadingError(e){e.innerHTML=`\n <div class="error-container">\n <div class="error-icon">⚠️</div>\n <div class="error-title">Widget Loading Error</div>\n <div class="error-message">Check console for details</div>\n <div class="error-uuid">UUID: ${this.config.storyfileUuid}</div>\n </div>\n `}disconnectedCallback(){this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null)}}customElements.define("lookalike-widget",LookalikeWidget),"undefined"!=typeof module&&module.exports&&(module.exports=LookalikeWidget);
|
|
8
|
+
const DEFAULT_UUID="019b4c51-7701-726a-8f59-e89a854682f3";function getBaseUrl(){const e=window.location.hostname;return"localhost"===e||"127.0.0.1"===e?(console.log("🏠 Local development detected"),"http://localhost:3000"):(console.log("🌐 Using production URL"),"https://lookalike.com")}const BASE_URL=getBaseUrl();class LookalikeWidget extends HTMLElement{constructor(){super(),this.config={storyfileUuid:null,primaryColor:"#2563eb",enableText:!0,enableVideo:!0,enableAudio:!0},this.currentIframe=null,this.shadow=null,this.messageHandler=null,this.isInWixEmbed=!1}connectedCallback(){console.log("🚀 Lookalike Widget initializing..."),this.detectWixEmbed(),this.shadow=this.attachShadow({mode:"closed"}),this.loadConfiguration(),this.initLive()}detectWixEmbed(){try{const e=window!==window.parent,n=window.location.hostname.includes("wix.com")||window.location.hostname.includes("wixsite.com")||window.location.search.includes("wix")||document.referrer.includes("wix")||e&&(window.innerWidth<500||window.innerHeight<300);this.isInWixEmbed=e&&n,this.isInWixEmbed&&console.log("🔍 Detected Wix embed environment - using full-screen overlay mode")}catch(e){this.isInWixEmbed=!0,console.log("🔍 Cross-origin iframe detected - using full-screen overlay mode")}}loadConfiguration(){this.hasAttribute("uuid")&&(this.config.storyfileUuid=this.getAttribute("uuid")),this.hasAttribute("color")&&(this.config.primaryColor=this.getAttribute("color")),this.hasAttribute("text")&&(this.config.enableText="false"!==this.getAttribute("text")),this.hasAttribute("video")&&(this.config.enableVideo="false"!==this.getAttribute("video")),this.hasAttribute("audio")&&(this.config.enableAudio="false"!==this.getAttribute("audio")),this.config.storyfileUuid||(this.config.storyfileUuid=DEFAULT_UUID,console.log("🔧 Using default UUID:",DEFAULT_UUID)),console.log("📥 Loaded config from attributes:",this.config)}static get observedAttributes(){return["uuid","color","text","video","audio"]}attributeChangedCallback(e,n,i){if(n!==i&&this.shadow){switch(console.log(`🔄 Attribute changed: ${e} = ${i}`),e){case"uuid":this.config.storyfileUuid=i;break;case"color":this.config.primaryColor=i;break;case"text":this.config.enableText="false"!==i;break;case"video":this.config.enableVideo="false"!==i;break;case"audio":this.config.enableAudio="false"!==i}console.log("🔄 Updated config after attribute change:",this.config),this.isConnected&&(this.shadow.innerHTML="",this.initLive())}}initLive(){console.log("🚀 Initializing live widget with config:",this.config),this.isInWixEmbed?this.initWixEmbedMode():this.initStandardMode(),this.injectShadowContent(),this.injectIframe()}initWixEmbedMode(){console.log("📱 Initializing Wix embed mode with full-screen overlay"),this.style.cssText="\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n border: 0;\n z-index: 9999;\n background: transparent;\n pointer-events: none;\n display: block;\n ",this.className="collapsed wix-embed"}initStandardMode(){console.log("💻 Initializing standard mode"),this.style.cssText="\n position: fixed;\n bottom: 16px;\n right: 16px;\n width: 380px;\n height: 60px;\n max-width: calc(100vw - 32px);\n border: 0;\n border-radius: 16px;\n z-index: 9999;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n background: transparent;\n display: block;\n ",this.className="collapsed"}injectShadowContent(){const e=document.createElement("style");e.textContent="\n @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');\n \n :host {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n }\n\n /* Standard mode styles */\n :host(.collapsed:not(.wix-embed)) {\n height: 60px !important;\n max-height: 60px !important;\n }\n\n :host(.expanded:not(.wix-embed)) {\n height: 520px;\n max-height: calc(100vh - 32px);\n }\n\n /* Wix embed mode: container for positioned widget */\n .wix-widget-container {\n position: absolute;\n bottom: 16px;\n right: 16px;\n width: 380px;\n height: 60px;\n max-width: calc(100vw - 32px);\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n background: transparent;\n pointer-events: auto;\n }\n\n :host(.wix-embed.collapsed) .wix-widget-container {\n height: 60px;\n }\n\n :host(.wix-embed.expanded) .wix-widget-container {\n height: 520px;\n max-height: calc(100vh - 32px);\n }\n\n @media (max-width: 639px) {\n :host(.expanded:not(.wix-embed)) {\n width: 100vw;\n height: 100vh;\n max-width: none;\n max-height: none;\n bottom: 0;\n right: 0;\n border-radius: 0;\n box-shadow: none;\n }\n \n :host(:not(.wix-embed)) {\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n }\n \n :host(.collapsed:not(.wix-embed)) {\n height: 60px !important;\n max-height: 60px !important;\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n }\n\n /* Wix embed mobile styles */\n :host(.wix-embed.expanded) .wix-widget-container {\n width: 100vw;\n height: 100vh;\n max-width: none;\n max-height: none;\n bottom: 0;\n right: 0;\n border-radius: 0;\n box-shadow: none;\n }\n \n .wix-widget-container {\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n }\n \n :host(.wix-embed.collapsed) .wix-widget-container {\n height: 60px !important;\n width: calc(100vw - 16px);\n right: 8px;\n bottom: 8px;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n }\n }\n \n .loading {\n background: #f3f4f6;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n border-radius: inherit;\n }\n \n .loading::after {\n content: 'Loading chat...';\n color: #6b7280;\n font-size: 14px;\n }\n\n .error-container {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n background: #f9fafb;\n border-radius: inherit;\n border: 2px dashed #d1d5db;\n color: #6b7280;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n text-align: center;\n padding: 20px;\n box-sizing: border-box;\n }\n\n .error-icon {\n font-size: 24px;\n margin-bottom: 8px;\n }\n\n .error-title {\n font-size: 14px;\n font-weight: 500;\n margin-bottom: 4px;\n }\n\n .error-message {\n font-size: 12px;\n }\n\n .error-uuid {\n font-size: 11px;\n margin-top: 8px;\n opacity: 0.7;\n }\n\n iframe {\n width: 100%;\n height: 100%;\n border: 0;\n border-radius: inherit;\n }\n ",this.shadow.appendChild(e);const n=document.createElement("div");this.isInWixEmbed?n.className="wix-widget-container":n.style.cssText="\n width: 100%;\n height: 100%;\n border-radius: inherit;\n ",this.shadow.appendChild(n)}buildIframeSrc(){if(!this.config.storyfileUuid)return console.error("❌ No storyfile UUID configured"),null;const e=new URL(`/${this.config.storyfileUuid}/chat`,BASE_URL);e.searchParams.set("embed",""),e.searchParams.set("variant","floating"),e.searchParams.set("anchor","bottom-right");const n=[];return this.config.enableText&&n.push("text"),this.config.enableAudio&&n.push("audio"),this.config.enableVideo&&n.push("video"),n.length>0&&n.length<3&&e.searchParams.set("modes",n.join(",")),this.config.primaryColor&&"#2563eb"!==this.config.primaryColor&&e.searchParams.set("theme",`primary:${this.config.primaryColor}`),console.log("🔗 Built iframe URL:",e.toString()),e.toString()}injectIframe(){const e=this.shadow.querySelector(this.isInWixEmbed?".wix-widget-container":"div:last-child"),n=e.querySelector("iframe");n&&n.remove();const i=this.buildIframeSrc();if(!i)return void this.showConfigurationError(e);const t=document.createElement("iframe");t.className="loading",t.src=i,t.allow="microphone; camera",t.loading="lazy",t.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-presentation"),t.onerror=()=>{console.error("❌ Failed to load widget iframe"),this.showLoadingError(e)},t.onload=()=>{console.log("✅ Iframe loaded successfully"),t.classList.remove("loading")},this.currentIframe=t,this.setupMessageHandling(t),e.appendChild(t)}setupMessageHandling(e){this.messageHandler&&window.removeEventListener("message",this.messageHandler),this.messageHandler=n=>{if(n.source===e.contentWindow&&"lookalike-widget-ready"===n.data?.type){console.log("🎉 Widget ready, setting up communication");const n=new MessageChannel;n.port1.onmessage=e=>{if(console.log("📏 Received resize message:",e.data),"lookalike-widget-resize"===e.data?.type){const n=e.data.collapsed?"collapsed":"expanded";console.log(`📏 Widget resize: ${this.className} → ${n}`),this.className=n}},e.contentWindow.postMessage({type:"lookalike-init-channel"},BASE_URL,[n.port2])}},window.addEventListener("message",this.messageHandler)}showConfigurationError(e){e.innerHTML='\n <div class="error-container">\n <div class="error-icon">⚠️</div>\n <div class="error-title">Configuration Error</div>\n <div class="error-message">No UUID configured. Please add a uuid attribute.</div>\n <div class="error-uuid">Expected: <lookalike-widget uuid="your-uuid"></div>\n </div>\n '}showLoadingError(e){e.innerHTML=`\n <div class="error-container">\n <div class="error-icon">⚠️</div>\n <div class="error-title">Widget Loading Error</div>\n <div class="error-message">Check console for details</div>\n <div class="error-uuid">UUID: ${this.config.storyfileUuid}</div>\n </div>\n `}disconnectedCallback(){this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null)}}customElements.define("lookalike-widget",LookalikeWidget),"undefined"!=typeof module&&module.exports&&(module.exports=LookalikeWidget);
|