@blumessage/react-chat 1.0.4 → 1.0.6

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.
@@ -57,6 +57,15 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
57
57
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
58
58
  import React, { useState, useEffect, useRef } from "react";
59
59
  import { MessageCircle, AlertTriangle, Loader2, Send, X, Maximize, Minimize2, Bot, MessageSquare, Phone, Mail, Headphones, Users, User, Heart, Star, Zap } from "lucide-react";
60
+ // Custom CSS animations that don't depend on Tailwind
61
+ var customStyles = "\n @keyframes bounce {\n 0%, 100% {\n transform: translateY(0);\n }\n 50% {\n transform: translateY(-25%);\n }\n }\n \n @keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }\n \n .blumessage-animate-bounce {\n animation: bounce 1s infinite;\n }\n \n .blumessage-animate-spin {\n animation: spin 1s linear infinite;\n }\n";
62
+ // Inject custom styles
63
+ if (typeof document !== 'undefined' && !document.getElementById('blumessage-styles')) {
64
+ var style = document.createElement('style');
65
+ style.id = 'blumessage-styles';
66
+ style.textContent = customStyles;
67
+ document.head.appendChild(style);
68
+ }
60
69
  // Session storage key for conversation ID
61
70
  var CONVERSATION_ID_KEY = 'blumessage_conversation_id';
62
71
  // Utility functions for storage
