ttp-agent-sdk 2.4.23 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-widget.js +1 -1
- package/dist/agent-widget.js.map +1 -1
- package/dist/demos/index.html +273 -0
- package/dist/examples/test-index.html +273 -0
- package/dist/examples/test-widget.html +477 -0
- package/dist/shared/mic-permission-assets/address-bar-hint.svg +41 -0
- package/dist/shared/mic-permission-assets/android-chrome.svg +72 -0
- package/dist/shared/mic-permission-assets/desktop-chrome.svg +77 -0
- package/dist/shared/mic-permission-assets/desktop-edge.svg +65 -0
- package/dist/shared/mic-permission-assets/desktop-firefox.svg +60 -0
- package/dist/shared/mic-permission-assets/desktop-safari.svg +64 -0
- package/dist/shared/mic-permission-assets/ios-settings.svg +71 -0
- package/examples/test-index.html +273 -0
- package/examples/test-widget.html +477 -0
- package/package.json +1 -1
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>TTP Chat Widget - Test Page</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
body {
|
|
15
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
|
|
16
|
+
background: #f9fafb;
|
|
17
|
+
padding: 20px;
|
|
18
|
+
min-height: 100vh;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.container {
|
|
22
|
+
max-width: 1200px;
|
|
23
|
+
margin: 0 auto;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.header {
|
|
27
|
+
background: white;
|
|
28
|
+
padding: 32px;
|
|
29
|
+
border-radius: 16px;
|
|
30
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
31
|
+
margin-bottom: 24px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.header h1 {
|
|
35
|
+
font-size: 32px;
|
|
36
|
+
font-weight: 700;
|
|
37
|
+
color: #111827;
|
|
38
|
+
margin-bottom: 8px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.header p {
|
|
42
|
+
font-size: 16px;
|
|
43
|
+
color: #6b7280;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.back-link {
|
|
47
|
+
display: inline-block;
|
|
48
|
+
margin-bottom: 20px;
|
|
49
|
+
color: #4f46e5;
|
|
50
|
+
text-decoration: none;
|
|
51
|
+
font-weight: 500;
|
|
52
|
+
transition: color 0.2s;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.back-link:hover {
|
|
56
|
+
color: #4338ca;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.config-section {
|
|
60
|
+
background: white;
|
|
61
|
+
padding: 32px;
|
|
62
|
+
border-radius: 16px;
|
|
63
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
64
|
+
margin-bottom: 24px;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.config-section h2 {
|
|
68
|
+
font-size: 24px;
|
|
69
|
+
font-weight: 700;
|
|
70
|
+
color: #111827;
|
|
71
|
+
margin-bottom: 20px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.config-grid {
|
|
75
|
+
display: grid;
|
|
76
|
+
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
77
|
+
gap: 20px;
|
|
78
|
+
margin-bottom: 24px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.config-group {
|
|
82
|
+
display: flex;
|
|
83
|
+
flex-direction: column;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.config-group label {
|
|
87
|
+
font-size: 14px;
|
|
88
|
+
font-weight: 600;
|
|
89
|
+
color: #374151;
|
|
90
|
+
margin-bottom: 8px;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.config-group input,
|
|
94
|
+
.config-group select {
|
|
95
|
+
padding: 10px 12px;
|
|
96
|
+
border: 1px solid #d1d5db;
|
|
97
|
+
border-radius: 8px;
|
|
98
|
+
font-size: 14px;
|
|
99
|
+
transition: border-color 0.2s;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.config-group input:focus,
|
|
103
|
+
.config-group select:focus {
|
|
104
|
+
outline: none;
|
|
105
|
+
border-color: #4f46e5;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.info-box {
|
|
109
|
+
background: #eff6ff;
|
|
110
|
+
border-left: 4px solid #3b82f6;
|
|
111
|
+
padding: 16px;
|
|
112
|
+
border-radius: 8px;
|
|
113
|
+
margin-bottom: 24px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.info-box h3 {
|
|
117
|
+
font-size: 16px;
|
|
118
|
+
font-weight: 600;
|
|
119
|
+
color: #1e40af;
|
|
120
|
+
margin-bottom: 8px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.info-box p {
|
|
124
|
+
font-size: 14px;
|
|
125
|
+
color: #1e3a8a;
|
|
126
|
+
line-height: 1.6;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.info-box ul {
|
|
130
|
+
margin-top: 8px;
|
|
131
|
+
padding-left: 20px;
|
|
132
|
+
color: #1e3a8a;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.info-box li {
|
|
136
|
+
margin-bottom: 4px;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.warning-box {
|
|
140
|
+
background: #fef3c7;
|
|
141
|
+
border-left: 4px solid #f59e0b;
|
|
142
|
+
padding: 16px;
|
|
143
|
+
border-radius: 8px;
|
|
144
|
+
margin-bottom: 24px;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.warning-box h3 {
|
|
148
|
+
font-size: 16px;
|
|
149
|
+
font-weight: 600;
|
|
150
|
+
color: #92400e;
|
|
151
|
+
margin-bottom: 8px;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.warning-box p {
|
|
155
|
+
font-size: 14px;
|
|
156
|
+
color: #78350f;
|
|
157
|
+
line-height: 1.6;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.button-group {
|
|
161
|
+
display: flex;
|
|
162
|
+
gap: 12px;
|
|
163
|
+
flex-wrap: wrap;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.btn {
|
|
167
|
+
padding: 12px 24px;
|
|
168
|
+
border: none;
|
|
169
|
+
border-radius: 8px;
|
|
170
|
+
font-size: 16px;
|
|
171
|
+
font-weight: 600;
|
|
172
|
+
cursor: pointer;
|
|
173
|
+
transition: all 0.2s;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.btn-primary {
|
|
177
|
+
background: #4f46e5;
|
|
178
|
+
color: white;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.btn-primary:hover {
|
|
182
|
+
background: #4338ca;
|
|
183
|
+
transform: translateY(-1px);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.btn-secondary {
|
|
187
|
+
background: #e5e7eb;
|
|
188
|
+
color: #111827;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.btn-secondary:hover {
|
|
192
|
+
background: #d1d5db;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.status {
|
|
196
|
+
background: #f3f4f6;
|
|
197
|
+
padding: 16px;
|
|
198
|
+
border-radius: 8px;
|
|
199
|
+
margin-top: 24px;
|
|
200
|
+
font-family: monospace;
|
|
201
|
+
font-size: 14px;
|
|
202
|
+
color: #374151;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.status-item {
|
|
206
|
+
margin-bottom: 8px;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.status-item:last-child {
|
|
210
|
+
margin-bottom: 0;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.status-label {
|
|
214
|
+
font-weight: 600;
|
|
215
|
+
color: #111827;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
@media (max-width: 768px) {
|
|
219
|
+
.header h1 {
|
|
220
|
+
font-size: 24px;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.config-grid {
|
|
224
|
+
grid-template-columns: 1fr;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.button-group {
|
|
228
|
+
flex-direction: column;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.btn {
|
|
232
|
+
width: 100%;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
</style>
|
|
236
|
+
</head>
|
|
237
|
+
<body>
|
|
238
|
+
<div class="container">
|
|
239
|
+
<a href="test-index.html" class="back-link">← Back to Test Pages</a>
|
|
240
|
+
|
|
241
|
+
<div class="header">
|
|
242
|
+
<h1>🎨 TTP Chat Widget Test</h1>
|
|
243
|
+
<p>Test the unified voice and text chat widget with microphone permission handling</p>
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
|
+
<div class="warning-box">
|
|
247
|
+
<h3>📱 Mobile Browser Note</h3>
|
|
248
|
+
<p>
|
|
249
|
+
Microphone access requires HTTPS and must be triggered by a direct button tap.
|
|
250
|
+
If you see permission errors, ensure you're using HTTPS and tap the recording button directly.
|
|
251
|
+
</p>
|
|
252
|
+
</div>
|
|
253
|
+
|
|
254
|
+
<div class="info-box">
|
|
255
|
+
<h3>ℹ️ About This Test</h3>
|
|
256
|
+
<p>
|
|
257
|
+
This page tests the <strong>TTPChatWidget</strong> which provides a unified interface for both
|
|
258
|
+
voice and text chat. The widget includes:
|
|
259
|
+
</p>
|
|
260
|
+
<ul>
|
|
261
|
+
<li>🎤 Voice call functionality with microphone permission handling</li>
|
|
262
|
+
<li>💬 Text chat interface</li>
|
|
263
|
+
<li>🎨 Customizable styling and positioning</li>
|
|
264
|
+
<li>🌐 Multi-language support</li>
|
|
265
|
+
<li>📱 Mobile-responsive design</li>
|
|
266
|
+
</ul>
|
|
267
|
+
</div>
|
|
268
|
+
|
|
269
|
+
<div class="config-section">
|
|
270
|
+
<h2>⚙️ Widget Configuration</h2>
|
|
271
|
+
|
|
272
|
+
<div class="config-grid">
|
|
273
|
+
<div class="config-group">
|
|
274
|
+
<label for="agentId">Agent ID *</label>
|
|
275
|
+
<input type="text" id="agentId" value="agent_e5cf06457" placeholder="agent_123">
|
|
276
|
+
</div>
|
|
277
|
+
|
|
278
|
+
<div class="config-group">
|
|
279
|
+
<label for="appId">App ID *</label>
|
|
280
|
+
<input type="text" id="appId" value="app_Bc01EqMQt2Euehl4qqZSi6l3FJP42Q9vJ0pC" placeholder="app_456">
|
|
281
|
+
</div>
|
|
282
|
+
|
|
283
|
+
<div class="config-group">
|
|
284
|
+
<label for="getSessionUrl">Get Session URL</label>
|
|
285
|
+
<input type="text" id="getSessionUrl" value="" placeholder="https://your-api.com/get-session">
|
|
286
|
+
</div>
|
|
287
|
+
|
|
288
|
+
<div class="config-group">
|
|
289
|
+
<label for="websocketUrl">WebSocket URL</label>
|
|
290
|
+
<input type="text" id="websocketUrl" value="wss://speech.talktopc.com/ws/conv" placeholder="wss://...">
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
<div class="config-group">
|
|
294
|
+
<label for="position">Position</label>
|
|
295
|
+
<select id="position">
|
|
296
|
+
<option value="bottom-right" selected>Bottom Right</option>
|
|
297
|
+
<option value="bottom-left">Bottom Left</option>
|
|
298
|
+
<option value="top-right">Top Right</option>
|
|
299
|
+
<option value="top-left">Top Left</option>
|
|
300
|
+
</select>
|
|
301
|
+
</div>
|
|
302
|
+
|
|
303
|
+
<div class="config-group">
|
|
304
|
+
<label for="language">Language</label>
|
|
305
|
+
<select id="language">
|
|
306
|
+
<option value="en" selected>English</option>
|
|
307
|
+
<option value="he">Hebrew</option>
|
|
308
|
+
<option value="ar">Arabic</option>
|
|
309
|
+
<option value="ru">Russian</option>
|
|
310
|
+
<option value="es">Spanish</option>
|
|
311
|
+
<option value="fr">French</option>
|
|
312
|
+
<option value="de">German</option>
|
|
313
|
+
</select>
|
|
314
|
+
</div>
|
|
315
|
+
|
|
316
|
+
<div class="config-group">
|
|
317
|
+
<label for="mode">Widget Mode</label>
|
|
318
|
+
<select id="mode">
|
|
319
|
+
<option value="unified" selected>Unified (Voice + Text)</option>
|
|
320
|
+
<option value="voice-only">Voice Only</option>
|
|
321
|
+
<option value="text-only">Text Only</option>
|
|
322
|
+
</select>
|
|
323
|
+
</div>
|
|
324
|
+
|
|
325
|
+
<div class="config-group">
|
|
326
|
+
<label for="primaryColor">Primary Color</label>
|
|
327
|
+
<input type="color" id="primaryColor" value="#7C3AED">
|
|
328
|
+
</div>
|
|
329
|
+
</div>
|
|
330
|
+
|
|
331
|
+
<div class="button-group">
|
|
332
|
+
<button class="btn btn-primary" onclick="initializeWidget()">Initialize Widget</button>
|
|
333
|
+
<button class="btn btn-secondary" onclick="destroyWidget()">Destroy Widget</button>
|
|
334
|
+
<button class="btn btn-secondary" onclick="resetConfig()">Reset Config</button>
|
|
335
|
+
</div>
|
|
336
|
+
|
|
337
|
+
<div id="status" class="status" style="display: none;">
|
|
338
|
+
<div class="status-item">
|
|
339
|
+
<span class="status-label">Status:</span> <span id="statusText">Ready</span>
|
|
340
|
+
</div>
|
|
341
|
+
<div class="status-item">
|
|
342
|
+
<span class="status-label">Widget Initialized:</span> <span id="widgetStatus">No</span>
|
|
343
|
+
</div>
|
|
344
|
+
</div>
|
|
345
|
+
</div>
|
|
346
|
+
|
|
347
|
+
<div class="info-box">
|
|
348
|
+
<h3>📝 Test Scenarios</h3>
|
|
349
|
+
<p>Try these scenarios to test the widget:</p>
|
|
350
|
+
<ul>
|
|
351
|
+
<li><strong>Voice Call:</strong> Click "Voice Call" → Should show pre-prompt modal → Grant permission → Start call</li>
|
|
352
|
+
<li><strong>Permission Denied:</strong> Deny microphone permission → Should show blocked modal with instructions</li>
|
|
353
|
+
<li><strong>Text Chat:</strong> Click "Text Chat" → Send messages → Test conversation flow</li>
|
|
354
|
+
<li><strong>Widget Positioning:</strong> Change position and reinitialize to test different placements</li>
|
|
355
|
+
<li><strong>Language:</strong> Change language to test translations</li>
|
|
356
|
+
</ul>
|
|
357
|
+
</div>
|
|
358
|
+
</div>
|
|
359
|
+
|
|
360
|
+
<!-- Load SDK -->
|
|
361
|
+
<script type="module">
|
|
362
|
+
import { TTPChatWidget } from '../dist/agent-widget.js';
|
|
363
|
+
|
|
364
|
+
window.TTPChatWidget = TTPChatWidget;
|
|
365
|
+
window.widgetInstance = null;
|
|
366
|
+
|
|
367
|
+
window.initializeWidget = function() {
|
|
368
|
+
const agentId = document.getElementById('agentId').value;
|
|
369
|
+
const appId = document.getElementById('appId').value;
|
|
370
|
+
const getSessionUrl = document.getElementById('getSessionUrl').value;
|
|
371
|
+
const websocketUrl = document.getElementById('websocketUrl').value;
|
|
372
|
+
const position = document.getElementById('position').value;
|
|
373
|
+
const language = document.getElementById('language').value;
|
|
374
|
+
const mode = document.getElementById('mode').value;
|
|
375
|
+
const primaryColor = document.getElementById('primaryColor').value;
|
|
376
|
+
|
|
377
|
+
if (!agentId || !appId) {
|
|
378
|
+
alert('Please provide Agent ID and App ID');
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Destroy existing widget if any
|
|
383
|
+
if (window.widgetInstance) {
|
|
384
|
+
window.destroyWidget();
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
try {
|
|
388
|
+
const config = {
|
|
389
|
+
agentId: agentId,
|
|
390
|
+
appId: appId,
|
|
391
|
+
language: language,
|
|
392
|
+
primaryColor: primaryColor,
|
|
393
|
+
behavior: {
|
|
394
|
+
mode: mode
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
// Add optional configs
|
|
399
|
+
if (getSessionUrl) {
|
|
400
|
+
config.getSessionUrl = getSessionUrl;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (websocketUrl) {
|
|
404
|
+
config.websocketUrl = websocketUrl;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Handle position
|
|
408
|
+
if (position) {
|
|
409
|
+
const [vertical, horizontal] = position.split('-');
|
|
410
|
+
config.position = {
|
|
411
|
+
vertical: vertical,
|
|
412
|
+
horizontal: horizontal,
|
|
413
|
+
offset: { x: 20, y: 20 }
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
console.log('Initializing widget with config:', config);
|
|
418
|
+
window.widgetInstance = new TTPChatWidget(config);
|
|
419
|
+
|
|
420
|
+
// Update status
|
|
421
|
+
document.getElementById('status').style.display = 'block';
|
|
422
|
+
document.getElementById('statusText').textContent = 'Widget initialized';
|
|
423
|
+
document.getElementById('widgetStatus').textContent = 'Yes';
|
|
424
|
+
|
|
425
|
+
console.log('✅ Widget initialized successfully');
|
|
426
|
+
} catch (error) {
|
|
427
|
+
console.error('❌ Error initializing widget:', error);
|
|
428
|
+
alert('Error initializing widget: ' + error.message);
|
|
429
|
+
document.getElementById('statusText').textContent = 'Error: ' + error.message;
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
window.destroyWidget = function() {
|
|
434
|
+
if (window.widgetInstance) {
|
|
435
|
+
try {
|
|
436
|
+
// Widget doesn't have a destroy method, but we can remove it from DOM
|
|
437
|
+
const widgetButton = document.getElementById('text-chat-button');
|
|
438
|
+
const widgetPanel = document.getElementById('text-chat-panel');
|
|
439
|
+
|
|
440
|
+
if (widgetButton && widgetButton.parentNode) {
|
|
441
|
+
widgetButton.parentNode.removeChild(widgetButton);
|
|
442
|
+
}
|
|
443
|
+
if (widgetPanel && widgetPanel.parentNode) {
|
|
444
|
+
widgetPanel.parentNode.removeChild(widgetPanel);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
window.widgetInstance = null;
|
|
448
|
+
document.getElementById('statusText').textContent = 'Widget destroyed';
|
|
449
|
+
document.getElementById('widgetStatus').textContent = 'No';
|
|
450
|
+
console.log('✅ Widget destroyed');
|
|
451
|
+
} catch (error) {
|
|
452
|
+
console.error('❌ Error destroying widget:', error);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
window.resetConfig = function() {
|
|
458
|
+
document.getElementById('agentId').value = 'agent_e5cf06457';
|
|
459
|
+
document.getElementById('appId').value = 'app_Bc01EqMQt2Euehl4qqZSi6l3FJP42Q9vJ0pC';
|
|
460
|
+
document.getElementById('getSessionUrl').value = '';
|
|
461
|
+
document.getElementById('websocketUrl').value = 'wss://speech.talktopc.com/ws/conv';
|
|
462
|
+
document.getElementById('position').value = 'bottom-right';
|
|
463
|
+
document.getElementById('language').value = 'en';
|
|
464
|
+
document.getElementById('mode').value = 'unified';
|
|
465
|
+
document.getElementById('primaryColor').value = '#7C3AED';
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
// Auto-initialize on load (optional)
|
|
469
|
+
// window.addEventListener('DOMContentLoaded', () => {
|
|
470
|
+
// setTimeout(() => {
|
|
471
|
+
// window.initializeWidget();
|
|
472
|
+
// }, 1000);
|
|
473
|
+
// });
|
|
474
|
+
</script>
|
|
475
|
+
</body>
|
|
476
|
+
</html>
|
|
477
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 120" width="500" height="120">
|
|
2
|
+
<defs>
|
|
3
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
4
|
+
<feDropShadow dx="0" dy="2" stdDeviation="4" flood-opacity="0.1"/>
|
|
5
|
+
</filter>
|
|
6
|
+
</defs>
|
|
7
|
+
|
|
8
|
+
<!-- Browser chrome background -->
|
|
9
|
+
<rect width="500" height="120" fill="#f1f3f4" rx="8"/>
|
|
10
|
+
|
|
11
|
+
<!-- Tab bar -->
|
|
12
|
+
<rect x="0" y="0" width="500" height="40" fill="#dee1e6" rx="8 8 0 0"/>
|
|
13
|
+
|
|
14
|
+
<!-- Active tab -->
|
|
15
|
+
<rect x="10" y="8" width="180" height="32" fill="#f1f3f4" rx="8 8 0 0"/>
|
|
16
|
+
<text x="40" y="30" font-family="Segoe UI, Arial, sans-serif" font-size="13" fill="#202124">🌐 Your Website</text>
|
|
17
|
+
<text x="170" y="30" font-family="Arial, sans-serif" font-size="14" fill="#5f6368">×</text>
|
|
18
|
+
|
|
19
|
+
<!-- Address bar area -->
|
|
20
|
+
<rect x="10" y="50" width="480" height="40" fill="white" rx="20" filter="url(#shadow)"/>
|
|
21
|
+
|
|
22
|
+
<!-- HIGHLIGHTED Lock icon area -->
|
|
23
|
+
<rect x="12" y="52" width="45" height="36" fill="#e8f5e9" rx="18 0 0 18"/>
|
|
24
|
+
<rect x="12" y="52" width="4" height="36" fill="#4caf50" rx="2"/>
|
|
25
|
+
|
|
26
|
+
<!-- Lock icon -->
|
|
27
|
+
<circle cx="35" cy="70" r="12" fill="#4caf50"/>
|
|
28
|
+
<text x="29" y="76" font-family="Arial, sans-serif" font-size="14" fill="white">🔒</text>
|
|
29
|
+
|
|
30
|
+
<!-- URL text -->
|
|
31
|
+
<text x="60" y="76" font-family="Segoe UI, Arial, sans-serif" font-size="14" fill="#202124">your-website.com/voice-call</text>
|
|
32
|
+
|
|
33
|
+
<!-- Pointer arrow -->
|
|
34
|
+
<path d="M 35 95 L 35 105 L 25 100 Z" fill="#4caf50"/>
|
|
35
|
+
<path d="M 35 95 L 35 105 L 45 100 Z" fill="#4caf50"/>
|
|
36
|
+
<rect x="20" y="105" width="30" height="2" fill="#4caf50"/>
|
|
37
|
+
|
|
38
|
+
<!-- Instruction text -->
|
|
39
|
+
<rect x="55" y="95" width="130" height="22" rx="4" fill="#4caf50"/>
|
|
40
|
+
<text x="67" y="111" font-family="Segoe UI, Arial, sans-serif" font-size="12" fill="white" font-weight="600">👆 Click this icon</text>
|
|
41
|
+
</svg>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 340 520" width="340" height="520">
|
|
2
|
+
<defs>
|
|
3
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
4
|
+
<feDropShadow dx="0" dy="2" stdDeviation="4" flood-opacity="0.1"/>
|
|
5
|
+
</filter>
|
|
6
|
+
</defs>
|
|
7
|
+
|
|
8
|
+
<!-- Android phone frame -->
|
|
9
|
+
<rect width="340" height="520" fill="#1a1a1a" rx="30"/>
|
|
10
|
+
<rect x="8" y="8" width="324" height="504" fill="#f5f5f5" rx="26"/>
|
|
11
|
+
|
|
12
|
+
<!-- Status bar -->
|
|
13
|
+
<rect x="8" y="8" width="324" height="28" fill="#1a73e8" rx="26 26 0 0"/>
|
|
14
|
+
<text x="25" y="27" font-family="Roboto, Arial, sans-serif" font-size="12" fill="white">12:30</text>
|
|
15
|
+
<text x="270" y="27" font-family="Roboto, Arial, sans-serif" font-size="12" fill="white">📶 🔋 85%</text>
|
|
16
|
+
|
|
17
|
+
<!-- Toolbar -->
|
|
18
|
+
<rect x="8" y="36" width="324" height="56" fill="white"/>
|
|
19
|
+
<text x="25" y="72" font-family="Roboto, Arial, sans-serif" font-size="24" fill="#5f6368">←</text>
|
|
20
|
+
<text x="60" y="72" font-family="Roboto, Arial, sans-serif" font-size="20" fill="#202124">Site settings</text>
|
|
21
|
+
|
|
22
|
+
<!-- Site header -->
|
|
23
|
+
<rect x="8" y="92" width="324" height="70" fill="white"/>
|
|
24
|
+
<line x1="8" y1="162" x2="332" y2="162" stroke="#e0e0e0" stroke-width="1"/>
|
|
25
|
+
|
|
26
|
+
<!-- Site icon -->
|
|
27
|
+
<circle cx="50" cy="127" r="22" fill="#e8eaed"/>
|
|
28
|
+
<text x="40" y="133" font-family="Arial, sans-serif" font-size="18">🌐</text>
|
|
29
|
+
|
|
30
|
+
<text x="85" y="122" font-family="Roboto, Arial, sans-serif" font-size="16" fill="#202124">your-website.com</text>
|
|
31
|
+
<text x="85" y="142" font-family="Roboto, Arial, sans-serif" font-size="13" fill="#5f6368">https://your-website.com</text>
|
|
32
|
+
|
|
33
|
+
<!-- Permissions section -->
|
|
34
|
+
<rect x="8" y="162" width="324" height="310" fill="white"/>
|
|
35
|
+
|
|
36
|
+
<text x="25" y="195" font-family="Roboto, Arial, sans-serif" font-size="14" fill="#5f6368" font-weight="500">Permissions</text>
|
|
37
|
+
|
|
38
|
+
<!-- HIGHLIGHTED Microphone Row -->
|
|
39
|
+
<rect x="8" y="210" width="324" height="65" fill="#e8f5e9"/>
|
|
40
|
+
<rect x="8" y="210" width="4" height="65" fill="#4caf50"/>
|
|
41
|
+
<text x="30" y="250" font-family="Arial, sans-serif" font-size="24">🎤</text>
|
|
42
|
+
<text x="70" y="240" font-family="Roboto, Arial, sans-serif" font-size="16" fill="#202124">Microphone</text>
|
|
43
|
+
<text x="70" y="260" font-family="Roboto, Arial, sans-serif" font-size="14" fill="#d93025">Blocked</text>
|
|
44
|
+
|
|
45
|
+
<!-- Highlight badge -->
|
|
46
|
+
<rect x="170" y="230" width="110" height="24" rx="4" fill="#4caf50"/>
|
|
47
|
+
<text x="182" y="247" font-family="Roboto, Arial, sans-serif" font-size="11" fill="white" font-weight="600">← Tap to Allow</text>
|
|
48
|
+
|
|
49
|
+
<!-- Camera Row -->
|
|
50
|
+
<rect x="8" y="275" width="324" height="60" fill="white"/>
|
|
51
|
+
<text x="30" y="312" font-family="Arial, sans-serif" font-size="24">📷</text>
|
|
52
|
+
<text x="70" y="302" font-family="Roboto, Arial, sans-serif" font-size="16" fill="#202124">Camera</text>
|
|
53
|
+
<text x="70" y="322" font-family="Roboto, Arial, sans-serif" font-size="14" fill="#5f6368">Ask first</text>
|
|
54
|
+
|
|
55
|
+
<!-- Location Row -->
|
|
56
|
+
<rect x="8" y="335" width="324" height="60" fill="white"/>
|
|
57
|
+
<text x="30" y="372" font-family="Arial, sans-serif" font-size="24">📍</text>
|
|
58
|
+
<text x="70" y="362" font-family="Roboto, Arial, sans-serif" font-size="16" fill="#202124">Location</text>
|
|
59
|
+
<text x="70" y="382" font-family="Roboto, Arial, sans-serif" font-size="14" fill="#5f6368">Ask first</text>
|
|
60
|
+
|
|
61
|
+
<!-- Notifications Row -->
|
|
62
|
+
<rect x="8" y="395" width="324" height="60" fill="white"/>
|
|
63
|
+
<text x="30" y="432" font-family="Arial, sans-serif" font-size="24">🔔</text>
|
|
64
|
+
<text x="70" y="422" font-family="Roboto, Arial, sans-serif" font-size="16" fill="#202124">Notifications</text>
|
|
65
|
+
<text x="70" y="442" font-family="Roboto, Arial, sans-serif" font-size="14" fill="#5f6368">Blocked</text>
|
|
66
|
+
|
|
67
|
+
<!-- Navigation bar -->
|
|
68
|
+
<rect x="8" y="472" width="324" height="40" fill="#f5f5f5" rx="0 0 26 26"/>
|
|
69
|
+
<rect x="100" y="482" width="40" height="4" rx="2" fill="#9e9e9e"/>
|
|
70
|
+
<rect x="160" y="482" width="40" height="4" rx="2" fill="#9e9e9e"/>
|
|
71
|
+
<rect x="220" y="482" width="40" height="4" rx="2" fill="#9e9e9e"/>
|
|
72
|
+
</svg>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 450" width="380" height="450">
|
|
2
|
+
<defs>
|
|
3
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
4
|
+
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-opacity="0.15"/>
|
|
5
|
+
</filter>
|
|
6
|
+
<linearGradient id="highlight" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
7
|
+
<stop offset="0%" style="stop-color:#4caf50;stop-opacity:1" />
|
|
8
|
+
<stop offset="100%" style="stop-color:#81c784;stop-opacity:1" />
|
|
9
|
+
</linearGradient>
|
|
10
|
+
</defs>
|
|
11
|
+
|
|
12
|
+
<!-- Background -->
|
|
13
|
+
<rect width="380" height="450" fill="#f5f5f5" rx="12"/>
|
|
14
|
+
|
|
15
|
+
<!-- Browser popup -->
|
|
16
|
+
<rect x="20" y="20" width="340" height="410" fill="white" rx="10" filter="url(#shadow)"/>
|
|
17
|
+
|
|
18
|
+
<!-- Header -->
|
|
19
|
+
<rect x="20" y="20" width="340" height="50" fill="white" rx="10 10 0 0"/>
|
|
20
|
+
<line x1="20" y1="70" x2="360" y2="70" stroke="#e5e5e5" stroke-width="1"/>
|
|
21
|
+
<text x="35" y="50" font-family="Arial, sans-serif" font-size="14" font-weight="600" fill="#202124">your-website.com</text>
|
|
22
|
+
<text x="335" y="52" font-family="Arial, sans-serif" font-size="20" fill="#5f6368">×</text>
|
|
23
|
+
|
|
24
|
+
<!-- Security info -->
|
|
25
|
+
<circle cx="45" cy="95" r="12" fill="#1a73e8"/>
|
|
26
|
+
<text x="41" y="100" font-family="Arial, sans-serif" font-size="12" fill="white" font-weight="bold">🔒</text>
|
|
27
|
+
<text x="65" y="92" font-family="Arial, sans-serif" font-size="12" fill="#202124">Connection is secure</text>
|
|
28
|
+
<text x="65" y="108" font-family="Arial, sans-serif" font-size="11" fill="#1a73e8">Learn more</text>
|
|
29
|
+
|
|
30
|
+
<!-- Divider -->
|
|
31
|
+
<line x1="35" y1="130" x2="345" y2="130" stroke="#e5e5e5" stroke-width="1"/>
|
|
32
|
+
|
|
33
|
+
<!-- HIGHLIGHTED Microphone Row -->
|
|
34
|
+
<rect x="20" y="140" width="340" height="60" fill="#e8f5e9"/>
|
|
35
|
+
<rect x="20" y="140" width="4" height="60" fill="#4caf50"/>
|
|
36
|
+
<text x="45" y="177" font-family="Arial, sans-serif" font-size="22">🎤</text>
|
|
37
|
+
<text x="80" y="175" font-family="Arial, sans-serif" font-size="14" fill="#202124">Microphone</text>
|
|
38
|
+
|
|
39
|
+
<!-- Toggle OFF -->
|
|
40
|
+
<rect x="280" y="160" width="40" height="22" rx="11" fill="#dadce0"/>
|
|
41
|
+
<circle cx="293" cy="171" r="9" fill="white"/>
|
|
42
|
+
|
|
43
|
+
<!-- Arrow -->
|
|
44
|
+
<text x="330" y="177" font-family="Arial, sans-serif" font-size="16" fill="#5f6368">›</text>
|
|
45
|
+
|
|
46
|
+
<!-- Highlight badge -->
|
|
47
|
+
<rect x="180" y="155" width="90" height="24" rx="4" fill="#4caf50"/>
|
|
48
|
+
<text x="192" y="172" font-family="Arial, sans-serif" font-size="11" fill="white" font-weight="600">👆 Click here</text>
|
|
49
|
+
|
|
50
|
+
<!-- Notifications Row -->
|
|
51
|
+
<rect x="20" y="200" width="340" height="60" fill="white"/>
|
|
52
|
+
<text x="45" y="237" font-family="Arial, sans-serif" font-size="22">🔔</text>
|
|
53
|
+
<text x="80" y="227" font-family="Arial, sans-serif" font-size="14" fill="#202124">Notifications</text>
|
|
54
|
+
<text x="80" y="245" font-family="Arial, sans-serif" font-size="12" fill="#5f6368">Not allowed (default)</text>
|
|
55
|
+
<rect x="280" y="220" width="40" height="22" rx="11" fill="#dadce0"/>
|
|
56
|
+
<circle cx="293" cy="231" r="9" fill="white"/>
|
|
57
|
+
|
|
58
|
+
<!-- Sound Row -->
|
|
59
|
+
<rect x="20" y="260" width="340" height="60" fill="white"/>
|
|
60
|
+
<text x="45" y="297" font-family="Arial, sans-serif" font-size="22">🔊</text>
|
|
61
|
+
<text x="80" y="287" font-family="Arial, sans-serif" font-size="14" fill="#202124">Sound</text>
|
|
62
|
+
<text x="80" y="305" font-family="Arial, sans-serif" font-size="12" fill="#5f6368">Automatic (default)</text>
|
|
63
|
+
<rect x="280" y="280" width="40" height="22" rx="11" fill="#1a73e8"/>
|
|
64
|
+
<circle cx="307" cy="291" r="9" fill="white"/>
|
|
65
|
+
|
|
66
|
+
<!-- Reset button -->
|
|
67
|
+
<rect x="35" y="335" width="130" height="35" rx="4" fill="white" stroke="#dadce0" stroke-width="1"/>
|
|
68
|
+
<text x="52" y="358" font-family="Arial, sans-serif" font-size="13" fill="#1a73e8">Reset permissions</text>
|
|
69
|
+
|
|
70
|
+
<!-- Divider -->
|
|
71
|
+
<line x1="35" y1="385" x2="345" y2="385" stroke="#e5e5e5" stroke-width="1"/>
|
|
72
|
+
|
|
73
|
+
<!-- Site settings -->
|
|
74
|
+
<text x="45" y="415" font-family="Arial, sans-serif" font-size="20">⚙️</text>
|
|
75
|
+
<text x="80" y="415" font-family="Arial, sans-serif" font-size="14" fill="#202124">Site settings</text>
|
|
76
|
+
<text x="330" y="415" font-family="Arial, sans-serif" font-size="14" fill="#5f6368">↗</text>
|
|
77
|
+
</svg>
|