test-chat-component-per 1.0.1
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/LICENSE +29 -0
- package/README.md +298 -0
- package/dist/delachat-webcomponent.js +683 -0
- package/dist/delachat-webcomponent.min.js +1 -0
- package/dist/delachat-webcomponent.min.js.map +1 -0
- package/package.json +66 -0
- package/src/delachat-webcomponent.js +683 -0
- package/src/delachat.css +430 -0
- package/src/delachat.js +580 -0
- package/src/index.html +343 -0
- package/src/webcomponent-demo.html +452 -0
- package/types/index.d.ts +130 -0
package/src/delachat.js
ADDED
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DelaChat - Standalone Chat Component
|
|
3
|
+
* Version: 1.0.0
|
|
4
|
+
*
|
|
5
|
+
* A plug-and-play chat component for integrating DelaChat AI
|
|
6
|
+
* Pure vanilla JavaScript - zero dependencies
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
(function(window) {
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
// Component version
|
|
13
|
+
const VERSION = '1.0.0';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* DelaChat Constructor
|
|
17
|
+
*/
|
|
18
|
+
function DelaChatInstance(container, config) {
|
|
19
|
+
this.container = container;
|
|
20
|
+
this.config = this._validateConfig(config);
|
|
21
|
+
this.state = {
|
|
22
|
+
messages: [],
|
|
23
|
+
isLoading: false,
|
|
24
|
+
isOpen: true,
|
|
25
|
+
error: null
|
|
26
|
+
};
|
|
27
|
+
this.elements = {};
|
|
28
|
+
this.eventListeners = {};
|
|
29
|
+
|
|
30
|
+
this._init();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Initialize the component
|
|
35
|
+
*/
|
|
36
|
+
DelaChatInstance.prototype._init = function() {
|
|
37
|
+
this._render();
|
|
38
|
+
this._attachEventListeners();
|
|
39
|
+
this._loadHistory();
|
|
40
|
+
|
|
41
|
+
if (this.config.onReady) {
|
|
42
|
+
this.config.onReady.call(this);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Validate and set default configuration
|
|
48
|
+
*/
|
|
49
|
+
DelaChatInstance.prototype._validateConfig = function(config) {
|
|
50
|
+
if (!config.apiUrl) throw new Error('apiUrl is required');
|
|
51
|
+
if (!config.sessionUid) throw new Error('sessionUid is required');
|
|
52
|
+
if (!config.datasource) throw new Error('datasource is required');
|
|
53
|
+
if (!config.productId) throw new Error('productId is required');
|
|
54
|
+
if (!config.token) throw new Error('token is required');
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
apiUrl: config.apiUrl,
|
|
58
|
+
sessionUid: config.sessionUid,
|
|
59
|
+
datasource: config.datasource,
|
|
60
|
+
productId: config.productId,
|
|
61
|
+
token: config.token,
|
|
62
|
+
theme: config.theme || 'light',
|
|
63
|
+
height: config.height || '600px',
|
|
64
|
+
width: config.width || '400px',
|
|
65
|
+
position: config.position || 'inline',
|
|
66
|
+
autoOpen: config.autoOpen !== false,
|
|
67
|
+
avatarUrl: config.avatarUrl || null,
|
|
68
|
+
userName: config.userName || 'User',
|
|
69
|
+
onReady: config.onReady || null,
|
|
70
|
+
onMessageSent: config.onMessageSent || null,
|
|
71
|
+
onMessageReceived: config.onMessageReceived || null,
|
|
72
|
+
onError: config.onError || null,
|
|
73
|
+
onClose: config.onClose || null
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Render the chat UI
|
|
79
|
+
*/
|
|
80
|
+
DelaChatInstance.prototype._render = function() {
|
|
81
|
+
const html = `
|
|
82
|
+
<div class="delachat-window" data-theme="${this.config.theme}" style="height: ${this.config.height}; width: ${this.config.width};">
|
|
83
|
+
<!-- Header -->
|
|
84
|
+
<div class="delachat-header">
|
|
85
|
+
<h2 class="delachat-title">Ask Dela</h2>
|
|
86
|
+
<div class="delachat-header-buttons">
|
|
87
|
+
<button class="delachat-btn-icon" data-action="disclaimer" title="Disclaimer">
|
|
88
|
+
<span class="delachat-icon">ℹ</span>
|
|
89
|
+
</button>
|
|
90
|
+
<button class="delachat-btn-icon" data-action="new-chat" title="New Chat">
|
|
91
|
+
<span class="delachat-icon">+</span>
|
|
92
|
+
</button>
|
|
93
|
+
<button class="delachat-btn-icon" data-action="help" title="Help">
|
|
94
|
+
<span class="delachat-icon">?</span>
|
|
95
|
+
</button>
|
|
96
|
+
<button class="delachat-btn-icon" data-action="close" title="Close">
|
|
97
|
+
<span class="delachat-icon">✕</span>
|
|
98
|
+
</button>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<!-- Disclaimer -->
|
|
103
|
+
<div class="delachat-disclaimer" style="display: none;">
|
|
104
|
+
<p>Dela is an AI-powered assistant. While I strive to provide accurate information, please verify important details independently.</p>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<!-- Error message -->
|
|
108
|
+
<div class="delachat-error" style="display: none;"></div>
|
|
109
|
+
|
|
110
|
+
<!-- Messages area -->
|
|
111
|
+
<div class="delachat-messages">
|
|
112
|
+
<div class="delachat-welcome">
|
|
113
|
+
<div class="delachat-ai-avatar-large">
|
|
114
|
+
<span>🤖</span>
|
|
115
|
+
</div>
|
|
116
|
+
<p>Hello! I'm Dela, your AI assistant. How can I help you today?</p>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
<!-- Loading indicator -->
|
|
121
|
+
<div class="delachat-loading" style="display: none;">
|
|
122
|
+
<div class="delachat-loading-dots">
|
|
123
|
+
<span></span>
|
|
124
|
+
<span></span>
|
|
125
|
+
<span></span>
|
|
126
|
+
</div>
|
|
127
|
+
<span>Dela is thinking...</span>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
<!-- Input area -->
|
|
131
|
+
<div class="delachat-input-container">
|
|
132
|
+
<div class="delachat-input-wrapper">
|
|
133
|
+
<textarea
|
|
134
|
+
class="delachat-input"
|
|
135
|
+
placeholder="Type your message..."
|
|
136
|
+
rows="1"
|
|
137
|
+
></textarea>
|
|
138
|
+
<button class="delachat-btn-send" data-action="send" title="Send message">
|
|
139
|
+
<span class="delachat-icon">➤</span>
|
|
140
|
+
</button>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
`;
|
|
145
|
+
|
|
146
|
+
this.container.innerHTML = html;
|
|
147
|
+
this._cacheElements();
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Cache DOM elements
|
|
152
|
+
*/
|
|
153
|
+
DelaChatInstance.prototype._cacheElements = function() {
|
|
154
|
+
const win = this.container.querySelector('.delachat-window');
|
|
155
|
+
this.elements = {
|
|
156
|
+
window: win,
|
|
157
|
+
header: win.querySelector('.delachat-header'),
|
|
158
|
+
disclaimer: win.querySelector('.delachat-disclaimer'),
|
|
159
|
+
error: win.querySelector('.delachat-error'),
|
|
160
|
+
messages: win.querySelector('.delachat-messages'),
|
|
161
|
+
welcome: win.querySelector('.delachat-welcome'),
|
|
162
|
+
loading: win.querySelector('.delachat-loading'),
|
|
163
|
+
inputContainer: win.querySelector('.delachat-input-container'),
|
|
164
|
+
input: win.querySelector('.delachat-input'),
|
|
165
|
+
btnSend: win.querySelector('[data-action="send"]'),
|
|
166
|
+
btnClose: win.querySelector('[data-action="close"]'),
|
|
167
|
+
btnDisclaimer: win.querySelector('[data-action="disclaimer"]'),
|
|
168
|
+
btnNewChat: win.querySelector('[data-action="new-chat"]'),
|
|
169
|
+
btnHelp: win.querySelector('[data-action="help"]')
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Attach event listeners
|
|
175
|
+
*/
|
|
176
|
+
DelaChatInstance.prototype._attachEventListeners = function() {
|
|
177
|
+
var self = this;
|
|
178
|
+
|
|
179
|
+
// Send button
|
|
180
|
+
this.elements.btnSend.addEventListener('click', function() {
|
|
181
|
+
self._handleSend();
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Input - Enter key
|
|
185
|
+
this.elements.input.addEventListener('keydown', function(e) {
|
|
186
|
+
if (e.key === 'Enter' && !e.shiftKey) {
|
|
187
|
+
e.preventDefault();
|
|
188
|
+
self._handleSend();
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Auto-resize textarea
|
|
193
|
+
this.elements.input.addEventListener('input', function() {
|
|
194
|
+
this.style.height = 'auto';
|
|
195
|
+
this.style.height = (this.scrollHeight) + 'px';
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Close button
|
|
199
|
+
this.elements.btnClose.addEventListener('click', function() {
|
|
200
|
+
self.close();
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Disclaimer toggle
|
|
204
|
+
this.elements.btnDisclaimer.addEventListener('click', function() {
|
|
205
|
+
var disclaimer = self.elements.disclaimer;
|
|
206
|
+
disclaimer.style.display = disclaimer.style.display === 'none' ? 'block' : 'none';
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// New chat
|
|
210
|
+
this.elements.btnNewChat.addEventListener('click', function() {
|
|
211
|
+
if (confirm('Start a new conversation? This will clear the current chat.')) {
|
|
212
|
+
self.clearHistory();
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// Help
|
|
217
|
+
this.elements.btnHelp.addEventListener('click', function() {
|
|
218
|
+
alert('DelaChat Help\n\nType your question and press Enter or click Send.\n\nTips:\n- Ask specific questions\n- Provide context for better answers\n- Use "Regenerate" if you need a different response');
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Handle send message
|
|
224
|
+
*/
|
|
225
|
+
DelaChatInstance.prototype._handleSend = function() {
|
|
226
|
+
var message = this.elements.input.value.trim();
|
|
227
|
+
if (!message || this.state.isLoading) return;
|
|
228
|
+
|
|
229
|
+
this.sendMessage(message);
|
|
230
|
+
this.elements.input.value = '';
|
|
231
|
+
this.elements.input.style.height = 'auto';
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Load chat history from API
|
|
236
|
+
*/
|
|
237
|
+
DelaChatInstance.prototype._loadHistory = function() {
|
|
238
|
+
var self = this;
|
|
239
|
+
this._setLoading(true);
|
|
240
|
+
|
|
241
|
+
this._apiRequest('GET', '/delachat/history?limit=50&offset=0')
|
|
242
|
+
.then(function(data) {
|
|
243
|
+
self.state.messages = data.records || [];
|
|
244
|
+
self._renderMessages();
|
|
245
|
+
self._setLoading(false);
|
|
246
|
+
})
|
|
247
|
+
.catch(function(error) {
|
|
248
|
+
self._handleError(error);
|
|
249
|
+
self._setLoading(false);
|
|
250
|
+
});
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Send user message
|
|
255
|
+
*/
|
|
256
|
+
DelaChatInstance.prototype.sendMessage = function(message) {
|
|
257
|
+
var self = this;
|
|
258
|
+
this._setLoading(true);
|
|
259
|
+
this._hideWelcome();
|
|
260
|
+
|
|
261
|
+
// Add user message to UI immediately
|
|
262
|
+
var userMsg = {
|
|
263
|
+
historyId: 'temp-' + Date.now(),
|
|
264
|
+
message: message,
|
|
265
|
+
source: 0,
|
|
266
|
+
created: new Date().toISOString(),
|
|
267
|
+
userId: this.config.userName,
|
|
268
|
+
isUserMessage: true,
|
|
269
|
+
isAIMessage: false
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
this.state.messages.unshift(userMsg);
|
|
273
|
+
this._renderMessages();
|
|
274
|
+
|
|
275
|
+
// Send to API
|
|
276
|
+
this._apiRequest('POST', '/delachat/history', {
|
|
277
|
+
message: message,
|
|
278
|
+
source: 0,
|
|
279
|
+
productUid: this.config.productId
|
|
280
|
+
})
|
|
281
|
+
.then(function(data) {
|
|
282
|
+
// Replace temp message with real one
|
|
283
|
+
self.state.messages[0] = data.record;
|
|
284
|
+
self._renderMessages();
|
|
285
|
+
|
|
286
|
+
if (self.config.onMessageSent) {
|
|
287
|
+
self.config.onMessageSent.call(self, message);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Simulate AI response (in real app, this would come from AI service)
|
|
291
|
+
self._simulateAIResponse(message);
|
|
292
|
+
})
|
|
293
|
+
.catch(function(error) {
|
|
294
|
+
self._handleError(error);
|
|
295
|
+
self._setLoading(false);
|
|
296
|
+
});
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Simulate AI response (Replace with real AI integration)
|
|
301
|
+
*/
|
|
302
|
+
DelaChatInstance.prototype._simulateAIResponse = function(userMessage) {
|
|
303
|
+
var self = this;
|
|
304
|
+
|
|
305
|
+
// Simulate delay
|
|
306
|
+
setTimeout(function() {
|
|
307
|
+
var aiResponse = "I received your message: \"" + userMessage + "\". This is a simulated response. In production, this would call your AI service.";
|
|
308
|
+
|
|
309
|
+
self._apiRequest('POST', '/delachat/history', {
|
|
310
|
+
message: aiResponse,
|
|
311
|
+
source: 1,
|
|
312
|
+
productUid: self.config.productId
|
|
313
|
+
})
|
|
314
|
+
.then(function(data) {
|
|
315
|
+
self.state.messages.unshift(data.record);
|
|
316
|
+
self._renderMessages();
|
|
317
|
+
self._setLoading(false);
|
|
318
|
+
|
|
319
|
+
if (self.config.onMessageReceived) {
|
|
320
|
+
self.config.onMessageReceived.call(self, aiResponse);
|
|
321
|
+
}
|
|
322
|
+
})
|
|
323
|
+
.catch(function(error) {
|
|
324
|
+
self._handleError(error);
|
|
325
|
+
self._setLoading(false);
|
|
326
|
+
});
|
|
327
|
+
}, 1500);
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Render messages
|
|
332
|
+
*/
|
|
333
|
+
DelaChatInstance.prototype._renderMessages = function() {
|
|
334
|
+
var self = this;
|
|
335
|
+
var messagesHtml = this.state.messages.map(function(msg) {
|
|
336
|
+
return self._renderMessage(msg);
|
|
337
|
+
}).join('');
|
|
338
|
+
|
|
339
|
+
this.elements.messages.innerHTML = messagesHtml;
|
|
340
|
+
this._scrollToBottom();
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Render single message
|
|
345
|
+
*/
|
|
346
|
+
DelaChatInstance.prototype._renderMessage = function(msg) {
|
|
347
|
+
var isUser = msg.source === 0;
|
|
348
|
+
var avatarIcon = isUser ? '👤' : '🤖';
|
|
349
|
+
var messageClass = isUser ? 'delachat-message-user' : 'delachat-message-ai';
|
|
350
|
+
|
|
351
|
+
var actions = '';
|
|
352
|
+
if (!isUser) {
|
|
353
|
+
actions = `
|
|
354
|
+
<div class="delachat-message-actions">
|
|
355
|
+
<button onclick="DelaChat._copyMessage('${msg.historyId}')" class="delachat-btn-action" title="Copy">
|
|
356
|
+
📋 Copy
|
|
357
|
+
</button>
|
|
358
|
+
<button onclick="DelaChat._regenerate('${msg.historyId}')" class="delachat-btn-action" title="Regenerate">
|
|
359
|
+
🔄 Regenerate
|
|
360
|
+
</button>
|
|
361
|
+
</div>
|
|
362
|
+
`;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return `
|
|
366
|
+
<div class="delachat-message ${messageClass}" data-id="${msg.historyId}">
|
|
367
|
+
<div class="delachat-avatar">
|
|
368
|
+
<span>${avatarIcon}</span>
|
|
369
|
+
</div>
|
|
370
|
+
<div class="delachat-message-content">
|
|
371
|
+
<div class="delachat-message-bubble">
|
|
372
|
+
${this._escapeHtml(msg.message)}
|
|
373
|
+
</div>
|
|
374
|
+
${actions}
|
|
375
|
+
</div>
|
|
376
|
+
</div>
|
|
377
|
+
`;
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* API Request helper
|
|
382
|
+
*/
|
|
383
|
+
DelaChatInstance.prototype._apiRequest = function(method, endpoint, data) {
|
|
384
|
+
var self = this;
|
|
385
|
+
var url = this.config.apiUrl + endpoint;
|
|
386
|
+
|
|
387
|
+
return new Promise(function(resolve, reject) {
|
|
388
|
+
var xhr = new XMLHttpRequest();
|
|
389
|
+
xhr.open(method, url);
|
|
390
|
+
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
391
|
+
xhr.setRequestHeader('X-SessionUid', self.config.sessionUid);
|
|
392
|
+
xhr.setRequestHeader('X-Datasource', self.config.datasource);
|
|
393
|
+
xhr.setRequestHeader('X-ProductId', self.config.productId.toString());
|
|
394
|
+
xhr.setRequestHeader('X-RequestVerificationToken', self.config.token);
|
|
395
|
+
|
|
396
|
+
xhr.onload = function() {
|
|
397
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
398
|
+
try {
|
|
399
|
+
var response = JSON.parse(xhr.responseText);
|
|
400
|
+
resolve(response);
|
|
401
|
+
} catch (e) {
|
|
402
|
+
reject(new Error('Invalid JSON response'));
|
|
403
|
+
}
|
|
404
|
+
} else if (xhr.status === 401) {
|
|
405
|
+
reject(new Error('Unauthorized: Session expired or invalid token'));
|
|
406
|
+
} else {
|
|
407
|
+
reject(new Error('Request failed: ' + xhr.status));
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
xhr.onerror = function() {
|
|
412
|
+
reject(new Error('Network error'));
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
xhr.send(data ? JSON.stringify(data) : null);
|
|
416
|
+
});
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Set loading state
|
|
421
|
+
*/
|
|
422
|
+
DelaChatInstance.prototype._setLoading = function(isLoading) {
|
|
423
|
+
this.state.isLoading = isLoading;
|
|
424
|
+
this.elements.loading.style.display = isLoading ? 'flex' : 'none';
|
|
425
|
+
this.elements.input.disabled = isLoading;
|
|
426
|
+
this.elements.btnSend.disabled = isLoading;
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Handle error
|
|
431
|
+
*/
|
|
432
|
+
DelaChatInstance.prototype._handleError = function(error) {
|
|
433
|
+
this.state.error = error.message;
|
|
434
|
+
this.elements.error.textContent = error.message;
|
|
435
|
+
this.elements.error.style.display = 'block';
|
|
436
|
+
|
|
437
|
+
if (this.config.onError) {
|
|
438
|
+
this.config.onError.call(this, error);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Auto-hide error after 5 seconds
|
|
442
|
+
var self = this;
|
|
443
|
+
setTimeout(function() {
|
|
444
|
+
self.elements.error.style.display = 'none';
|
|
445
|
+
}, 5000);
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Hide welcome message
|
|
450
|
+
*/
|
|
451
|
+
DelaChatInstance.prototype._hideWelcome = function() {
|
|
452
|
+
if (this.elements.welcome) {
|
|
453
|
+
this.elements.welcome.style.display = 'none';
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Scroll to bottom
|
|
459
|
+
*/
|
|
460
|
+
DelaChatInstance.prototype._scrollToBottom = function() {
|
|
461
|
+
this.elements.messages.scrollTop = this.elements.messages.scrollHeight;
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Escape HTML
|
|
466
|
+
*/
|
|
467
|
+
DelaChatInstance.prototype._escapeHtml = function(text) {
|
|
468
|
+
var div = document.createElement('div');
|
|
469
|
+
div.textContent = text;
|
|
470
|
+
return div.innerHTML.replace(/\n/g, '<br>');
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Public API Methods
|
|
475
|
+
*/
|
|
476
|
+
|
|
477
|
+
DelaChatInstance.prototype.open = function() {
|
|
478
|
+
this.state.isOpen = true;
|
|
479
|
+
this.elements.window.style.display = 'flex';
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
DelaChatInstance.prototype.close = function() {
|
|
483
|
+
this.state.isOpen = false;
|
|
484
|
+
this.elements.window.style.display = 'none';
|
|
485
|
+
|
|
486
|
+
if (this.config.onClose) {
|
|
487
|
+
this.config.onClose.call(this);
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
DelaChatInstance.prototype.toggle = function() {
|
|
492
|
+
if (this.state.isOpen) {
|
|
493
|
+
this.close();
|
|
494
|
+
} else {
|
|
495
|
+
this.open();
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
DelaChatInstance.prototype.clearHistory = function() {
|
|
500
|
+
this.state.messages = [];
|
|
501
|
+
this._renderMessages();
|
|
502
|
+
this.elements.welcome.style.display = 'block';
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
DelaChatInstance.prototype.getMessages = function() {
|
|
506
|
+
return this.state.messages.slice();
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
DelaChatInstance.prototype.isOpen = function() {
|
|
510
|
+
return this.state.isOpen;
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
DelaChatInstance.prototype.getConfig = function() {
|
|
514
|
+
return Object.assign({}, this.config);
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
DelaChatInstance.prototype.updateConfig = function(newConfig) {
|
|
518
|
+
Object.assign(this.config, newConfig);
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
DelaChatInstance.prototype.destroy = function() {
|
|
522
|
+
this.container.innerHTML = '';
|
|
523
|
+
this.state = null;
|
|
524
|
+
this.config = null;
|
|
525
|
+
this.elements = null;
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Global DelaChat object
|
|
530
|
+
*/
|
|
531
|
+
var DelaChat = {
|
|
532
|
+
version: VERSION,
|
|
533
|
+
instances: [],
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Create new chat instance
|
|
537
|
+
*/
|
|
538
|
+
create: function(selector, config) {
|
|
539
|
+
var container = typeof selector === 'string'
|
|
540
|
+
? document.querySelector(selector)
|
|
541
|
+
: selector;
|
|
542
|
+
|
|
543
|
+
if (!container) {
|
|
544
|
+
throw new Error('Container not found: ' + selector);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
var instance = new DelaChatInstance(container, config);
|
|
548
|
+
this.instances.push(instance);
|
|
549
|
+
return instance;
|
|
550
|
+
},
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Helper methods for global actions
|
|
554
|
+
*/
|
|
555
|
+
_copyMessage: function(messageId) {
|
|
556
|
+
// Find message in all instances
|
|
557
|
+
for (var i = 0; i < this.instances.length; i++) {
|
|
558
|
+
var msg = this.instances[i].state.messages.find(function(m) {
|
|
559
|
+
return m.historyId === messageId;
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
if (msg) {
|
|
563
|
+
if (navigator.clipboard) {
|
|
564
|
+
navigator.clipboard.writeText(msg.message);
|
|
565
|
+
alert('Message copied to clipboard');
|
|
566
|
+
}
|
|
567
|
+
break;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
},
|
|
571
|
+
|
|
572
|
+
_regenerate: function(messageId) {
|
|
573
|
+
alert('Regenerate feature - implement AI regeneration here');
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
// Export to global scope
|
|
578
|
+
window.DelaChat = DelaChat;
|
|
579
|
+
|
|
580
|
+
})(window);
|