ttp-agent-sdk 2.35.0 → 2.36.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/agent-widget.dev.js
CHANGED
|
@@ -10949,6 +10949,8 @@ var TTPEcommerceWidget = /*#__PURE__*/function () {
|
|
|
10949
10949
|
self._handleCartUpdatedFromServer(message);
|
|
10950
10950
|
} else if (type === 'add_to_store_cart') {
|
|
10951
10951
|
self._handleAddToStoreCart(message);
|
|
10952
|
+
} else if (type === 'get_store_cart') {
|
|
10953
|
+
self._handleGetStoreCart();
|
|
10952
10954
|
}
|
|
10953
10955
|
});
|
|
10954
10956
|
console.log('[TTPEcommerceWidget] E-commerce message listener attached');
|
|
@@ -11048,26 +11050,101 @@ var TTPEcommerceWidget = /*#__PURE__*/function () {
|
|
|
11048
11050
|
// ═══════════════════════════════════════════
|
|
11049
11051
|
|
|
11050
11052
|
/**
|
|
11051
|
-
*
|
|
11052
|
-
*
|
|
11053
|
-
* the store's
|
|
11054
|
-
*
|
|
11055
|
-
* We don't attempt to refresh the theme's cart UI (icon badge, drawer)
|
|
11056
|
-
* because there's no universal mechanism — every theme is different.
|
|
11057
|
-
* The user will see the updated cart when they navigate to /cart or refresh.
|
|
11058
|
-
* Our own CartToast + CartSummary provide immediate visual feedback.
|
|
11053
|
+
* Fetch cart contents from Shopify's AJAX Cart API and send back to backend.
|
|
11054
|
+
* Triggered when the LLM calls get_cart for a Shopify store.
|
|
11055
|
+
* Only the browser can read the store's cart because it requires the session cookie.
|
|
11059
11056
|
*/
|
|
11060
11057
|
}, {
|
|
11061
|
-
key: "
|
|
11058
|
+
key: "_handleGetStoreCart",
|
|
11062
11059
|
value: function () {
|
|
11063
|
-
var
|
|
11064
|
-
var
|
|
11060
|
+
var _handleGetStoreCart2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
11061
|
+
var response, cart, _t3;
|
|
11065
11062
|
return _regenerator().w(function (_context4) {
|
|
11066
11063
|
while (1) switch (_context4.p = _context4.n) {
|
|
11067
11064
|
case 0:
|
|
11068
|
-
|
|
11069
|
-
_context4.
|
|
11070
|
-
|
|
11065
|
+
_context4.p = 0;
|
|
11066
|
+
_context4.n = 1;
|
|
11067
|
+
return fetch('/cart.js', {
|
|
11068
|
+
method: 'GET',
|
|
11069
|
+
headers: {
|
|
11070
|
+
'Content-Type': 'application/json'
|
|
11071
|
+
}
|
|
11072
|
+
});
|
|
11073
|
+
case 1:
|
|
11074
|
+
response = _context4.v;
|
|
11075
|
+
if (response.ok) {
|
|
11076
|
+
_context4.n = 2;
|
|
11077
|
+
break;
|
|
11078
|
+
}
|
|
11079
|
+
console.error('[TTP Ecommerce] Failed to fetch /cart.js:', response.status);
|
|
11080
|
+
this._sendToVoiceSDK({
|
|
11081
|
+
t: 'cart_state_result',
|
|
11082
|
+
success: false,
|
|
11083
|
+
error: "Failed to fetch cart: HTTP ".concat(response.status)
|
|
11084
|
+
});
|
|
11085
|
+
return _context4.a(2);
|
|
11086
|
+
case 2:
|
|
11087
|
+
_context4.n = 3;
|
|
11088
|
+
return response.json();
|
|
11089
|
+
case 3:
|
|
11090
|
+
cart = _context4.v;
|
|
11091
|
+
this._sendToVoiceSDK({
|
|
11092
|
+
t: 'cart_state_result',
|
|
11093
|
+
success: true,
|
|
11094
|
+
items: (cart.items || []).map(function (item) {
|
|
11095
|
+
return {
|
|
11096
|
+
title: item.title,
|
|
11097
|
+
variant_title: item.variant_title,
|
|
11098
|
+
quantity: item.quantity,
|
|
11099
|
+
price: item.price,
|
|
11100
|
+
line_price: item.line_price,
|
|
11101
|
+
image: item.image,
|
|
11102
|
+
variant_id: item.variant_id,
|
|
11103
|
+
product_id: item.product_id
|
|
11104
|
+
};
|
|
11105
|
+
}),
|
|
11106
|
+
item_count: cart.item_count,
|
|
11107
|
+
total_price: cart.total_price,
|
|
11108
|
+
currency: cart.currency
|
|
11109
|
+
});
|
|
11110
|
+
console.log("[TTP Ecommerce] Cart state sent: ".concat(cart.item_count, " items, ").concat(cart.currency, " ").concat((cart.total_price / 100).toFixed(2)));
|
|
11111
|
+
_context4.n = 5;
|
|
11112
|
+
break;
|
|
11113
|
+
case 4:
|
|
11114
|
+
_context4.p = 4;
|
|
11115
|
+
_t3 = _context4.v;
|
|
11116
|
+
console.error('[TTP Ecommerce] Error fetching cart:', _t3);
|
|
11117
|
+
this._sendToVoiceSDK({
|
|
11118
|
+
t: 'cart_state_result',
|
|
11119
|
+
success: false,
|
|
11120
|
+
error: _t3.message || 'Failed to fetch cart'
|
|
11121
|
+
});
|
|
11122
|
+
case 5:
|
|
11123
|
+
return _context4.a(2);
|
|
11124
|
+
}
|
|
11125
|
+
}, _callee4, this, [[0, 4]]);
|
|
11126
|
+
}));
|
|
11127
|
+
function _handleGetStoreCart() {
|
|
11128
|
+
return _handleGetStoreCart2.apply(this, arguments);
|
|
11129
|
+
}
|
|
11130
|
+
return _handleGetStoreCart;
|
|
11131
|
+
}()
|
|
11132
|
+
/**
|
|
11133
|
+
* Add product to Shopify store cart via AJAX Cart API, then report result back to backend.
|
|
11134
|
+
* Must be done from the browser because only the browser has the store's session cookie.
|
|
11135
|
+
*/
|
|
11136
|
+
}, {
|
|
11137
|
+
key: "_handleAddToStoreCart",
|
|
11138
|
+
value: (function () {
|
|
11139
|
+
var _handleAddToStoreCart2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(data) {
|
|
11140
|
+
var variantId, quantity, productName, addResponse, errorText, addResult, cartResponse, cart, cartRefreshed, _t4;
|
|
11141
|
+
return _regenerator().w(function (_context5) {
|
|
11142
|
+
while (1) switch (_context5.p = _context5.n) {
|
|
11143
|
+
case 0:
|
|
11144
|
+
variantId = data.variantId, quantity = data.quantity;
|
|
11145
|
+
productName = '';
|
|
11146
|
+
_context5.p = 1;
|
|
11147
|
+
_context5.n = 2;
|
|
11071
11148
|
return fetch('/cart/add.js', {
|
|
11072
11149
|
method: 'POST',
|
|
11073
11150
|
headers: {
|
|
@@ -11075,57 +11152,117 @@ var TTPEcommerceWidget = /*#__PURE__*/function () {
|
|
|
11075
11152
|
},
|
|
11076
11153
|
body: JSON.stringify({
|
|
11077
11154
|
items: [{
|
|
11078
|
-
id: parseInt(variantId
|
|
11155
|
+
id: parseInt(variantId),
|
|
11079
11156
|
quantity: quantity || 1
|
|
11080
11157
|
}]
|
|
11081
11158
|
})
|
|
11082
11159
|
});
|
|
11083
11160
|
case 2:
|
|
11084
|
-
|
|
11085
|
-
if (
|
|
11086
|
-
|
|
11161
|
+
addResponse = _context5.v;
|
|
11162
|
+
if (addResponse.ok) {
|
|
11163
|
+
_context5.n = 4;
|
|
11087
11164
|
break;
|
|
11088
11165
|
}
|
|
11089
|
-
|
|
11090
|
-
return
|
|
11166
|
+
_context5.n = 3;
|
|
11167
|
+
return addResponse.text();
|
|
11091
11168
|
case 3:
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
|
|
11096
|
-
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
|
|
11169
|
+
errorText = _context5.v;
|
|
11170
|
+
console.error('[TTP Ecommerce] /cart/add.js failed:', addResponse.status, errorText);
|
|
11171
|
+
this._sendToVoiceSDK({
|
|
11172
|
+
t: 'cart_add_result',
|
|
11173
|
+
success: false,
|
|
11174
|
+
error: "Cart add failed: HTTP ".concat(addResponse.status),
|
|
11175
|
+
productName: productName || String(variantId),
|
|
11176
|
+
quantity: quantity || 1
|
|
11100
11177
|
});
|
|
11178
|
+
return _context5.a(2);
|
|
11179
|
+
case 4:
|
|
11180
|
+
_context5.n = 5;
|
|
11181
|
+
return addResponse.json();
|
|
11101
11182
|
case 5:
|
|
11102
|
-
|
|
11183
|
+
addResult = _context5.v;
|
|
11184
|
+
if (addResult.items && addResult.items.length > 0) {
|
|
11185
|
+
productName = addResult.items[0].title || '';
|
|
11186
|
+
}
|
|
11187
|
+
_context5.n = 6;
|
|
11188
|
+
return fetch('/cart.js');
|
|
11189
|
+
case 6:
|
|
11190
|
+
cartResponse = _context5.v;
|
|
11191
|
+
_context5.n = 7;
|
|
11192
|
+
return cartResponse.json();
|
|
11193
|
+
case 7:
|
|
11194
|
+
cart = _context5.v;
|
|
11195
|
+
cartRefreshed = false;
|
|
11196
|
+
try {
|
|
11197
|
+
cartRefreshed = this._refreshCartCount(cart.item_count);
|
|
11198
|
+
} catch (e) {
|
|
11199
|
+
console.warn('[TTP Ecommerce] Cart count refresh failed (non-critical):', e);
|
|
11200
|
+
}
|
|
11103
11201
|
this._handleCartUpdatedFromServer({
|
|
11104
11202
|
action: 'added',
|
|
11105
11203
|
product: {
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
price: price || ((_cartResponse$items2 = cartResponse.items) === null || _cartResponse$items2 === void 0 || (_cartResponse$items2 = _cartResponse$items2[0]) === null || _cartResponse$items2 === void 0 ? void 0 : _cartResponse$items2.price) / 100 || 0
|
|
11204
|
+
name: productName,
|
|
11205
|
+
id: variantId
|
|
11109
11206
|
},
|
|
11110
|
-
cartTotal:
|
|
11111
|
-
cartItemCount:
|
|
11207
|
+
cartTotal: cart.total_price / 100,
|
|
11208
|
+
cartItemCount: cart.item_count,
|
|
11209
|
+
currency: cart.currency
|
|
11112
11210
|
});
|
|
11113
|
-
|
|
11211
|
+
this._sendToVoiceSDK({
|
|
11212
|
+
t: 'cart_add_result',
|
|
11213
|
+
success: true,
|
|
11214
|
+
cartRefreshed: cartRefreshed,
|
|
11215
|
+
productName: productName,
|
|
11216
|
+
quantity: quantity || 1,
|
|
11217
|
+
cartTotal: cart.total_price,
|
|
11218
|
+
cartItemCount: cart.item_count,
|
|
11219
|
+
currency: cart.currency
|
|
11220
|
+
});
|
|
11221
|
+
console.log("[TTP Ecommerce] Cart add result sent: ".concat(productName, ", refreshed=").concat(cartRefreshed, ", ").concat(cart.item_count, " items"));
|
|
11222
|
+
_context5.n = 9;
|
|
11114
11223
|
break;
|
|
11115
|
-
case
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
console.error('[
|
|
11119
|
-
|
|
11120
|
-
|
|
11224
|
+
case 8:
|
|
11225
|
+
_context5.p = 8;
|
|
11226
|
+
_t4 = _context5.v;
|
|
11227
|
+
console.error('[TTP Ecommerce] Error in _handleAddToStoreCart:', _t4);
|
|
11228
|
+
this._sendToVoiceSDK({
|
|
11229
|
+
t: 'cart_add_result',
|
|
11230
|
+
success: false,
|
|
11231
|
+
error: _t4.message || 'Failed to add to cart',
|
|
11232
|
+
productName: productName || String(variantId),
|
|
11233
|
+
quantity: quantity || 1
|
|
11234
|
+
});
|
|
11235
|
+
case 9:
|
|
11236
|
+
return _context5.a(2);
|
|
11121
11237
|
}
|
|
11122
|
-
},
|
|
11238
|
+
}, _callee5, this, [[1, 8]]);
|
|
11123
11239
|
}));
|
|
11124
11240
|
function _handleAddToStoreCart(_x2) {
|
|
11125
11241
|
return _handleAddToStoreCart2.apply(this, arguments);
|
|
11126
11242
|
}
|
|
11127
11243
|
return _handleAddToStoreCart;
|
|
11128
|
-
}()
|
|
11244
|
+
}()
|
|
11245
|
+
/**
|
|
11246
|
+
* Simple cart count refresh — update common counter selectors.
|
|
11247
|
+
* Theme-specific refresh (Section Rendering API, etc.) can be added later per-theme.
|
|
11248
|
+
* @returns {boolean} Whether any element was updated
|
|
11249
|
+
*/
|
|
11250
|
+
)
|
|
11251
|
+
}, {
|
|
11252
|
+
key: "_refreshCartCount",
|
|
11253
|
+
value: function _refreshCartCount(itemCount) {
|
|
11254
|
+
var refreshed = false;
|
|
11255
|
+
var selectors = ['.cart-count', '.cart-count-bubble', '[data-cart-count]', '.js-cart-count', '.cart-item-count', '#CartCount', '.site-header__cart-count', '.cart-count-tag'];
|
|
11256
|
+
selectors.forEach(function (selector) {
|
|
11257
|
+
document.querySelectorAll(selector).forEach(function (el) {
|
|
11258
|
+
el.textContent = itemCount;
|
|
11259
|
+
refreshed = true;
|
|
11260
|
+
});
|
|
11261
|
+
});
|
|
11262
|
+
return refreshed;
|
|
11263
|
+
}
|
|
11264
|
+
|
|
11265
|
+
// ═══════════════════════════════════════════
|
|
11129
11266
|
// PRODUCT SELECTION (server manages cart)
|
|
11130
11267
|
// ═══════════════════════════════════════════
|
|
11131
11268
|
}, {
|
|
@@ -11181,45 +11318,45 @@ var TTPEcommerceWidget = /*#__PURE__*/function () {
|
|
|
11181
11318
|
self.ecommerce.handleMessage(payload);
|
|
11182
11319
|
},
|
|
11183
11320
|
showProducts: function () {
|
|
11184
|
-
var _showProducts = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
11321
|
+
var _showProducts = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(query) {
|
|
11185
11322
|
var limit,
|
|
11186
11323
|
sessionId,
|
|
11187
11324
|
baseUrl,
|
|
11188
11325
|
response,
|
|
11189
11326
|
data,
|
|
11190
|
-
|
|
11191
|
-
|
|
11192
|
-
return _regenerator().w(function (
|
|
11193
|
-
while (1) switch (
|
|
11327
|
+
_args6 = arguments,
|
|
11328
|
+
_t5;
|
|
11329
|
+
return _regenerator().w(function (_context6) {
|
|
11330
|
+
while (1) switch (_context6.p = _context6.n) {
|
|
11194
11331
|
case 0:
|
|
11195
|
-
limit =
|
|
11196
|
-
sessionId =
|
|
11332
|
+
limit = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : 5;
|
|
11333
|
+
sessionId = _args6.length > 2 && _args6[2] !== undefined ? _args6[2] : 'test';
|
|
11197
11334
|
baseUrl = window.__TTP_MOCK_API__ || 'https://backend.talktopc.com';
|
|
11198
|
-
|
|
11199
|
-
|
|
11335
|
+
_context6.p = 1;
|
|
11336
|
+
_context6.n = 2;
|
|
11200
11337
|
return fetch("".concat(baseUrl, "/api/partner/mock-store/products/search?q=").concat(encodeURIComponent(query), "&limit=").concat(limit, "&sessionId=").concat(encodeURIComponent(sessionId)));
|
|
11201
11338
|
case 2:
|
|
11202
|
-
response =
|
|
11203
|
-
|
|
11339
|
+
response = _context6.v;
|
|
11340
|
+
_context6.n = 3;
|
|
11204
11341
|
return response.json();
|
|
11205
11342
|
case 3:
|
|
11206
|
-
data =
|
|
11343
|
+
data = _context6.v;
|
|
11207
11344
|
self.ecommerce.handleShowProducts({
|
|
11208
11345
|
t: 'show_products',
|
|
11209
11346
|
products: data.products,
|
|
11210
11347
|
title: "".concat(data.totalCount, " results for \"").concat(query, "\""),
|
|
11211
11348
|
layout: data.products.length <= 4 ? 'cards' : 'list'
|
|
11212
11349
|
});
|
|
11213
|
-
|
|
11350
|
+
_context6.n = 5;
|
|
11214
11351
|
break;
|
|
11215
11352
|
case 4:
|
|
11216
|
-
|
|
11217
|
-
|
|
11218
|
-
console.error('[TTPEcommerceWidget] showProducts failed:',
|
|
11353
|
+
_context6.p = 4;
|
|
11354
|
+
_t5 = _context6.v;
|
|
11355
|
+
console.error('[TTPEcommerceWidget] showProducts failed:', _t5);
|
|
11219
11356
|
case 5:
|
|
11220
|
-
return
|
|
11357
|
+
return _context6.a(2);
|
|
11221
11358
|
}
|
|
11222
|
-
},
|
|
11359
|
+
}, _callee6, null, [[1, 4]]);
|
|
11223
11360
|
}));
|
|
11224
11361
|
function showProducts(_x3) {
|
|
11225
11362
|
return _showProducts.apply(this, arguments);
|
|
@@ -21150,6 +21287,9 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
21150
21287
|
// Callback to show error toast (for domain errors, etc.)
|
|
21151
21288
|
onErrorToast: function onErrorToast(message, type) {
|
|
21152
21289
|
_this.showErrorToast(message, type);
|
|
21290
|
+
},
|
|
21291
|
+
onMobileError: function onMobileError(message) {
|
|
21292
|
+
_this.showMobileLandingError(message);
|
|
21153
21293
|
}
|
|
21154
21294
|
});
|
|
21155
21295
|
this.voiceInterface = new _VoiceInterface_js__WEBPACK_IMPORTED_MODULE_1__.VoiceInterface(voiceConfig);
|
|
@@ -21442,7 +21582,10 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
21442
21582
|
voiceCardIcon: cleanLandingConfig.voiceCardIcon || '🎤',
|
|
21443
21583
|
textCardIcon: cleanLandingConfig.textCardIcon || '💬',
|
|
21444
21584
|
voiceCardTitle: cleanLandingConfig.voiceCardTitle || null,
|
|
21445
|
-
textCardTitle: cleanLandingConfig.textCardTitle || null
|
|
21585
|
+
textCardTitle: cleanLandingConfig.textCardTitle || null,
|
|
21586
|
+
callButtonText: cleanLandingConfig.callButtonText || null,
|
|
21587
|
+
chatButtonText: cleanLandingConfig.chatButtonText || null,
|
|
21588
|
+
statusText: cleanLandingConfig.statusText || null
|
|
21446
21589
|
}, cleanLandingConfig);
|
|
21447
21590
|
}(),
|
|
21448
21591
|
// Header Configuration (top of panel)
|
|
@@ -21472,7 +21615,8 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
21472
21615
|
backgroundColor: cleanHeaderConfig.backgroundColor || '#7C3AED',
|
|
21473
21616
|
// Default purple
|
|
21474
21617
|
textColor: cleanHeaderConfig.textColor || '#FFFFFF',
|
|
21475
|
-
showCloseButton: cleanHeaderConfig.showCloseButton !== false
|
|
21618
|
+
showCloseButton: cleanHeaderConfig.showCloseButton !== false,
|
|
21619
|
+
mobileLabel: cleanHeaderConfig.mobileLabel || 'Chat'
|
|
21476
21620
|
}, cleanHeaderConfig);
|
|
21477
21621
|
return finalHeader;
|
|
21478
21622
|
}(),
|
|
@@ -21678,10 +21822,10 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
21678
21822
|
var resetCSS = '';
|
|
21679
21823
|
if (this.config.useShadowDOM) {
|
|
21680
21824
|
// Shadow DOM mode - use :host selector
|
|
21681
|
-
resetCSS = "\n :host {\n all: initial;\n display: block;\n pointer-events: none;\n }\n img {\n max-width: none !important;\n }\n #text-chat-button img {\n width: 28px !important;\n height: 28px !important;\n }\n #text-chat-button {\n pointer-events: auto;\n }\n #text-chat-panel {\n pointer-events: auto;\n }\n ";
|
|
21825
|
+
resetCSS = "\n :host {\n all: initial;\n display: block;\n pointer-events: none;\n }\n img {\n max-width: none !important;\n }\n #text-chat-button img {\n width: 28px !important;\n height: 28px !important;\n }\n #text-chat-button {\n pointer-events: auto;\n }\n #text-chat-panel {\n pointer-events: auto;\n }\n .ttp-mobile-fab {\n pointer-events: auto;\n }\n #ttpMobileLanding {\n pointer-events: auto;\n }\n ";
|
|
21682
21826
|
} else {
|
|
21683
21827
|
// Regular DOM mode - targeted reset without breaking widget styles
|
|
21684
|
-
resetCSS = "\n /* Reset only problematic inherited styles, not all styles */\n #text-chat-button,\n #text-chat-panel,\n #text-chat-panel * {\n box-sizing: border-box;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n }\n \n /* Prevent theme CSS from affecting images */\n #text-chat-button img,\n #text-chat-panel img {\n max-width: none !important;\n width: auto;\n height: auto;\n }\n \n #text-chat-button img {\n width: 28px !important;\n height: 28px !important;\n }\n \n /* Ensure button and panel can receive clicks */\n #text-chat-button,\n #text-chat-panel {\n pointer-events: auto;\n }\n \n /* Reset any inherited text styles that might break layout */\n #text-chat-panel {\n text-align: left;\n line-height: normal;\n letter-spacing: normal;\n word-spacing: normal;\n text-transform: none;\n text-indent: 0;\n text-shadow: none;\n white-space: normal;\n }\n \n /* Ensure flexbox works properly */\n #text-chat-panel .widget-shell,\n #text-chat-panel .panel-inner,\n #text-chat-panel .widget-container,\n #text-chat-panel .landing-screen,\n #text-chat-panel .voice-interface,\n #text-chat-panel .text-interface,\n #text-chat-panel .widget-header,\n #text-chat-panel .mode-selection {\n display: flex;\n }\n \n #text-chat-panel .widget-shell,\n #text-chat-panel .panel-inner,\n #text-chat-panel .widget-container,\n #text-chat-panel .landing-screen,\n #text-chat-panel .voice-interface,\n #text-chat-panel .text-interface {\n flex-direction: column;\n }\n \n #text-chat-panel .mode-selection {\n flex-direction: row;\n }\n \n /* Ensure proper stacking */\n #text-chat-button {\n z-index: 10001 !important;\n }\n \n #text-chat-panel {\n z-index: 10000 !important;\n }\n ";
|
|
21828
|
+
resetCSS = "\n /* Reset only problematic inherited styles, not all styles */\n #text-chat-button,\n #text-chat-panel,\n #text-chat-panel * {\n box-sizing: border-box;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n }\n \n /* Prevent theme CSS from affecting images */\n #text-chat-button img,\n #text-chat-panel img {\n max-width: none !important;\n width: auto;\n height: auto;\n }\n \n #text-chat-button img {\n width: 28px !important;\n height: 28px !important;\n }\n \n /* Ensure button and panel can receive clicks */\n #text-chat-button,\n #text-chat-panel,\n .ttp-mobile-fab,\n #ttpMobileLanding {\n pointer-events: auto;\n }\n \n /* Reset any inherited text styles that might break layout */\n #text-chat-panel {\n text-align: left;\n line-height: normal;\n letter-spacing: normal;\n word-spacing: normal;\n text-transform: none;\n text-indent: 0;\n text-shadow: none;\n white-space: normal;\n }\n \n /* Ensure flexbox works properly */\n #text-chat-panel .widget-shell,\n #text-chat-panel .panel-inner,\n #text-chat-panel .widget-container,\n #text-chat-panel .landing-screen,\n #text-chat-panel .voice-interface,\n #text-chat-panel .text-interface,\n #text-chat-panel .widget-header,\n #text-chat-panel .mode-selection {\n display: flex;\n }\n \n #text-chat-panel .widget-shell,\n #text-chat-panel .panel-inner,\n #text-chat-panel .widget-container,\n #text-chat-panel .landing-screen,\n #text-chat-panel .voice-interface,\n #text-chat-panel .text-interface {\n flex-direction: column;\n }\n \n #text-chat-panel .mode-selection {\n flex-direction: row;\n }\n \n /* Ensure proper stacking */\n #text-chat-button {\n z-index: 10001 !important;\n }\n \n #text-chat-panel {\n z-index: 10000 !important;\n }\n ";
|
|
21685
21829
|
}
|
|
21686
21830
|
var widgetHTML = this.generateWidgetHTML();
|
|
21687
21831
|
if (this.config.useShadowDOM) {
|
|
@@ -21850,7 +21994,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
21850
21994
|
isPromptEnabled: isPromptEnabled,
|
|
21851
21995
|
willGenerateHTML: !!promptBubbleHTML
|
|
21852
21996
|
});
|
|
21853
|
-
return "\n ".concat(styleTag, "\n \n ").concat(this.config.behavior.hidden ? '' : "\n <div id=\"text-chat-button-container\">\n ".concat(promptBubbleHTML, "\n ").concat(isPromptEnabled && promptConfig.showPulseRings !== false ? this.generatePulseRingsHTML(promptConfig) : '', "\n <button id=\"text-chat-button\" \n aria-label=\"").concat(this.config.accessibility.ariaLabel, "\"\n aria-description=\"").concat(this.config.accessibility.ariaDescription, "\">\n
|
|
21997
|
+
return "\n ".concat(styleTag, "\n \n ").concat(this.config.behavior.hidden ? '' : "\n <div id=\"text-chat-button-container\">\n ".concat(promptBubbleHTML, "\n ").concat(isPromptEnabled && promptConfig.showPulseRings !== false ? this.generatePulseRingsHTML(promptConfig) : '', "\n <button id=\"text-chat-button\" \n aria-label=\"").concat(this.config.accessibility.ariaLabel, "\"\n aria-description=\"").concat(this.config.accessibility.ariaDescription, "\">\n ").concat(iconHTML, "\n </button>\n <button class=\"ttp-mobile-fab\" aria-label=\"").concat(this.config.accessibility.ariaLabel, "\">\n <div class=\"ttp-mobile-fab__icon-wrap\">\n <div class=\"ttp-mobile-fab__waveform\">\n <span class=\"bar\"></span><span class=\"bar\"></span><span class=\"bar\"></span><span class=\"bar\"></span><span class=\"bar\"></span>\n </div>\n </div>\n <div class=\"ttp-mobile-fab__label-wrap\">\n <span class=\"ttp-mobile-fab__label\">").concat(header.mobileLabel || 'Chat', "</span>\n <span class=\"ttp-mobile-fab__status\">\n <span class=\"ttp-mobile-fab__dot\"></span>\n ").concat(header.onlineIndicatorText !== undefined && header.onlineIndicatorText !== null ? header.onlineIndicatorText : t('online'), "\n </span>\n </div>\n </button>\n </div>\n "), "\n\n ").concat(this.config.behavior.hidden ? '' : "\n <div id=\"ttpMobileLanding\" class=\"ttp-mobile-landing\">\n <div class=\"ttp-mobile-landing__header\">\n <div class=\"ttp-mobile-landing__avatar\">\n <div class=\"ttp-mobile-landing__waveform\">\n <span class=\"bar\"></span><span class=\"bar\"></span><span class=\"bar\"></span><span class=\"bar\"></span><span class=\"bar\"></span>\n </div>\n </div>\n <div class=\"ttp-mobile-landing__info\">\n <div class=\"ttp-mobile-landing__name\">".concat(header.title || 'Chat Assistant', "</div>\n <div class=\"ttp-mobile-landing__status\">\n <span class=\"ttp-mobile-landing__dot\"></span>\n ").concat(this.config.landing.statusText || t('online') + ' • ' + (this.config.landing.subtitle || 'Ready to help'), "\n </div>\n </div>\n <button class=\"ttp-mobile-landing__close\" aria-label=\"Close\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n <div class=\"ttp-mobile-landing__error\" id=\"ttpMobileLandingError\" style=\"display:none;\">\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\n </svg>\n <span class=\"ttp-mobile-landing__error-text\"></span>\n </div>\n <div class=\"ttp-mobile-landing__actions\">\n ").concat(showVoice ? "\n <button class=\"ttp-mobile-landing__btn ttp-mobile-landing__btn--call\" id=\"ttpMobileCallBtn\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z\"/>\n </svg>\n ".concat(this.config.landing.callButtonText || this.config.landing.voiceCardTitle || t('voiceCall'), "\n </button>\n ") : '', "\n ").concat(showText ? "\n <button class=\"ttp-mobile-landing__btn ttp-mobile-landing__btn--text\" id=\"ttpMobileChatBtn\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/>\n </svg>\n ".concat(this.config.landing.chatButtonText || this.config.landing.textCardTitle || t('textChat'), "\n </button>\n ") : '', "\n </div>\n ").concat(this.config.footer.show !== false ? "\n <div class=\"ttp-mobile-landing__footer\">\n <div class=\"ttp-mobile-landing__powered\">\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"10\" height=\"10\">\n <polygon points=\"13 2 3 14 12 14 11 22 21 10 12 10 13 2\"/>\n </svg>\n Powered by <a href=\"https://talktopc.com\" target=\"_blank\" rel=\"noopener\">TalkToPC</a>\n </div>\n </div>\n " : '', "\n </div>\n "), "\n \n <div id=\"text-chat-panel\">\n <div class=\"widget-shell\">\n <div class=\"panel-inner widget-container\" style=\"direction: ").concat(this.config.direction, ";\">\n <div class=\"widget-header\" style=\"background: ").concat(header.backgroundColor || '#7C3AED', " !important; color: ").concat(header.textColor || '#FFFFFF', " !important;\">\n <div>\n ").concat(header.showTitle ? "<div class=\"header-title\">".concat(header.title, "</div>") : '', "\n <div class=\"header-status\" style=\"color: ").concat(header.onlineIndicatorColor || 'rgba(255,255,255,0.7)', " !important;\">\n <span class=\"status-dot\" style=\"background: ").concat(header.onlineIndicatorDotColor || '#10b981', " !important;\"></span>\n <span>").concat(header.onlineIndicatorText !== undefined && header.onlineIndicatorText !== null ? header.onlineIndicatorText : t('online'), "</span>\n </div>\n </div>\n \n <div style=\"display: flex; gap: 6px; align-items: center; position: relative; z-index: 1;\">\n <!-- New Chat Button (hide on landing screen, show otherwise) -->\n <button class=\"header-icon new-chat-btn\" id=\"newChatBtn\" title=\"").concat(getTooltip('newChat'), "\" style=\"").concat(showLanding ? 'display: none;' : '', "\">\n <span style=\"font-size: 18px; font-weight: bold;\">+</span>\n </button>\n \n <!-- Back Button (only show in unified mode) -->\n ").concat(widgetMode === 'unified' ? "<button class=\"header-icon back-btn\" id=\"backBtn\" title=\"".concat(getTooltip('back'), "\" style=\"display: none;\">\n <span style=\"font-size: 16px;\">\u2039</span>\n </button>") : '', "\n \n <!-- Close Button -->\n ").concat(header.showCloseButton ? '<button class="header-icon close-btn" id="closeBtn" title="' + getTooltip('close') + '">' + '<span style="font-size: 18px; font-weight: bold;">×</span>' + '</button>' : '', "\n </div>\n </div>\n\n ").concat(showLanding && this.landingScreen ? this.landingScreen.generateHTML() : '', "\n\n ").concat(showVoice ? this.voiceInterface.generateHTML() : '', "\n ").concat(showText ? this.textInterface.generateHTML() : '', "\n ").concat(this.generateFooterHTML(), "\n </div>\n </div>\n </div>\n ");
|
|
21854
21998
|
}
|
|
21855
21999
|
|
|
21856
22000
|
/**
|
|
@@ -21976,7 +22120,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
21976
22120
|
// Note: Removed headerColor variable - landing screen colors now use explicit defaults
|
|
21977
22121
|
// to prevent buttons from inheriting header backgroundColor
|
|
21978
22122
|
|
|
21979
|
-
return "\n /* MOBILE FIRST - Default styles for all devices */\n #text-chat-widget {\n position: fixed !important;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n /* Mobile defaults */\n right: 10px;\n bottom: 10px;\n left: auto;\n top: auto;\n }\n \n /* Desktop positioning (only on larger screens) */\n @media (min-width: 769px) {\n #text-chat-widget {\n ".concat(positionStyles, "\n right: ").concat(this.config.position.horizontal === 'right' ? '20px' : 'auto', ";\n left: ").concat(this.config.position.horizontal === 'left' ? '20px' : 'auto', ";\n bottom: ").concat(this.config.position.vertical === 'bottom' ? '20px' : 'auto', ";\n top: ").concat(this.config.position.vertical === 'top' ? '20px' : 'auto', ";\n }\n }\n \n /* Mobile override (force mobile positioning) */\n @media (max-width: 768px) {\n #text-chat-widget {\n right: 10px !important;\n bottom: 10px !important;\n left: auto !important;\n top: auto !important;\n transform: none !important;\n }\n }\n \n @media (max-width: 480px) {\n #text-chat-widget {\n right: 8px !important;\n bottom: 8px !important;\n left: auto !important;\n top: auto !important;\n }\n }\n \n #text-chat-button {\n position: relative;\n width: ").concat(buttonSize, "px;\n height: ").concat(buttonSize, "px;\n margin: 0;\n flex-shrink: 0;\n border-radius: ").concat(btn.shape === 'circle' ? '50%' : btn.shape === 'square' ? '0' : '12px', ";\n background: ").concat(btn.backgroundColor || icon.backgroundColor || '#7C3AED', ";\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all ").concat(anim.duration, "s ease;\n box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);\n touch-action: manipulation;\n -webkit-tap-highlight-color: transparent;\n -webkit-touch-callout: none;\n user-select: none;\n min-width: 44px;\n min-height: 44px;\n z-index: 1;\n }\n \n @media (max-width: 768px) {\n #text-chat-widget {\n right: 10px !important;\n bottom: 10px !important;\n left: auto !important;\n top: auto !important;\n transform: none !important;\n }\n \n #text-chat-button-container {\n width: 56px !important;\n height: 56px !important;\n }\n \n #text-chat-button {\n width: 56px !important;\n height: 56px !important;\n min-width: 56px !important;\n min-height: 56px !important;\n max-width: 56px !important;\n max-height: 56px !important;\n }\n \n #text-chat-panel {\n position: fixed !important;\n left: 10px !important;\n right: 10px !important;\n bottom: 92px !important; /* 56px button + 20px gap + 16px footer */\n top: 60px !important; /* Add top spacing */\n width: auto !important;\n max-width: none !important;\n height: auto !important; /* Change from max-height to auto */\n max-height: none !important; /* Remove max-height */\n transform: none !important;\n margin: 0 !important;\n }\n \n #text-chat-panel .widget-header {\n padding: 10px 14px;\n min-height: 56px;\n }\n \n #text-chat-panel .header-title {\n font-size: 15px;\n }\n \n #text-chat-panel .header-icon {\n width: 40px;\n height: 40px;\n min-width: 40px;\n min-height: 40px;\n }\n \n #text-chat-input {\n font-size: 16px !important; /* Prevents iOS zoom on focus */\n padding: 12px 16px !important;\n min-height: 48px !important;\n }\n \n #text-chat-send {\n min-width: 48px !important;\n min-height: 48px !important;\n width: 48px !important;\n height: 48px !important;\n }\n \n .landing-screen {\n padding: 16px;\n }\n \n .landing-logo {\n font-size: 40px;\n }\n \n .landing-title {\n font-size: 18px;\n margin-bottom: 16px;\n }\n \n .mode-selection {\n flex-direction: column;\n gap: 12px;\n align-items: center;\n }\n \n .mode-card {\n max-width: 100%;\n width: 100%;\n padding: 16px;\n }\n \n .mode-card-icon {\n width: 50px;\n height: 50px;\n font-size: 28px;\n }\n \n .mode-card-title {\n font-size: 14px;\n }\n }\n \n @media (max-width: 480px) {\n #text-chat-widget {\n right: 8px !important;\n bottom: 8px !important;\n left: auto !important;\n top: auto !important;\n }\n \n #text-chat-button-container {\n width: 54px !important;\n height: 54px !important;\n }\n \n #text-chat-button {\n width: 54px !important;\n height: 54px !important;\n min-width: 54px !important;\n min-height: 54px !important;\n }\n \n #text-chat-panel {\n left: 8px !important;\n right: 8px !important;\n bottom: 86px !important; /* 54px button + 20px gap + 12px footer */\n top: 50px !important; /* Add top spacing for very small screens */\n height: auto !important;\n max-height: none !important;\n }\n \n #text-chat-panel .widget-header {\n padding: 8px 12px;\n min-height: 52px;\n }\n \n #text-chat-panel .header-title {\n font-size: 14px;\n }\n \n .landing-logo {\n font-size: 36px;\n }\n \n .landing-title {\n font-size: 16px;\n }\n }\n \n ").concat(anim.enableHover ? "\n #text-chat-button:hover {\n ".concat(btn.hoverColor ? "background: ".concat(btn.hoverColor, ";") : '', "\n transform: scale(1.05);\n box-shadow: 0 8px 20px rgba(102, 126, 234, 0.5);\n }\n ") : '', "\n \n /* Prompt Animation Keyframes */\n @keyframes widget-shimmer {\n 0% { transform: translateX(-100%); }\n 100% { transform: translateX(200%); }\n }\n \n @keyframes widget-ripple {\n 0% { transform: scale(1); opacity: 0.6; }\n 100% { transform: scale(2.5); opacity: 0; }\n }\n \n @keyframes widget-float {\n 0%, 100% { transform: translateX(-50%) translateY(0); }\n 50% { transform: translateX(-50%) translateY(-8px); }\n }\n \n @keyframes widget-bounce {\n 0%, 100% { transform: translateX(-50%) translateY(0); }\n 50% { transform: translateX(-50%) translateY(-10px); }\n }\n \n @keyframes widget-pulse-ring {\n 0% { transform: scale(1); opacity: 0.4; }\n 100% { transform: scale(1.8); opacity: 0; }\n }\n \n /* Prompt Bubble Container */\n #text-chat-button-container {\n position: fixed;\n ").concat(this.config.position.vertical === 'bottom' ? "bottom: ".concat(((_this$config$position = this.config.position.offset) === null || _this$config$position === void 0 ? void 0 : _this$config$position.y) || 20, "px;") : "top: ".concat(((_this$config$position2 = this.config.position.offset) === null || _this$config$position2 === void 0 ? void 0 : _this$config$position2.y) || 20, "px;"), "\n ").concat(this.config.position.horizontal === 'right' ? "right: ".concat(((_this$config$position3 = this.config.position.offset) === null || _this$config$position3 === void 0 ? void 0 : _this$config$position3.x) || 20, "px;") : "left: ".concat(((_this$config$position4 = this.config.position.offset) === null || _this$config$position4 === void 0 ? void 0 : _this$config$position4.x) || 20, "px;"), "\n width: ").concat(buttonSize, "px;\n height: ").concat(buttonSize, "px;\n z-index: 10001;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n \n @media (max-width: 768px) {\n #text-chat-button-container {\n right: 10px !important;\n bottom: 10px !important;\n left: auto !important;\n top: auto !important;\n }\n }\n \n @media (max-width: 480px) {\n #text-chat-button-container {\n right: 8px !important;\n bottom: 8px !important;\n left: auto !important;\n top: auto !important;\n }\n }\n \n /* Prompt Bubble Styles */\n .prompt-bubble {\n position: absolute;\n z-index: 10002;\n pointer-events: none;\n white-space: nowrap;\n }\n \n .prompt-bubble.top {\n bottom: calc(100% + 18px);\n left: 50%;\n transform: translateX(-50%);\n }\n \n .prompt-bubble.left {\n right: calc(100% + 12px);\n top: 50%;\n transform: translateY(-50%);\n }\n \n .prompt-bubble.right {\n left: calc(100% + 12px);\n top: 50%;\n transform: translateY(-50%);\n }\n \n /* Ensure animations preserve horizontal centering for top position */\n .prompt-bubble.top.animation-bounce {\n animation: widget-bounce 1s ease-in-out infinite;\n transform: translateX(-50%); /* Keep centering */\n }\n \n .prompt-bubble.top.animation-float {\n animation: widget-float 2s ease-in-out infinite;\n transform: translateX(-50%); /* Keep centering */\n }\n \n .prompt-bubble.top.animation-pulse {\n animation: pulse 2s ease-in-out infinite;\n transform: translateX(-50%); /* Keep centering */\n }\n \n .prompt-bubble-content {\n position: relative;\n padding: 8px 16px;\n border-radius: 20px;\n font-weight: 500;\n font-size: 14px;\n box-shadow: 0 4px 15px rgba(124, 58, 237, 0.3);\n overflow: hidden;\n }\n \n .prompt-bubble-shimmer {\n position: absolute;\n inset: 0;\n background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.25), transparent);\n animation: widget-shimmer 2s infinite;\n }\n \n .prompt-bubble.animation-bounce {\n animation: widget-bounce 1s ease-in-out infinite;\n }\n \n .prompt-bubble.animation-pulse {\n animation: pulse 2s ease-in-out infinite;\n }\n \n .prompt-bubble.animation-float {\n animation: widget-float 2s ease-in-out infinite;\n }\n \n /* Ensure top-positioned bubbles maintain horizontal centering during animations */\n .prompt-bubble.top.animation-bounce,\n .prompt-bubble.top.animation-float,\n .prompt-bubble.top.animation-pulse {\n /* Animation keyframes already include translateX(-50%) for centering */\n }\n \n /* Prompt Bubble Arrow */\n .prompt-bubble-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border: 8px solid transparent;\n }\n \n .prompt-bubble.top .prompt-bubble-arrow {\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-top-color: var(--prompt-bubble-bg-color, #7c3aed);\n border-bottom: none;\n margin-left: 0;\n }\n \n .prompt-bubble.left .prompt-bubble-arrow {\n left: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-left-color: var(--prompt-bubble-bg-color, #7c3aed);\n border-right: none;\n }\n \n .prompt-bubble.right .prompt-bubble-arrow {\n right: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-right-color: var(--prompt-bubble-bg-color, #7c3aed);\n border-left: none;\n }\n \n /* Pulse Rings */\n .prompt-pulse-rings {\n position: absolute;\n inset: 0;\n border-radius: 50%;\n pointer-events: none;\n }\n \n .prompt-pulse-ring {\n position: absolute;\n inset: 0;\n border-radius: 50%;\n animation: widget-pulse-ring 2s ease-out infinite;\n }\n \n .prompt-pulse-ring:nth-child(2) {\n animation-delay: 0.5s;\n }\n \n /* Mobile adjustments for prompt bubble */\n @media (max-width: 768px) {\n .prompt-bubble-content {\n font-size: 12px;\n padding: 6px 12px;\n }\n \n .prompt-bubble.top {\n bottom: calc(100% + 14px);\n }\n \n .prompt-bubble.left,\n .prompt-bubble.right {\n display: none; /* Hide side prompts on mobile */\n }\n }\n \n #text-chat-panel {\n display: none").concat(important, ";\n position: fixed;\n bottom: calc(").concat(buttonSize, "px + 20px + 20px); /* Button + gap + reduced footer offset */\n ").concat(this.config.position.horizontal === 'right' ? 'right: 20px;' : 'left: 20px;', "\n width: ").concat(panel.width, "px;\n max-width: calc(100vw - 40px);\n height: ").concat(panel.height, "px;\n max-height: calc(100vh - ").concat(buttonSize, "px - 40px - 20px); /* Account for footer height */\n background: transparent;\n border-radius: ").concat(panel.borderRadius, "px;\n border: none;\n flex-direction: column;\n overflow: hidden;\n ").concat(panel.backdropFilter ? "backdrop-filter: ".concat(panel.backdropFilter, ";") : '', "\n ").concat(anim.enableSlide ? "transition: all ".concat(anim.duration, "s ease;") : '', "\n box-sizing: border-box;\n }\n \n #text-chat-panel.open {\n display: flex").concat(important, ";\n ").concat(anim.enableSlide ? 'transform: translateY(0); opacity: 1;' : '', "\n }\n\n /* Shell for gradient border/background */\n .widget-shell { width: 100%; height: 100%; padding: 0; border-radius: ").concat(panel.borderRadius, "px; background: transparent; box-shadow: 0 20px 60px rgba(0,0,0,0.15); overflow: hidden; display: flex; flex-direction: column; box-sizing: border-box; }\n .panel-inner { width: 100%; height: 100%; background: #ffffff; border-radius: ").concat(panel.borderRadius, "px; border: ").concat(panel.border, "; overflow: hidden; display:flex; flex-direction: column; padding: 0; box-sizing: border-box; max-width: 100%; }\n\n /* New structure styles matching provided design */\n #text-chat-panel .widget-container {\n width: 100%; height: 100%; background: #FFFFFF; overflow: visible; display: flex; flex-direction: column; border-radius: ").concat(panel.borderRadius, "px;\n container-type: size;\n }\n \n /* Ensure content areas can scroll when height is constrained */\n #text-chat-panel .widget-container > .landing-screen,\n #text-chat-panel .widget-container > .voice-interface,\n #text-chat-panel .widget-container > .text-interface {\n flex: 1;\n overflow-y: auto;\n overflow-x: visible; /* Change from hidden to visible */\n }\n \n /* Header should not scroll */\n #text-chat-panel .widget-header {\n padding: 14px 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-top-left-radius: ").concat(panel.borderRadius, "px;\n border-top-right-radius: ").concat(panel.borderRadius, "px;\n flex-shrink: 0;\n box-sizing: border-box;\n position: relative;\n overflow: hidden;\n background: ").concat(header.backgroundColor || '#7C3AED').concat(important, ";\n color: ").concat(header.textColor || '#FFFFFF').concat(important, ";\n }\n \n #text-chat-panel .widget-header::before {\n content: '';\n position: absolute;\n top: -50%;\n right: -20%;\n width: 180px;\n height: 180px;\n background: radial-gradient(circle, rgba(255,255,255,0.08) 0%, transparent 70%);\n pointer-events: none;\n }\n \n #text-chat-panel .widget-header > div:first-child {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n position: relative;\n z-index: 1;\n }\n \n #text-chat-panel .header-title { font-size: 15px; font-weight: 600; margin: 0; }\n #text-chat-panel .header-status { display: flex; align-items: center; gap: 5px; font-size: 12px; margin: 0; }\n #text-chat-panel .status-dot { width: 6px; height: 6px; border-radius: 50%; animation: pulse 2s ease-in-out infinite; }\n /* Online indicator customization - inline styles take precedence */\n @keyframes pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.15); opacity: 0.8; } }\n /* Header icon buttons */\n .header-icon {\n background: rgba(255, 255, 255, 0.1);\n border: none;\n color: white;\n width: 34px;\n height: 34px;\n min-width: 34px;\n min-height: 34px;\n border-radius: 10px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.2s;\n flex-shrink: 0;\n font-size: 16px;\n padding: 0;\n box-sizing: border-box;\n position: relative;\n z-index: 1;\n }\n \n .header-icon:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n \n .header-icon svg {\n pointer-events: none;\n stroke: white;\n fill: none;\n }\n \n .back-btn.visible {\n display: flex !important;\n }\n\n ").concat(showLanding && this.landingScreen ? this.landingScreen.generateCSS() : '', "\n\n ").concat(showVoice ? this.voiceInterface.generateCSS() : '', "\n ").concat(showText ? this.textInterface.generateCSS() : '', "\n \n /* Footer Branding */\n .widget-footer {\n box-sizing: border-box;\n }\n \n .footer-brand-link {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n \n .footer-brand-link:hover {\n opacity: 0.9;\n }\n \n @media (max-width: 768px) {\n .widget-footer {\n height: 32px;\n }\n .widget-footer span {\n font-size: 10px;\n }\n .widget-footer span:last-child {\n font-size: 8px;\n }\n }\n \n #text-chat-send-hint {\n text-align: center;\n line-height: 1.4;\n }\n \n .agent-thinking {\n font-style: italic;\n color: #6B7280;\n }\n ");
|
|
22123
|
+
return "\n /* MOBILE FIRST - Default styles for all devices */\n #text-chat-widget {\n position: fixed !important;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n /* Mobile defaults */\n right: 10px;\n bottom: 10px;\n left: auto;\n top: auto;\n }\n \n /* Desktop positioning (only on larger screens) */\n @media (min-width: 769px) {\n #text-chat-widget {\n ".concat(positionStyles, "\n right: ").concat(this.config.position.horizontal === 'right' ? '20px' : 'auto', ";\n left: ").concat(this.config.position.horizontal === 'left' ? '20px' : 'auto', ";\n bottom: ").concat(this.config.position.vertical === 'bottom' ? '20px' : 'auto', ";\n top: ").concat(this.config.position.vertical === 'top' ? '20px' : 'auto', ";\n }\n }\n \n /* Mobile override (force mobile positioning) */\n @media (max-width: 768px) {\n #text-chat-widget {\n right: 10px !important;\n bottom: 10px !important;\n left: auto !important;\n top: auto !important;\n transform: none !important;\n }\n }\n \n @media (max-width: 480px) {\n #text-chat-widget {\n right: 8px !important;\n bottom: 8px !important;\n left: auto !important;\n top: auto !important;\n }\n }\n \n #text-chat-button {\n position: relative;\n width: ").concat(buttonSize, "px;\n height: ").concat(buttonSize, "px;\n margin: 0;\n flex-shrink: 0;\n border-radius: ").concat(btn.shape === 'circle' ? '50%' : btn.shape === 'square' ? '0' : '12px', ";\n background: ").concat(btn.backgroundColor || icon.backgroundColor || '#7C3AED', ";\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all ").concat(anim.duration, "s ease;\n box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);\n touch-action: manipulation;\n -webkit-tap-highlight-color: transparent;\n -webkit-touch-callout: none;\n user-select: none;\n min-width: 44px;\n min-height: 44px;\n z-index: 1;\n }\n \n @media (max-width: 768px) {\n #text-chat-widget {\n right: 10px !important;\n bottom: 10px !important;\n left: auto !important;\n top: auto !important;\n transform: none !important;\n }\n \n #text-chat-button-container {\n width: 56px !important;\n height: 56px !important;\n }\n \n #text-chat-button {\n width: 56px !important;\n height: 56px !important;\n min-width: 56px !important;\n min-height: 56px !important;\n max-width: 56px !important;\n max-height: 56px !important;\n }\n \n #text-chat-panel {\n position: fixed !important;\n left: 10px !important;\n right: 10px !important;\n bottom: 92px !important; /* 56px button + 20px gap + 16px footer */\n top: 60px !important; /* Add top spacing */\n width: auto !important;\n max-width: none !important;\n height: auto !important; /* Change from max-height to auto */\n max-height: none !important; /* Remove max-height */\n transform: none !important;\n margin: 0 !important;\n }\n \n #text-chat-panel .widget-header {\n padding: 10px 14px;\n min-height: 56px;\n }\n \n #text-chat-panel .header-title {\n font-size: 15px;\n }\n \n #text-chat-panel .header-icon {\n width: 40px;\n height: 40px;\n min-width: 40px;\n min-height: 40px;\n }\n \n #text-chat-input {\n font-size: 16px !important; /* Prevents iOS zoom on focus */\n padding: 12px 16px !important;\n min-height: 48px !important;\n }\n \n #text-chat-send {\n min-width: 48px !important;\n min-height: 48px !important;\n width: 48px !important;\n height: 48px !important;\n }\n \n .landing-screen {\n padding: 16px;\n }\n \n .landing-logo {\n font-size: 40px;\n }\n \n .landing-title {\n font-size: 18px;\n margin-bottom: 16px;\n }\n \n .mode-selection {\n flex-direction: column;\n gap: 12px;\n align-items: center;\n }\n \n .mode-card {\n max-width: 100%;\n width: 100%;\n padding: 16px;\n }\n \n .mode-card-icon {\n width: 50px;\n height: 50px;\n font-size: 28px;\n }\n \n .mode-card-title {\n font-size: 14px;\n }\n }\n \n @media (max-width: 480px) {\n #text-chat-widget {\n right: 8px !important;\n bottom: 8px !important;\n left: auto !important;\n top: auto !important;\n }\n \n #text-chat-button-container {\n width: 54px !important;\n height: 54px !important;\n }\n \n #text-chat-button {\n width: 54px !important;\n height: 54px !important;\n min-width: 54px !important;\n min-height: 54px !important;\n }\n \n #text-chat-panel {\n left: 8px !important;\n right: 8px !important;\n bottom: 86px !important; /* 54px button + 20px gap + 12px footer */\n top: 50px !important; /* Add top spacing for very small screens */\n height: auto !important;\n max-height: none !important;\n }\n \n #text-chat-panel .widget-header {\n padding: 8px 12px;\n min-height: 52px;\n }\n \n #text-chat-panel .header-title {\n font-size: 14px;\n }\n \n .landing-logo {\n font-size: 36px;\n }\n \n .landing-title {\n font-size: 16px;\n }\n }\n \n ").concat(anim.enableHover ? "\n #text-chat-button:hover {\n ".concat(btn.hoverColor ? "background: ".concat(btn.hoverColor, ";") : '', "\n transform: scale(1.05);\n box-shadow: 0 8px 20px rgba(102, 126, 234, 0.5);\n }\n ") : '', "\n \n /* Prompt Animation Keyframes */\n @keyframes widget-shimmer {\n 0% { transform: translateX(-100%); }\n 100% { transform: translateX(200%); }\n }\n \n @keyframes widget-ripple {\n 0% { transform: scale(1); opacity: 0.6; }\n 100% { transform: scale(2.5); opacity: 0; }\n }\n \n @keyframes widget-float {\n 0%, 100% { transform: translateX(-50%) translateY(0); }\n 50% { transform: translateX(-50%) translateY(-8px); }\n }\n \n @keyframes widget-bounce {\n 0%, 100% { transform: translateX(-50%) translateY(0); }\n 50% { transform: translateX(-50%) translateY(-10px); }\n }\n \n @keyframes widget-pulse-ring {\n 0% { transform: scale(1); opacity: 0.4; }\n 100% { transform: scale(1.8); opacity: 0; }\n }\n \n /* Prompt Bubble Container */\n #text-chat-button-container {\n position: fixed;\n ").concat(this.config.position.vertical === 'bottom' ? "bottom: ".concat(((_this$config$position = this.config.position.offset) === null || _this$config$position === void 0 ? void 0 : _this$config$position.y) || 20, "px;") : "top: ".concat(((_this$config$position2 = this.config.position.offset) === null || _this$config$position2 === void 0 ? void 0 : _this$config$position2.y) || 20, "px;"), "\n ").concat(this.config.position.horizontal === 'right' ? "right: ".concat(((_this$config$position3 = this.config.position.offset) === null || _this$config$position3 === void 0 ? void 0 : _this$config$position3.x) || 20, "px;") : "left: ".concat(((_this$config$position4 = this.config.position.offset) === null || _this$config$position4 === void 0 ? void 0 : _this$config$position4.x) || 20, "px;"), "\n width: ").concat(buttonSize, "px;\n height: ").concat(buttonSize, "px;\n z-index: 10001;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n \n @media (max-width: 768px) {\n #text-chat-button-container {\n right: 10px !important;\n bottom: 10px !important;\n left: auto !important;\n top: auto !important;\n }\n }\n \n @media (max-width: 480px) {\n #text-chat-button-container {\n right: 8px !important;\n bottom: 8px !important;\n left: auto !important;\n top: auto !important;\n }\n }\n \n /* Prompt Bubble Styles */\n .prompt-bubble {\n position: absolute;\n z-index: 10002;\n pointer-events: none;\n white-space: nowrap;\n }\n \n .prompt-bubble.top {\n bottom: calc(100% + 18px);\n left: 50%;\n transform: translateX(-50%);\n }\n \n .prompt-bubble.left {\n right: calc(100% + 12px);\n top: 50%;\n transform: translateY(-50%);\n }\n \n .prompt-bubble.right {\n left: calc(100% + 12px);\n top: 50%;\n transform: translateY(-50%);\n }\n \n /* Ensure animations preserve horizontal centering for top position */\n .prompt-bubble.top.animation-bounce {\n animation: widget-bounce 1s ease-in-out infinite;\n transform: translateX(-50%); /* Keep centering */\n }\n \n .prompt-bubble.top.animation-float {\n animation: widget-float 2s ease-in-out infinite;\n transform: translateX(-50%); /* Keep centering */\n }\n \n .prompt-bubble.top.animation-pulse {\n animation: pulse 2s ease-in-out infinite;\n transform: translateX(-50%); /* Keep centering */\n }\n \n .prompt-bubble-content {\n position: relative;\n padding: 8px 16px;\n border-radius: 20px;\n font-weight: 500;\n font-size: 14px;\n box-shadow: 0 4px 15px rgba(124, 58, 237, 0.3);\n overflow: hidden;\n }\n \n .prompt-bubble-shimmer {\n position: absolute;\n inset: 0;\n background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.25), transparent);\n animation: widget-shimmer 2s infinite;\n }\n \n .prompt-bubble.animation-bounce {\n animation: widget-bounce 1s ease-in-out infinite;\n }\n \n .prompt-bubble.animation-pulse {\n animation: pulse 2s ease-in-out infinite;\n }\n \n .prompt-bubble.animation-float {\n animation: widget-float 2s ease-in-out infinite;\n }\n \n /* Ensure top-positioned bubbles maintain horizontal centering during animations */\n .prompt-bubble.top.animation-bounce,\n .prompt-bubble.top.animation-float,\n .prompt-bubble.top.animation-pulse {\n /* Animation keyframes already include translateX(-50%) for centering */\n }\n \n /* Prompt Bubble Arrow */\n .prompt-bubble-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border: 8px solid transparent;\n }\n \n .prompt-bubble.top .prompt-bubble-arrow {\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-top-color: var(--prompt-bubble-bg-color, #7c3aed);\n border-bottom: none;\n margin-left: 0;\n }\n \n .prompt-bubble.left .prompt-bubble-arrow {\n left: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-left-color: var(--prompt-bubble-bg-color, #7c3aed);\n border-right: none;\n }\n \n .prompt-bubble.right .prompt-bubble-arrow {\n right: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-right-color: var(--prompt-bubble-bg-color, #7c3aed);\n border-left: none;\n }\n \n /* Pulse Rings */\n .prompt-pulse-rings {\n position: absolute;\n inset: 0;\n border-radius: 50%;\n pointer-events: none;\n }\n \n .prompt-pulse-ring {\n position: absolute;\n inset: 0;\n border-radius: 50%;\n animation: widget-pulse-ring 2s ease-out infinite;\n }\n \n .prompt-pulse-ring:nth-child(2) {\n animation-delay: 0.5s;\n }\n \n /* Mobile adjustments for prompt bubble */\n @media (max-width: 768px) {\n .prompt-bubble-content {\n font-size: 12px;\n padding: 6px 12px;\n }\n \n .prompt-bubble.top {\n bottom: calc(100% + 14px);\n }\n \n .prompt-bubble.left,\n .prompt-bubble.right {\n display: none; /* Hide side prompts on mobile */\n }\n }\n \n #text-chat-panel {\n display: none").concat(important, ";\n position: fixed;\n bottom: calc(").concat(buttonSize, "px + 20px + 20px); /* Button + gap + reduced footer offset */\n ").concat(this.config.position.horizontal === 'right' ? 'right: 20px;' : 'left: 20px;', "\n width: ").concat(panel.width, "px;\n max-width: calc(100vw - 40px);\n height: ").concat(panel.height, "px;\n max-height: calc(100vh - ").concat(buttonSize, "px - 40px - 20px); /* Account for footer height */\n background: transparent;\n border-radius: ").concat(panel.borderRadius, "px;\n border: none;\n flex-direction: column;\n overflow: hidden;\n ").concat(panel.backdropFilter ? "backdrop-filter: ".concat(panel.backdropFilter, ";") : '', "\n ").concat(anim.enableSlide ? "transition: all ".concat(anim.duration, "s ease;") : '', "\n box-sizing: border-box;\n }\n \n #text-chat-panel.open {\n display: flex").concat(important, ";\n ").concat(anim.enableSlide ? 'transform: translateY(0); opacity: 1;' : '', "\n }\n\n /* Shell for gradient border/background */\n .widget-shell { width: 100%; height: 100%; padding: 0; border-radius: ").concat(panel.borderRadius, "px; background: transparent; box-shadow: 0 20px 60px rgba(0,0,0,0.15); overflow: hidden; display: flex; flex-direction: column; box-sizing: border-box; }\n .panel-inner { width: 100%; height: 100%; background: #ffffff; border-radius: ").concat(panel.borderRadius, "px; border: ").concat(panel.border, "; overflow: hidden; display:flex; flex-direction: column; padding: 0; box-sizing: border-box; max-width: 100%; }\n\n /* New structure styles matching provided design */\n #text-chat-panel .widget-container {\n width: 100%; height: 100%; background: #FFFFFF; overflow: visible; display: flex; flex-direction: column; border-radius: ").concat(panel.borderRadius, "px;\n container-type: size;\n }\n \n /* Ensure content areas can scroll when height is constrained */\n #text-chat-panel .widget-container > .landing-screen,\n #text-chat-panel .widget-container > .voice-interface,\n #text-chat-panel .widget-container > .text-interface {\n flex: 1;\n overflow-y: auto;\n overflow-x: visible; /* Change from hidden to visible */\n }\n \n /* Header should not scroll */\n #text-chat-panel .widget-header {\n padding: 14px 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-top-left-radius: ").concat(panel.borderRadius, "px;\n border-top-right-radius: ").concat(panel.borderRadius, "px;\n flex-shrink: 0;\n box-sizing: border-box;\n position: relative;\n overflow: hidden;\n background: ").concat(header.backgroundColor || '#7C3AED').concat(important, ";\n color: ").concat(header.textColor || '#FFFFFF').concat(important, ";\n }\n \n #text-chat-panel .widget-header::before {\n content: '';\n position: absolute;\n top: -50%;\n right: -20%;\n width: 180px;\n height: 180px;\n background: radial-gradient(circle, rgba(255,255,255,0.08) 0%, transparent 70%);\n pointer-events: none;\n }\n \n #text-chat-panel .widget-header > div:first-child {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n position: relative;\n z-index: 1;\n }\n \n #text-chat-panel .header-title { font-size: 15px; font-weight: 600; margin: 0; }\n #text-chat-panel .header-status { display: flex; align-items: center; gap: 5px; font-size: 12px; margin: 0; }\n #text-chat-panel .status-dot { width: 6px; height: 6px; border-radius: 50%; animation: pulse 2s ease-in-out infinite; }\n /* Online indicator customization - inline styles take precedence */\n @keyframes pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.15); opacity: 0.8; } }\n /* Header icon buttons */\n .header-icon {\n background: rgba(255, 255, 255, 0.1);\n border: none;\n color: white;\n width: 34px;\n height: 34px;\n min-width: 34px;\n min-height: 34px;\n border-radius: 10px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.2s;\n flex-shrink: 0;\n font-size: 16px;\n padding: 0;\n box-sizing: border-box;\n position: relative;\n z-index: 1;\n }\n \n .header-icon:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n \n .header-icon svg {\n pointer-events: none;\n stroke: white;\n fill: none;\n }\n \n .back-btn.visible {\n display: flex !important;\n }\n\n ").concat(showLanding && this.landingScreen ? this.landingScreen.generateCSS() : '', "\n\n ").concat(showVoice ? this.voiceInterface.generateCSS() : '', "\n ").concat(showText ? this.textInterface.generateCSS() : '', "\n \n /* Footer Branding */\n .widget-footer {\n box-sizing: border-box;\n }\n \n .footer-brand-link {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n \n .footer-brand-link:hover {\n opacity: 0.9;\n }\n \n @media (max-width: 768px) {\n .widget-footer {\n height: 32px;\n }\n .widget-footer span {\n font-size: 10px;\n }\n .widget-footer span:last-child {\n font-size: 8px;\n }\n }\n \n #text-chat-send-hint {\n text-align: center;\n line-height: 1.4;\n }\n \n .agent-thinking {\n font-style: italic;\n color: #6B7280;\n }\n\n /* ========================================\n MOBILE PILL BUTTON & LANDING OVERLAY\n Hidden on desktop, shown on mobile only\n ======================================== */\n .ttp-mobile-fab {\n display: none;\n }\n\n .ttp-mobile-landing {\n display: none;\n }\n\n @keyframes ttpWaveAnimation {\n 0%, 100% { transform: scaleY(0.4); }\n 50% { transform: scaleY(1); }\n }\n\n @keyframes ttpPulseAnimation {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n\n @media (max-width: 768px) {\n /* Hide desktop circle button on mobile */\n #text-chat-button {\n display: none !important;\n }\n\n /* Re-flow the container for pill shape */\n #text-chat-button-container {\n width: auto !important;\n height: auto !important;\n min-width: 0 !important;\n min-height: 0 !important;\n max-width: none !important;\n max-height: none !important;\n }\n\n /* Show mobile pill button */\n .ttp-mobile-fab {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 16px 10px 12px;\n background: linear-gradient(135deg, #581c87, ").concat(header.backgroundColor || '#7C3AED', ");\n border: none;\n border-radius: 24px;\n cursor: pointer;\n box-shadow: 0 8px 24px rgba(88, 28, 135, 0.4);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n z-index: 1;\n font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;\n touch-action: manipulation;\n -webkit-tap-highlight-color: transparent;\n }\n\n .ttp-mobile-fab:hover {\n transform: translateY(-3px);\n box-shadow: 0 12px 32px rgba(88, 28, 135, 0.5);\n }\n\n .ttp-mobile-fab__icon-wrap {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.15);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .ttp-mobile-fab__waveform {\n display: flex;\n align-items: center;\n gap: 2px;\n height: 16px;\n }\n\n .ttp-mobile-fab__waveform .bar {\n width: 2px;\n background: #fff;\n border-radius: 1px;\n animation: ttpWaveAnimation 0.8s ease-in-out infinite;\n }\n\n .ttp-mobile-fab__waveform .bar:nth-child(1) { height: 5px; animation-delay: 0s; }\n .ttp-mobile-fab__waveform .bar:nth-child(2) { height: 10px; animation-delay: 0.1s; }\n .ttp-mobile-fab__waveform .bar:nth-child(3) { height: 16px; animation-delay: 0.2s; }\n .ttp-mobile-fab__waveform .bar:nth-child(4) { height: 8px; animation-delay: 0.3s; }\n .ttp-mobile-fab__waveform .bar:nth-child(5) { height: 12px; animation-delay: 0.4s; }\n\n .ttp-mobile-fab__label-wrap {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 1px;\n }\n\n .ttp-mobile-fab__label {\n color: #fff;\n font-size: 14px;\n font-weight: 600;\n line-height: 1.2;\n }\n\n .ttp-mobile-fab__status {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: rgba(255, 255, 255, 0.7);\n line-height: 1.2;\n }\n\n .ttp-mobile-fab__dot {\n width: 6px;\n height: 6px;\n background: ").concat(header.onlineIndicatorDotColor || '#10b981', ";\n border-radius: 50%;\n box-shadow: 0 0 6px rgba(16, 185, 129, 0.6);\n }\n\n /* ---- Mobile Landing Overlay ---- */\n .ttp-mobile-landing.active {\n display: block;\n position: fixed;\n bottom: 16px;\n left: 12px;\n right: 12px;\n background: linear-gradient(135deg, #581c87 0%, ").concat(header.backgroundColor || '#7C3AED', " 100%);\n border-radius: 20px;\n overflow: hidden;\n box-shadow:\n 0 10px 40px rgba(88, 28, 135, 0.4),\n 0 0 0 1px rgba(255, 255, 255, 0.1) inset;\n z-index: 10002;\n font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;\n }\n\n .ttp-mobile-landing::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 1px;\n background: linear-gradient(90deg,\n transparent 0%,\n rgba(255, 255, 255, 0.3) 50%,\n transparent 100%);\n }\n\n .ttp-mobile-landing__header {\n padding: 14px 16px;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .ttp-mobile-landing__avatar {\n width: 44px;\n height: 44px;\n border-radius: 12px;\n background: rgba(255, 255, 255, 0.15);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .ttp-mobile-landing__waveform {\n display: flex;\n align-items: center;\n gap: 3px;\n height: 20px;\n }\n\n .ttp-mobile-landing__waveform .bar {\n width: 3px;\n background: rgba(255, 255, 255, 0.9);\n border-radius: 2px;\n animation: ttpWaveAnimation 0.8s ease-in-out infinite;\n }\n\n .ttp-mobile-landing__waveform .bar:nth-child(1) { height: 6px; animation-delay: 0s; }\n .ttp-mobile-landing__waveform .bar:nth-child(2) { height: 12px; animation-delay: 0.1s; }\n .ttp-mobile-landing__waveform .bar:nth-child(3) { height: 20px; animation-delay: 0.2s; }\n .ttp-mobile-landing__waveform .bar:nth-child(4) { height: 10px; animation-delay: 0.3s; }\n .ttp-mobile-landing__waveform .bar:nth-child(5) { height: 16px; animation-delay: 0.4s; }\n\n .ttp-mobile-landing__info {\n flex: 1;\n min-width: 0;\n }\n\n .ttp-mobile-landing__name {\n color: #fff;\n font-size: 15px;\n font-weight: 600;\n margin-bottom: 2px;\n }\n\n .ttp-mobile-landing__status {\n color: rgba(255, 255, 255, 0.7);\n font-size: 12px;\n display: flex;\n align-items: center;\n gap: 5px;\n }\n\n .ttp-mobile-landing__dot {\n width: 6px;\n height: 6px;\n background: ").concat(header.onlineIndicatorDotColor || '#10b981', ";\n border-radius: 50%;\n animation: ttpPulseAnimation 2s ease-in-out infinite;\n }\n\n .ttp-mobile-landing__close {\n width: 32px;\n height: 32px;\n border-radius: 10px;\n background: rgba(255, 255, 255, 0.1);\n border: none;\n color: rgba(255, 255, 255, 0.7);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s;\n flex-shrink: 0;\n }\n\n .ttp-mobile-landing__close:hover {\n background: rgba(255, 255, 255, 0.2);\n color: #fff;\n }\n\n .ttp-mobile-landing__error {\n margin: 0 14px 10px;\n padding: 10px 12px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: 10px;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n color: #b91c1c;\n font-size: 13px;\n line-height: 1.4;\n }\n .ttp-mobile-landing__error svg {\n flex-shrink: 0;\n margin-top: 1px;\n stroke: #dc2626;\n }\n\n .ttp-mobile-landing__actions {\n padding: 0 14px 14px;\n display: flex;\n gap: 10px;\n }\n\n .ttp-mobile-landing__btn {\n flex: 1;\n padding: 14px;\n border-radius: 12px;\n border: none;\n cursor: pointer;\n font-family: inherit;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n touch-action: manipulation;\n -webkit-tap-highlight-color: transparent;\n }\n\n .ttp-mobile-landing__btn svg {\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n }\n\n .ttp-mobile-landing__btn--call {\n background: #fff;\n color: ").concat(header.backgroundColor || '#7C3AED', ";\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n }\n\n .ttp-mobile-landing__btn--call:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);\n }\n\n .ttp-mobile-landing__btn--text {\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border: 1px solid rgba(255, 255, 255, 0.1);\n }\n\n .ttp-mobile-landing__btn--text:hover {\n background: rgba(255, 255, 255, 0.2);\n border-color: rgba(255, 255, 255, 0.2);\n }\n\n .ttp-mobile-landing__footer {\n padding: 10px 16px;\n display: flex;\n justify-content: center;\n border-top: 1px solid rgba(255, 255, 255, 0.08);\n }\n\n .ttp-mobile-landing__powered {\n color: rgba(255, 255, 255, 0.4);\n font-size: 11px;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .ttp-mobile-landing__powered svg {\n width: 10px;\n height: 10px;\n color: #f59e0b;\n }\n\n .ttp-mobile-landing__powered a {\n color: rgba(255, 255, 255, 0.6);\n text-decoration: none;\n }\n\n .ttp-mobile-landing__powered a:hover {\n color: #fff;\n }\n }\n ");
|
|
21980
22124
|
}
|
|
21981
22125
|
}, {
|
|
21982
22126
|
key: "setupWidgetEvents",
|
|
@@ -22047,7 +22191,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22047
22191
|
this.landingScreen.setupEventHandlers({
|
|
22048
22192
|
onSelectVoice: function () {
|
|
22049
22193
|
var _onSelectVoice = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
|
|
22050
|
-
var _this6$voiceInterface4, _this6$voiceInterface8, _this6$shadowRoot, _this6$voiceInterface5, _this6$shadowRoot2, _this6$voiceInterface6, panel, idleState, floatingButton, _this6$voiceInterface7, _this6$voiceInterface9, _this6$voiceInterface1, _this6$config$behavio, _idleState, isDomainError, statusTitle, _this6$voiceInterface0, titleText, domainErrorTitle, _widgetMode, _this6$voiceInterface11, _this6$voiceInterface12, _this6$config$behavio2, _this6$voiceInterface10, _this6$voiceInterface13, _this6$
|
|
22194
|
+
var _this6$voiceInterface4, _this6$voiceInterface8, _this6$shadowRoot, _this6$voiceInterface5, _this6$shadowRoot2, _this6$shadowRoot3, _this6$voiceInterface6, panel, idleState, floatingButton, mobileFab, _this6$voiceInterface7, _this6$voiceInterface9, _this6$voiceInterface1, _this6$config$behavio, _idleState, isDomainError, statusTitle, _this6$voiceInterface0, titleText, domainErrorTitle, _widgetMode, _this6$voiceInterface11, _this6$voiceInterface12, _this6$config$behavio2, _this6$voiceInterface10, _this6$voiceInterface13, _this6$shadowRoot4, _this6$shadowRoot5, existingBar, _floatingButton, _mobileFab, _widgetMode2, _t;
|
|
22051
22195
|
return _regenerator().w(function (_context) {
|
|
22052
22196
|
while (1) switch (_context.p = _context.n) {
|
|
22053
22197
|
case 0:
|
|
@@ -22097,6 +22241,10 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22097
22241
|
if (floatingButton) {
|
|
22098
22242
|
floatingButton.style.display = 'none';
|
|
22099
22243
|
}
|
|
22244
|
+
mobileFab = (_this6$shadowRoot3 = _this6.shadowRoot) === null || _this6$shadowRoot3 === void 0 ? void 0 : _this6$shadowRoot3.querySelector('.ttp-mobile-fab');
|
|
22245
|
+
if (mobileFab) {
|
|
22246
|
+
mobileFab.style.display = 'none';
|
|
22247
|
+
}
|
|
22100
22248
|
// Create minimized bar with connecting state
|
|
22101
22249
|
if (!((_this6$voiceInterface6 = _this6.voiceInterface) !== null && _this6$voiceInterface6 !== void 0 && _this6$voiceInterface6.createMobileMinimizedBar)) {
|
|
22102
22250
|
_context.n = 3;
|
|
@@ -22206,10 +22354,14 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22206
22354
|
_this6.voiceInterface.removeMobileMinimizedBar();
|
|
22207
22355
|
}
|
|
22208
22356
|
// Restore floating button if it was hidden
|
|
22209
|
-
_floatingButton = ((_this6$
|
|
22357
|
+
_floatingButton = ((_this6$shadowRoot4 = _this6.shadowRoot) === null || _this6$shadowRoot4 === void 0 ? void 0 : _this6$shadowRoot4.getElementById('text-chat-button')) || document.getElementById('text-chat-button');
|
|
22210
22358
|
if (_floatingButton) {
|
|
22211
22359
|
_floatingButton.style.display = '';
|
|
22212
22360
|
}
|
|
22361
|
+
_mobileFab = (_this6$shadowRoot5 = _this6.shadowRoot) === null || _this6$shadowRoot5 === void 0 ? void 0 : _this6$shadowRoot5.querySelector('.ttp-mobile-fab');
|
|
22362
|
+
if (_mobileFab) {
|
|
22363
|
+
_mobileFab.style.display = '';
|
|
22364
|
+
}
|
|
22213
22365
|
}
|
|
22214
22366
|
|
|
22215
22367
|
// Show user-friendly error message (unless it's a user cancellation)
|
|
@@ -22302,6 +22454,9 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22302
22454
|
}
|
|
22303
22455
|
}
|
|
22304
22456
|
|
|
22457
|
+
// Mobile floating button & landing overlay
|
|
22458
|
+
this.setupMobileWidgetEvents();
|
|
22459
|
+
|
|
22305
22460
|
// Keyboard navigation
|
|
22306
22461
|
if (this.config.accessibility.keyboardNavigation) {
|
|
22307
22462
|
this.setupKeyboardNavigation();
|
|
@@ -22385,13 +22540,83 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22385
22540
|
// Hide new chat button on voice interface (not applicable)
|
|
22386
22541
|
if (newChatBtn) newChatBtn.style.display = 'none';
|
|
22387
22542
|
}
|
|
22543
|
+
}, {
|
|
22544
|
+
key: "setupMobileWidgetEvents",
|
|
22545
|
+
value: function setupMobileWidgetEvents() {
|
|
22546
|
+
var _this7 = this;
|
|
22547
|
+
if (!this.shadowRoot) return;
|
|
22548
|
+
var mobileFab = this.shadowRoot.querySelector('.ttp-mobile-fab');
|
|
22549
|
+
var mobileLanding = this.shadowRoot.getElementById('ttpMobileLanding');
|
|
22550
|
+
if (!mobileFab || !mobileLanding) return;
|
|
22551
|
+
var closeMobileLanding = function closeMobileLanding() {
|
|
22552
|
+
mobileLanding.classList.remove('active');
|
|
22553
|
+
mobileFab.style.display = '';
|
|
22554
|
+
_this7.isMobileLandingOpen = false;
|
|
22555
|
+
};
|
|
22556
|
+
var openMobileLanding = function openMobileLanding() {
|
|
22557
|
+
if (_this7.config.promptAnimation.hideAfterClick) {
|
|
22558
|
+
_this7.hidePrompt();
|
|
22559
|
+
}
|
|
22560
|
+
// Clear any previous error banner
|
|
22561
|
+
var errorBanner = _this7.shadowRoot.getElementById('ttpMobileLandingError');
|
|
22562
|
+
if (errorBanner) errorBanner.style.display = 'none';
|
|
22563
|
+
mobileFab.style.display = 'none';
|
|
22564
|
+
mobileLanding.classList.add('active');
|
|
22565
|
+
_this7.isMobileLandingOpen = true;
|
|
22566
|
+
};
|
|
22567
|
+
mobileFab.onclick = openMobileLanding;
|
|
22568
|
+
var mobileClose = mobileLanding.querySelector('.ttp-mobile-landing__close');
|
|
22569
|
+
if (mobileClose) {
|
|
22570
|
+
mobileClose.onclick = closeMobileLanding;
|
|
22571
|
+
}
|
|
22572
|
+
var mobileCallBtn = this.shadowRoot.getElementById('ttpMobileCallBtn');
|
|
22573
|
+
if (mobileCallBtn) {
|
|
22574
|
+
mobileCallBtn.onclick = function () {
|
|
22575
|
+
closeMobileLanding();
|
|
22576
|
+
var desktopVoiceCard = _this7.shadowRoot.getElementById('mode-card-voice');
|
|
22577
|
+
if (desktopVoiceCard) {
|
|
22578
|
+
desktopVoiceCard.click();
|
|
22579
|
+
} else {
|
|
22580
|
+
_this7.showVoice();
|
|
22581
|
+
}
|
|
22582
|
+
};
|
|
22583
|
+
}
|
|
22584
|
+
var mobileChatBtn = this.shadowRoot.getElementById('ttpMobileChatBtn');
|
|
22585
|
+
if (mobileChatBtn) {
|
|
22586
|
+
mobileChatBtn.onclick = function () {
|
|
22587
|
+
closeMobileLanding();
|
|
22588
|
+
var desktopTextCard = _this7.shadowRoot.getElementById('mode-card-text');
|
|
22589
|
+
if (desktopTextCard) {
|
|
22590
|
+
desktopTextCard.click();
|
|
22591
|
+
} else {
|
|
22592
|
+
_this7.showText();
|
|
22593
|
+
}
|
|
22594
|
+
};
|
|
22595
|
+
}
|
|
22596
|
+
|
|
22597
|
+
// Close mobile landing on outside click
|
|
22598
|
+
document.addEventListener('click', function (e) {
|
|
22599
|
+
if (!_this7.isMobileLandingOpen) return;
|
|
22600
|
+
var path = e.composedPath();
|
|
22601
|
+
if (!path.includes(mobileLanding) && !path.includes(mobileFab)) {
|
|
22602
|
+
closeMobileLanding();
|
|
22603
|
+
}
|
|
22604
|
+
});
|
|
22605
|
+
|
|
22606
|
+
// Close mobile landing on Escape
|
|
22607
|
+
document.addEventListener('keydown', function (e) {
|
|
22608
|
+
if (e.key === 'Escape' && _this7.isMobileLandingOpen) {
|
|
22609
|
+
closeMobileLanding();
|
|
22610
|
+
}
|
|
22611
|
+
});
|
|
22612
|
+
}
|
|
22388
22613
|
}, {
|
|
22389
22614
|
key: "setupKeyboardNavigation",
|
|
22390
22615
|
value: function setupKeyboardNavigation() {
|
|
22391
|
-
var
|
|
22616
|
+
var _this8 = this;
|
|
22392
22617
|
document.addEventListener('keydown', function (e) {
|
|
22393
|
-
if (e.key === 'Escape' &&
|
|
22394
|
-
|
|
22618
|
+
if (e.key === 'Escape' && _this8.isOpen) {
|
|
22619
|
+
_this8.togglePanel();
|
|
22395
22620
|
}
|
|
22396
22621
|
});
|
|
22397
22622
|
}
|
|
@@ -22402,7 +22627,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22402
22627
|
}, {
|
|
22403
22628
|
key: "setupPromptAnimation",
|
|
22404
22629
|
value: function setupPromptAnimation() {
|
|
22405
|
-
var
|
|
22630
|
+
var _this9 = this;
|
|
22406
22631
|
if (!this.shadowRoot) return;
|
|
22407
22632
|
var promptConfig = this.config.promptAnimation || {};
|
|
22408
22633
|
// Default to disabled if not specified (enabled === true means explicitly enabled)
|
|
@@ -22432,7 +22657,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22432
22657
|
// Auto-hide after configured seconds (only if widget is closed)
|
|
22433
22658
|
if (!this.isOpen && promptConfig.hideAfterSeconds !== null && promptConfig.hideAfterSeconds > 0) {
|
|
22434
22659
|
this.promptAutoHideTimer = setTimeout(function () {
|
|
22435
|
-
|
|
22660
|
+
_this9.hidePrompt();
|
|
22436
22661
|
}, promptConfig.hideAfterSeconds * 1000);
|
|
22437
22662
|
}
|
|
22438
22663
|
|
|
@@ -22444,7 +22669,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22444
22669
|
// Wrap the callback to also hide pulse rings
|
|
22445
22670
|
this.config.onConversationStart = function () {
|
|
22446
22671
|
// Hide pulse rings when call starts
|
|
22447
|
-
var pulseRings =
|
|
22672
|
+
var pulseRings = _this9.shadowRoot.getElementById('prompt-pulse-rings');
|
|
22448
22673
|
if (pulseRings) pulseRings.style.display = 'none';
|
|
22449
22674
|
|
|
22450
22675
|
// Call original callback if it exists
|
|
@@ -22456,7 +22681,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22456
22681
|
// Also listen to recordingStarted event from SDK if available
|
|
22457
22682
|
if (this.voiceInterface.sdk.voiceSDK) {
|
|
22458
22683
|
this.voiceInterface.sdk.voiceSDK.on('recordingStarted', function () {
|
|
22459
|
-
var pulseRings =
|
|
22684
|
+
var pulseRings = _this9.shadowRoot.getElementById('prompt-pulse-rings');
|
|
22460
22685
|
if (pulseRings) pulseRings.style.display = 'none';
|
|
22461
22686
|
});
|
|
22462
22687
|
}
|
|
@@ -22504,7 +22729,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22504
22729
|
}, {
|
|
22505
22730
|
key: "showPrompt",
|
|
22506
22731
|
value: function showPrompt() {
|
|
22507
|
-
var
|
|
22732
|
+
var _this0 = this;
|
|
22508
22733
|
if (!this.shadowRoot) return;
|
|
22509
22734
|
var promptConfig = this.config.promptAnimation || {};
|
|
22510
22735
|
// Default to enabled if not specified
|
|
@@ -22524,8 +22749,8 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22524
22749
|
// Function to actually show the elements
|
|
22525
22750
|
var doShow = function doShow() {
|
|
22526
22751
|
// Show prompt bubble (check both shadow root and document for compatibility)
|
|
22527
|
-
var promptBubble =
|
|
22528
|
-
if (!promptBubble &&
|
|
22752
|
+
var promptBubble = _this0.shadowRoot.getElementById('prompt-bubble');
|
|
22753
|
+
if (!promptBubble && _this0.shadowRoot !== document) {
|
|
22529
22754
|
promptBubble = document.getElementById('prompt-bubble');
|
|
22530
22755
|
}
|
|
22531
22756
|
if (promptBubble) {
|
|
@@ -22539,8 +22764,8 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22539
22764
|
|
|
22540
22765
|
// Show pulse rings if enabled
|
|
22541
22766
|
if (promptConfig.showPulseRings !== false) {
|
|
22542
|
-
var _pulseRings =
|
|
22543
|
-
if (!_pulseRings &&
|
|
22767
|
+
var _pulseRings = _this0.shadowRoot.getElementById('prompt-pulse-rings');
|
|
22768
|
+
if (!_pulseRings && _this0.shadowRoot !== document) {
|
|
22544
22769
|
_pulseRings = document.getElementById('prompt-pulse-rings');
|
|
22545
22770
|
}
|
|
22546
22771
|
if (_pulseRings) {
|
|
@@ -22577,7 +22802,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22577
22802
|
}
|
|
22578
22803
|
// Start new timer
|
|
22579
22804
|
this.promptAutoHideTimer = setTimeout(function () {
|
|
22580
|
-
|
|
22805
|
+
_this0.hidePrompt();
|
|
22581
22806
|
}, promptConfig.hideAfterSeconds * 1000);
|
|
22582
22807
|
}
|
|
22583
22808
|
}
|
|
@@ -22593,7 +22818,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22593
22818
|
}, {
|
|
22594
22819
|
key: "_doTogglePanel",
|
|
22595
22820
|
value: function _doTogglePanel() {
|
|
22596
|
-
var
|
|
22821
|
+
var _this1 = this;
|
|
22597
22822
|
if (!this.shadowRoot) return;
|
|
22598
22823
|
this.isOpen = !this.isOpen;
|
|
22599
22824
|
var panel = this.shadowRoot.getElementById('text-chat-panel');
|
|
@@ -22606,7 +22831,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22606
22831
|
// Panel is opening - hide prompt
|
|
22607
22832
|
this.hidePrompt();
|
|
22608
22833
|
setTimeout(function () {
|
|
22609
|
-
var input =
|
|
22834
|
+
var input = _this1.shadowRoot.getElementById('messageInput');
|
|
22610
22835
|
if (input) input.focus();
|
|
22611
22836
|
}, 100);
|
|
22612
22837
|
} else {
|
|
@@ -22614,14 +22839,14 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22614
22839
|
// Call showPrompt immediately, then also retry after a delay to ensure it's visible
|
|
22615
22840
|
this.showPrompt();
|
|
22616
22841
|
setTimeout(function () {
|
|
22617
|
-
var
|
|
22842
|
+
var _this1$config$promptA;
|
|
22618
22843
|
// Double-check and ensure prompt is visible
|
|
22619
|
-
var promptBubble =
|
|
22844
|
+
var promptBubble = _this1.shadowRoot.getElementById('prompt-bubble');
|
|
22620
22845
|
if (promptBubble && promptBubble.style.display === 'none') {
|
|
22621
22846
|
promptBubble.style.display = 'block';
|
|
22622
22847
|
}
|
|
22623
|
-
var pulseRings =
|
|
22624
|
-
if (pulseRings && ((
|
|
22848
|
+
var pulseRings = _this1.shadowRoot.getElementById('prompt-pulse-rings');
|
|
22849
|
+
if (pulseRings && ((_this1$config$promptA = _this1.config.promptAnimation) === null || _this1$config$promptA === void 0 ? void 0 : _this1$config$promptA.showPulseRings) !== false) {
|
|
22625
22850
|
if (pulseRings.style.display === 'none') {
|
|
22626
22851
|
pulseRings.style.display = 'block';
|
|
22627
22852
|
}
|
|
@@ -22661,13 +22886,14 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22661
22886
|
padding: '12px 24px',
|
|
22662
22887
|
borderRadius: '8px',
|
|
22663
22888
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
|
22664
|
-
zIndex: '
|
|
22889
|
+
zIndex: '10003',
|
|
22665
22890
|
fontSize: '14px',
|
|
22666
22891
|
fontWeight: '500',
|
|
22667
22892
|
maxWidth: '90%',
|
|
22668
22893
|
textAlign: 'center',
|
|
22669
22894
|
animation: 'slideUp 0.3s ease-out',
|
|
22670
|
-
fontFamily: 'inherit'
|
|
22895
|
+
fontFamily: 'inherit',
|
|
22896
|
+
pointerEvents: 'auto'
|
|
22671
22897
|
});
|
|
22672
22898
|
|
|
22673
22899
|
// Add CSS animation if not already added
|
|
@@ -22692,6 +22918,25 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
22692
22918
|
}, 300);
|
|
22693
22919
|
}, 4000);
|
|
22694
22920
|
}
|
|
22921
|
+
}, {
|
|
22922
|
+
key: "showMobileLandingError",
|
|
22923
|
+
value: function showMobileLandingError(message) {
|
|
22924
|
+
if (!this.shadowRoot) return;
|
|
22925
|
+
var mobileLanding = this.shadowRoot.getElementById('ttpMobileLanding');
|
|
22926
|
+
var mobileFab = this.shadowRoot.querySelector('.ttp-mobile-fab');
|
|
22927
|
+
var errorBanner = this.shadowRoot.getElementById('ttpMobileLandingError');
|
|
22928
|
+
if (!mobileLanding || !errorBanner) return;
|
|
22929
|
+
|
|
22930
|
+
// Set error text
|
|
22931
|
+
var errorText = errorBanner.querySelector('.ttp-mobile-landing__error-text');
|
|
22932
|
+
if (errorText) errorText.textContent = message;
|
|
22933
|
+
errorBanner.style.display = 'flex';
|
|
22934
|
+
|
|
22935
|
+
// Show the mobile landing overlay with the error
|
|
22936
|
+
mobileLanding.classList.add('active');
|
|
22937
|
+
if (mobileFab) mobileFab.style.display = 'none';
|
|
22938
|
+
this.isMobileLandingOpen = true;
|
|
22939
|
+
}
|
|
22695
22940
|
|
|
22696
22941
|
/**
|
|
22697
22942
|
* Show confirmation modal (reusing modal pattern)
|
|
@@ -23366,12 +23611,12 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
23366
23611
|
key: "_flushPendingClientTools",
|
|
23367
23612
|
value: function _flushPendingClientTools() {
|
|
23368
23613
|
var _this$voiceInterface1,
|
|
23369
|
-
|
|
23614
|
+
_this10 = this;
|
|
23370
23615
|
if (this._pendingClientTools && (_this$voiceInterface1 = this.voiceInterface) !== null && _this$voiceInterface1 !== void 0 && _this$voiceInterface1.sdk) {
|
|
23371
23616
|
this._pendingClientTools.forEach(function (_ref2) {
|
|
23372
23617
|
var name = _ref2.name,
|
|
23373
23618
|
handler = _ref2.handler;
|
|
23374
|
-
|
|
23619
|
+
_this10.voiceInterface.sdk.registerToolHandler(name, handler);
|
|
23375
23620
|
});
|
|
23376
23621
|
this._pendingClientTools = null;
|
|
23377
23622
|
console.log('TTPChatWidget: Flushed pending client tools');
|
|
@@ -24560,7 +24805,7 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
24560
24805
|
value: (function () {
|
|
24561
24806
|
var _proceedWithVoiceCall = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
|
|
24562
24807
|
var _this3 = this;
|
|
24563
|
-
var isResumeCall, panel, header, toggleText, _voiceInterface, originalSection, compactSection, idleState, _panel, fallbackPanel, sampleRate, mediaStream, floatingButton, fallbackButton, existingBar, _floatingButton, _fallbackButton, _idleState, _panel2, _fallbackPanel, deviceInfo, _idleState2, activeState, voiceInterface, connected, serverRejected, originalOnError, originalOnDisconnected, attempts, _this$sdk$voiceSDK, error, _existingBar, _existingBar2, _idleState3, _panel3, _fallbackPanel2, _floatingButton2, _fallbackButton2, updateTimer, _existingBar3, _existingBar4, _idleState4, _panel4, _fallbackPanel3, _floatingButton3, _fallbackButton3, _updateTimer, _deviceInfo, _t2, _t3, _t4, _t5, _t6, _t7;
|
|
24808
|
+
var isResumeCall, panel, header, toggleText, _voiceInterface, originalSection, compactSection, idleState, _panel, fallbackPanel, sampleRate, mediaStream, floatingButton, fallbackButton, mobileFabGrant, existingBar, _floatingButton, _fallbackButton, mobileFabDeny, _idleState, _panel2, _fallbackPanel, deviceInfo, _idleState2, activeState, voiceInterface, connected, serverRejected, originalOnError, originalOnDisconnected, attempts, _this$sdk$voiceSDK, error, _existingBar, _existingBar2, _idleState3, _panel3, _fallbackPanel2, _floatingButton2, _fallbackButton2, updateTimer, _existingBar3, _existingBar4, _idleState4, _panel4, _fallbackPanel3, _floatingButton3, _fallbackButton3, _updateTimer, _deviceInfo, _t2, _t3, _t4, _t5, _t6, _t7;
|
|
24564
24809
|
return _regenerator().w(function (_context5) {
|
|
24565
24810
|
while (1) switch (_context5.p = _context5.n) {
|
|
24566
24811
|
case 0:
|
|
@@ -24667,6 +24912,8 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
24667
24912
|
console.log('✅ Floating button hidden (permission granted, fallback)');
|
|
24668
24913
|
}
|
|
24669
24914
|
}
|
|
24915
|
+
mobileFabGrant = this.shadowRoot.querySelector('.ttp-mobile-fab');
|
|
24916
|
+
if (mobileFabGrant) mobileFabGrant.style.display = 'none';
|
|
24670
24917
|
_context5.n = 4;
|
|
24671
24918
|
break;
|
|
24672
24919
|
case 3:
|
|
@@ -24692,6 +24939,8 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
24692
24939
|
_fallbackButton.style.display = '';
|
|
24693
24940
|
}
|
|
24694
24941
|
}
|
|
24942
|
+
mobileFabDeny = this.shadowRoot.querySelector('.ttp-mobile-fab');
|
|
24943
|
+
if (mobileFabDeny) mobileFabDeny.style.display = '';
|
|
24695
24944
|
_idleState = this.shadowRoot.getElementById('voiceIdleState');
|
|
24696
24945
|
if (_idleState) {
|
|
24697
24946
|
_idleState.style.display = 'flex';
|
|
@@ -25262,7 +25511,7 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
25262
25511
|
key: "endCallOnServerRejection",
|
|
25263
25512
|
value: (function () {
|
|
25264
25513
|
var _endCallOnServerRejection = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
|
|
25265
|
-
var voiceInterfaceEl, landingScreen, _this$sdk$voiceSDK2, _this$sdk$voiceSDK3, audioRecorder, isRecording, _this$sdk$voiceSDK4, activeState, idleState, panel, fallbackPanel, floatingButton, fallbackButton, _t8, _t9, _t0, _t1, _t10;
|
|
25514
|
+
var voiceInterfaceEl, landingScreen, _this$sdk$voiceSDK2, _this$sdk$voiceSDK3, audioRecorder, isRecording, _this$sdk$voiceSDK4, activeState, idleState, panel, fallbackPanel, floatingButton, fallbackButton, mobileFabEnd, errorMsg, _t8, _t9, _t0, _t1, _t10;
|
|
25266
25515
|
return _regenerator().w(function (_context6) {
|
|
25267
25516
|
while (1) switch (_context6.p = _context6.n) {
|
|
25268
25517
|
case 0:
|
|
@@ -25475,7 +25724,7 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
25475
25724
|
console.log('🚫 showDomainError() completed, isShowingDomainError:', this.isShowingDomainError);
|
|
25476
25725
|
}
|
|
25477
25726
|
|
|
25478
|
-
// Mobile: restore panel visibility
|
|
25727
|
+
// Mobile: restore panel visibility and show error toast
|
|
25479
25728
|
if (this.isMobile) {
|
|
25480
25729
|
panel = this.shadowRoot.getElementById('text-chat-panel');
|
|
25481
25730
|
if (panel) {
|
|
@@ -25497,10 +25746,20 @@ var VoiceInterface = /*#__PURE__*/function () {
|
|
|
25497
25746
|
fallbackButton.style.display = '';
|
|
25498
25747
|
}
|
|
25499
25748
|
}
|
|
25749
|
+
mobileFabEnd = this.shadowRoot.querySelector('.ttp-mobile-fab');
|
|
25750
|
+
if (mobileFabEnd) mobileFabEnd.style.display = '';
|
|
25500
25751
|
|
|
25501
25752
|
// Remove mobile minimized bar if it exists
|
|
25502
25753
|
this.removeMobileMinimizedBar();
|
|
25503
25754
|
this.stopWaveformAnimation();
|
|
25755
|
+
|
|
25756
|
+
// Show error in mobile landing overlay since the panel isn't visible
|
|
25757
|
+
errorMsg = this.t('domainNotValidated') || 'Domain not whitelisted. Please contact support.';
|
|
25758
|
+
if (this.config.onMobileError) {
|
|
25759
|
+
this.config.onMobileError(errorMsg);
|
|
25760
|
+
} else if (this.config.onErrorToast) {
|
|
25761
|
+
this.config.onErrorToast(errorMsg, 'error');
|
|
25762
|
+
}
|
|
25504
25763
|
}
|
|
25505
25764
|
case 23:
|
|
25506
25765
|
return _context6.a(2);
|