@@ -111,6 +120,7 @@ export var BlumessageChat = function (_a) {
111
120
  var _z = useState(false), isLoading = _z[0], setIsLoading = _z[1];
112
121
  var _0 = useState(false), isMaximized = _0[0], setIsMaximized = _0[1];
113
122
  var messagesEndRef = useRef(null);
123
+ var isInitialLoad = useRef(true);
114
124
  // Helper function to get dimensions based on size
115
125
  var getDimensions = function () {
116
126
  // If custom width/height are provided, use them
@@ -118,15 +128,19 @@ export var BlumessageChat = function (_a) {
118
128
  return { width: width, height: height };
119
129
  }
120
130
  // Otherwise, use size-based dimensions
131
+ var dimensions;
121
132
  switch (size) {
122
133
  case 'small':
123
- return { width: '320px', height: '400px' };
134
+ dimensions = { width: '320px', height: '400px' };
135
+ break;
124
136
  case 'large':
125
- return { width: '480px', height: '600px' };
137
+ dimensions = { width: '680px', height: '800px' };
138
+ break;
126
139
  case 'medium':
127
140
  default:
128
- return { width: '380px', height: '500px' };
141
+ dimensions = { width: '480px', height: '600px' };
129
142
  }
143
+ return dimensions;
130
144
  };
131
145
  var _1 = getDimensions(), actualWidth = _1.width, actualHeight = _1.height;
132
146
  // Function to update conversation ID and notify parent
@@ -153,7 +167,7 @@ export var BlumessageChat = function (_a) {
153
167
  return [4 /*yield*/, fetch("https://api.blumessage.com/api/v1/conversations/session/".concat(convId), {
154
168
  method: 'GET',
155
169
  headers: {
156
- 'Authorization': apiKey,
170
+ 'Authorization': "Bearer ".concat(apiKey),
157
171
  },
158
172
  })];
159
173
  case 1:
@@ -198,11 +212,11 @@ export var BlumessageChat = function (_a) {
198
212
  }
199
213
  // Validate API key with Blumessage API
200
214
  var validateApiKey = function () { return __awaiter(void 0, void 0, void 0, function () {
201
- var response, historyMessages, errorMessage, err_1, errorMessage;
215
+ var response, errorMessage, err_1, errorMessage;
202
216
  return __generator(this, function (_a) {
203
217
  switch (_a.label) {
204
218
  case 0:
205
- _a.trys.push([0, 9, , 10]);
219
+ _a.trys.push([0, 2, , 3]);
206
220
  setIsInitialized(false);
207
221
  setError(null);
208
222
  console.log("Initializing Blumessage chat...");
@@ -215,43 +229,22 @@ export var BlumessageChat = function (_a) {
215
229
  })];
216
230
  case 1:
217
231
  response = _a.sent();
218
- if (!response.ok) return [3 /*break*/, 7];
219
- console.log("Blumessage chat initialized successfully");
220
- setIsInitialized(true);
221
- setError(null);
222
- if (!(initialMessages.length > 0 && conversationId)) return [3 /*break*/, 2];
223
- // Warn if both are provided - initialMessages takes precedence
224
- console.warn('Both initialMessages and conversationId provided. Using initialMessages and ignoring stored conversation.');
225
- setMessages(initialMessages);
226
- return [3 /*break*/, 6];
227
- case 2:
228
- if (!(initialMessages.length > 0)) return [3 /*break*/, 3];
229
- // Use provided initial messages
230
- setMessages(initialMessages);
231
- return [3 /*break*/, 6];
232
- case 3:
233
- if (!conversationId) return [3 /*break*/, 5];
234
- return [4 /*yield*/, fetchConversationHistory(conversationId)];
235
- case 4:
236
- historyMessages = _a.sent();
237
- setMessages(historyMessages); // Will be empty array if fetch failed
238
- return [3 /*break*/, 6];
239
- case 5:
240
- // No conversation ID and no initial messages - start with empty array
241
- setMessages([]);
242
- _a.label = 6;
243
- case 6: return [3 /*break*/, 8];
244
- case 7:
245
- console.error("Blumessage chat initialization failed:", response.status, response.statusText);
246
- errorMessage = "Unable to connect - invalid API key";
247
- setError(errorMessage);
248
- setIsInitialized(false);
249
- if (onError) {
250
- onError(errorMessage, "api_key_validation");
232
+ if (response.ok) {
233
+ console.log("Blumessage chat initialized successfully");
234
+ setIsInitialized(true);
235
+ setError(null);
236
+ }
237
+ else {
238
+ console.error("Blumessage chat initialization failed:", response.status, response.statusText);
239
+ errorMessage = "Unable to connect - invalid API key";
240
+ setError(errorMessage);
241
+ setIsInitialized(false);
242
+ if (onError) {
243
+ onError(errorMessage, "api_key_validation");
244
+ }
251
245
  }
252
- _a.label = 8;
253
- case 8: return [3 /*break*/, 10];
254
- case 9:
246
+ return [3 /*break*/, 3];
247
+ case 2:
255
248
  err_1 = _a.sent();
256
249
  console.error("Blumessage chat initialization error:", err_1);
257
250
  errorMessage = "Unable to connect - network error";
@@ -260,13 +253,52 @@ export var BlumessageChat = function (_a) {
260
253
  if (onError) {
261
254
  onError(errorMessage, "network_error");
262
255
  }
263
- return [3 /*break*/, 10];
264
- case 10: return [2 /*return*/];
256
+ return [3 /*break*/, 3];
257
+ case 3: return [2 /*return*/];
265
258
  }
266
259
  });
267
260
  }); };
268
261
  validateApiKey();
269
- }, [apiKey, conversationId]);
262
+ }, [apiKey]);
263
+ // Handle initial message loading (only runs once on mount)
264
+ useEffect(function () {
265
+ var loadInitialMessages = function () { return __awaiter(void 0, void 0, void 0, function () {
266
+ var historyMessages;
267
+ return __generator(this, function (_a) {
268
+ switch (_a.label) {
269
+ case 0:
270
+ if (!isInitialLoad.current) return [3 /*break*/, 5];
271
+ isInitialLoad.current = false;
272
+ if (!(initialMessages.length > 0 && conversationId)) return [3 /*break*/, 1];
273
+ // Warn if both are provided - initialMessages takes precedence
274
+ console.warn('Both initialMessages and conversationId provided. Using initialMessages and ignoring stored conversation.');
275
+ setMessages(initialMessages);
276
+ return [3 /*break*/, 5];
277
+ case 1:
278
+ if (!(initialMessages.length > 0)) return [3 /*break*/, 2];
279
+ // Use provided initial messages
280
+ setMessages(initialMessages);
281
+ return [3 /*break*/, 5];
282
+ case 2:
283
+ if (!conversationId) return [3 /*break*/, 4];
284
+ return [4 /*yield*/, fetchConversationHistory(conversationId)];
285
+ case 3:
286
+ historyMessages = _a.sent();
287
+ setMessages(historyMessages); // Will be empty array if fetch failed
288
+ return [3 /*break*/, 5];
289
+ case 4:
290
+ // No conversation ID and no initial messages - start with empty array
291
+ setMessages([]);
292
+ _a.label = 5;
293
+ case 5: return [2 /*return*/];
294
+ }
295
+ });
296
+ }); };
297
+ // Only load initial messages after API key is validated
298
+ if (isInitialized) {
299
+ loadInitialMessages();
300
+ }
301
+ }, [isInitialized]);
270
302
  var handleSendMessage = function () { return __awaiter(void 0, void 0, void 0, function () {
271
303
  var userMessage, currentInput, requestBody, response, apiResponse, assistantMessages, latestAssistantMessage, assistantResponse_1, errorMessage_1, error_2, errorMessage_2;
272
304
  return __generator(this, function (_a) {
@@ -560,11 +592,11 @@ export var BlumessageChat = function (_a) {
560
592
  ? 'bg-gray-700 text-gray-100 border border-gray-600 shadow-sm'
561
593
  : 'bg-white text-gray-800 border border-gray-200 shadow-sm'), style: message.role === 'user' ? { backgroundImage: primaryColor } : {}, children: message.content }) }, message.id)); }), isLoading && (_jsx("div", { className: "flex justify-start", children: _jsx("div", { className: "px-4 py-3 rounded-2xl max-w-[80%] text-sm leading-6 shadow-sm ".concat(theme === 'dark'
562
594
  ? 'bg-gray-700 text-gray-100 border border-gray-600'
563
- : 'bg-white text-gray-800 border border-gray-200'), children: _jsxs("div", { className: "flex space-x-1", children: [_jsx("div", { className: "w-2 h-2 rounded-full animate-bounce ".concat(theme === 'dark' ? 'bg-gray-400' : 'bg-gray-400'), style: { animationDelay: '0ms' } }), _jsx("div", { className: "w-2 h-2 rounded-full animate-bounce ".concat(theme === 'dark' ? 'bg-gray-400' : 'bg-gray-400'), style: { animationDelay: '150ms' } }), _jsx("div", { className: "w-2 h-2 rounded-full animate-bounce ".concat(theme === 'dark' ? 'bg-gray-400' : 'bg-gray-400'), style: { animationDelay: '300ms' } })] }) }) })), messages.length === 0 && !isLoading && (_jsx("div", { className: "text-center text-sm py-8 ".concat(theme === 'dark' ? 'text-gray-400' : 'text-gray-500'), children: "No messages yet. Start a conversation!" })), _jsx("div", { ref: messagesEndRef })] }), _jsx("div", { className: "px-6 py-4 border-t ".concat(theme === 'dark'
595
+ : 'bg-white text-gray-800 border border-gray-200'), children: _jsxs("div", { className: "flex space-x-1", children: [_jsx("div", { className: "w-2 h-2 rounded-full blumessage-animate-bounce ".concat(theme === 'dark' ? 'bg-gray-400' : 'bg-gray-400'), style: { animationDelay: '0ms' } }), _jsx("div", { className: "w-2 h-2 rounded-full blumessage-animate-bounce ".concat(theme === 'dark' ? 'bg-gray-400' : 'bg-gray-400'), style: { animationDelay: '150ms' } }), _jsx("div", { className: "w-2 h-2 rounded-full blumessage-animate-bounce ".concat(theme === 'dark' ? 'bg-gray-400' : 'bg-gray-400'), style: { animationDelay: '300ms' } })] }) }) })), messages.length === 0 && !isLoading && (_jsx("div", { className: "text-center text-sm py-8 ".concat(theme === 'dark' ? 'text-gray-400' : 'text-gray-500'), children: "No messages yet. Start a conversation!" })), _jsx("div", { ref: messagesEndRef })] }), _jsx("div", { className: "px-6 py-4 border-t ".concat(theme === 'dark'
564
596
  ? 'bg-gray-900 border-gray-700'
565
597
  : 'bg-white border-gray-100'), children: _jsxs("div", { className: "flex items-center rounded-full px-4 py-3 border ".concat(theme === 'dark'
566
598
  ? 'bg-gray-800 border-gray-600'
567
- : 'bg-gray-50 border-gray-200'), children: [_jsx("input", { className: "flex-1 border-none bg-transparent outline-none text-sm font-inherit ".concat(theme === 'dark' ? 'text-gray-100' : 'text-gray-700'), type: "text", placeholder: placeholder, value: inputValue, onChange: function (e) { return setInputValue(e.target.value); }, onKeyPress: handleKeyPress }), _jsx("button", { className: "w-8 h-8 rounded-full border-none flex items-center justify-center cursor-pointer ml-2 text-white transition-all disabled:opacity-50 disabled:cursor-not-allowed", style: { backgroundImage: primaryColor }, onClick: handleSendMessage, disabled: !inputValue.trim() || isLoading, children: isLoading ? (_jsx(Loader2, { className: "w-4 h-4 animate-spin" })) : (_jsx(Send, { className: "w-4 h-4" })) })] }) })] }));
599
+ : 'bg-gray-50 border-gray-200'), children: [_jsx("input", { className: "flex-1 border-none bg-transparent outline-none text-sm font-inherit ".concat(theme === 'dark' ? 'text-gray-100' : 'text-gray-700'), type: "text", placeholder: placeholder, value: inputValue, onChange: function (e) { return setInputValue(e.target.value); }, onKeyPress: handleKeyPress }), _jsx("button", { className: "w-8 h-8 rounded-full border-none flex items-center justify-center cursor-pointer ml-2 text-white transition-all disabled:opacity-50 disabled:cursor-not-allowed", style: { backgroundImage: primaryColor }, onClick: handleSendMessage, disabled: !inputValue.trim() || isLoading, children: isLoading ? (_jsx(Loader2, { className: "w-4 h-4 blumessage-animate-spin" })) : (_jsx(Send, { className: "w-4 h-4" })) })] }) })] }));
568
600
  if (floating) {
569
601
  return (_jsx("div", { style: getChatPositionStyles(), children: chatContent }));
570
602
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumessage/react-chat",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "A React TypeScript chat widget component with floating button, theming, and Blumessage API integration",
5
5
  "license": "MIT",
6
6
  "author": "Blumessage <contact@blumessage.com>",