@uselingu/react-native-sdk 0.1.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/README.md +279 -0
- package/lib/commonjs/components/LinguChat.js +283 -0
- package/lib/commonjs/components/LinguChat.js.map +1 -0
- package/lib/commonjs/components/LinguWebView.js +203 -0
- package/lib/commonjs/components/LinguWebView.js.map +1 -0
- package/lib/commonjs/components/MessageBubble.js +91 -0
- package/lib/commonjs/components/MessageBubble.js.map +1 -0
- package/lib/commonjs/components/NativeChatUI.js +192 -0
- package/lib/commonjs/components/NativeChatUI.js.map +1 -0
- package/lib/commonjs/components/TypingIndicator.js +92 -0
- package/lib/commonjs/components/TypingIndicator.js.map +1 -0
- package/lib/commonjs/context/LinguProvider.js +47 -0
- package/lib/commonjs/context/LinguProvider.js.map +1 -0
- package/lib/commonjs/context/index.js +17 -0
- package/lib/commonjs/context/index.js.map +1 -0
- package/lib/commonjs/hooks/useLinguChat.js +295 -0
- package/lib/commonjs/hooks/useLinguChat.js.map +1 -0
- package/lib/commonjs/index.js +129 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/services/LinguAPI.js +196 -0
- package/lib/commonjs/services/LinguAPI.js.map +1 -0
- package/lib/commonjs/services/SessionManager.js +131 -0
- package/lib/commonjs/services/SessionManager.js.map +1 -0
- package/lib/commonjs/services/StorageManager.js +116 -0
- package/lib/commonjs/services/StorageManager.js.map +1 -0
- package/lib/commonjs/theme/ThemeProvider.js +49 -0
- package/lib/commonjs/theme/ThemeProvider.js.map +1 -0
- package/lib/commonjs/theme/index.js +28 -0
- package/lib/commonjs/theme/index.js.map +1 -0
- package/lib/commonjs/theme/theme.js +150 -0
- package/lib/commonjs/theme/theme.js.map +1 -0
- package/lib/commonjs/types/index.js +2 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/utils/animations.js +118 -0
- package/lib/commonjs/utils/animations.js.map +1 -0
- package/lib/commonjs/utils/formatters.js +89 -0
- package/lib/commonjs/utils/formatters.js.map +1 -0
- package/lib/commonjs/utils/index.js +28 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/module/components/LinguChat.js +277 -0
- package/lib/module/components/LinguChat.js.map +1 -0
- package/lib/module/components/LinguWebView.js +195 -0
- package/lib/module/components/LinguWebView.js.map +1 -0
- package/lib/module/components/MessageBubble.js +83 -0
- package/lib/module/components/MessageBubble.js.map +1 -0
- package/lib/module/components/NativeChatUI.js +184 -0
- package/lib/module/components/NativeChatUI.js.map +1 -0
- package/lib/module/components/TypingIndicator.js +84 -0
- package/lib/module/components/TypingIndicator.js.map +1 -0
- package/lib/module/context/LinguProvider.js +38 -0
- package/lib/module/context/LinguProvider.js.map +1 -0
- package/lib/module/context/index.js +6 -0
- package/lib/module/context/index.js.map +1 -0
- package/lib/module/hooks/useLinguChat.js +288 -0
- package/lib/module/hooks/useLinguChat.js.map +1 -0
- package/lib/module/index.js +30 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/services/LinguAPI.js +190 -0
- package/lib/module/services/LinguAPI.js.map +1 -0
- package/lib/module/services/SessionManager.js +124 -0
- package/lib/module/services/SessionManager.js.map +1 -0
- package/lib/module/services/StorageManager.js +108 -0
- package/lib/module/services/StorageManager.js.map +1 -0
- package/lib/module/theme/ThemeProvider.js +40 -0
- package/lib/module/theme/ThemeProvider.js.map +1 -0
- package/lib/module/theme/index.js +7 -0
- package/lib/module/theme/index.js.map +1 -0
- package/lib/module/theme/theme.js +142 -0
- package/lib/module/theme/theme.js.map +1 -0
- package/lib/module/types/index.js +2 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/utils/animations.js +106 -0
- package/lib/module/utils/animations.js.map +1 -0
- package/lib/module/utils/formatters.js +78 -0
- package/lib/module/utils/formatters.js.map +1 -0
- package/lib/module/utils/index.js +7 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/typescript/components/LinguChat.d.ts +18 -0
- package/lib/typescript/components/LinguChat.d.ts.map +1 -0
- package/lib/typescript/components/LinguWebView.d.ts +16 -0
- package/lib/typescript/components/LinguWebView.d.ts.map +1 -0
- package/lib/typescript/components/MessageBubble.d.ts +13 -0
- package/lib/typescript/components/MessageBubble.d.ts.map +1 -0
- package/lib/typescript/components/NativeChatUI.d.ts +16 -0
- package/lib/typescript/components/NativeChatUI.d.ts.map +1 -0
- package/lib/typescript/components/TypingIndicator.d.ts +7 -0
- package/lib/typescript/components/TypingIndicator.d.ts.map +1 -0
- package/lib/typescript/context/LinguProvider.d.ts +32 -0
- package/lib/typescript/context/LinguProvider.d.ts.map +1 -0
- package/lib/typescript/context/index.d.ts +5 -0
- package/lib/typescript/context/index.d.ts.map +1 -0
- package/lib/typescript/hooks/useLinguChat.d.ts +18 -0
- package/lib/typescript/hooks/useLinguChat.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +19 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/services/LinguAPI.d.ts +39 -0
- package/lib/typescript/services/LinguAPI.d.ts.map +1 -0
- package/lib/typescript/services/SessionManager.d.ts +46 -0
- package/lib/typescript/services/SessionManager.d.ts.map +1 -0
- package/lib/typescript/services/StorageManager.d.ts +36 -0
- package/lib/typescript/services/StorageManager.d.ts.map +1 -0
- package/lib/typescript/theme/ThemeProvider.d.ts +23 -0
- package/lib/typescript/theme/ThemeProvider.d.ts.map +1 -0
- package/lib/typescript/theme/index.d.ts +6 -0
- package/lib/typescript/theme/index.d.ts.map +1 -0
- package/lib/typescript/theme/theme.d.ts +130 -0
- package/lib/typescript/theme/theme.d.ts.map +1 -0
- package/lib/typescript/types/index.d.ts +50 -0
- package/lib/typescript/types/index.d.ts.map +1 -0
- package/lib/typescript/utils/animations.d.ts +34 -0
- package/lib/typescript/utils/animations.d.ts.map +1 -0
- package/lib/typescript/utils/formatters.d.ts +25 -0
- package/lib/typescript/utils/formatters.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +6 -0
- package/lib/typescript/utils/index.d.ts.map +1 -0
- package/package.json +98 -0
- package/src/components/LinguChat.tsx +309 -0
- package/src/components/LinguWebView.tsx +216 -0
- package/src/components/MessageBubble.tsx +120 -0
- package/src/components/NativeChatUI.tsx +247 -0
- package/src/components/TypingIndicator.tsx +84 -0
- package/src/context/LinguProvider.tsx +53 -0
- package/src/context/index.ts +5 -0
- package/src/hooks/useLinguChat.ts +314 -0
- package/src/index.ts +43 -0
- package/src/services/LinguAPI.ts +214 -0
- package/src/services/SessionManager.ts +131 -0
- package/src/services/StorageManager.ts +111 -0
- package/src/theme/ThemeProvider.tsx +58 -0
- package/src/theme/index.ts +6 -0
- package/src/theme/theme.ts +254 -0
- package/src/types/index.ts +59 -0
- package/src/utils/animations.ts +141 -0
- package/src/utils/formatters.ts +80 -0
- package/src/utils/index.ts +6 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.LinguWebView = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactNativeWebview = require("react-native-webview");
|
|
9
|
+
var _reactNative = require("react-native");
|
|
10
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
11
|
+
/**
|
|
12
|
+
* LinguWebView Component
|
|
13
|
+
* Wraps the existing web widget in a WebView with native bridge
|
|
14
|
+
* Now with comprehensive logging and message display
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const LOG_PREFIX = '[LinguWebView]';
|
|
18
|
+
const LinguWebView = ({
|
|
19
|
+
config,
|
|
20
|
+
messages,
|
|
21
|
+
onSendMessage,
|
|
22
|
+
onClose
|
|
23
|
+
}) => {
|
|
24
|
+
const webViewRef = (0, _react.useRef)(null);
|
|
25
|
+
console.log(`${LOG_PREFIX} Rendering with ${messages.length} messages`);
|
|
26
|
+
|
|
27
|
+
// Inject messages into WebView when they change
|
|
28
|
+
(0, _react.useEffect)(() => {
|
|
29
|
+
if (webViewRef.current && messages.length > 0) {
|
|
30
|
+
console.log(`${LOG_PREFIX} Injecting ${messages.length} messages into WebView`);
|
|
31
|
+
const script = `
|
|
32
|
+
(function() {
|
|
33
|
+
const messagesContainer = document.getElementById('messages');
|
|
34
|
+
if (messagesContainer) {
|
|
35
|
+
messagesContainer.innerHTML = ${JSON.stringify(messages.map(msg => `
|
|
36
|
+
<div style="margin-bottom: 12px; display: flex; justify-content: ${msg.sender === 'user' ? 'flex-end' : 'flex-start'};">
|
|
37
|
+
<div style="
|
|
38
|
+
max-width: 70%;
|
|
39
|
+
padding: 12px;
|
|
40
|
+
border-radius: 12px;
|
|
41
|
+
background: ${msg.sender === 'user' ? '#4ade80' : '#f3f4f6'};
|
|
42
|
+
color: ${msg.sender === 'user' ? 'white' : 'black'};
|
|
43
|
+
">
|
|
44
|
+
${msg.text}
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
`).join(''))};
|
|
48
|
+
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
|
49
|
+
console.log('Messages updated in WebView');
|
|
50
|
+
}
|
|
51
|
+
})();
|
|
52
|
+
true;
|
|
53
|
+
`;
|
|
54
|
+
webViewRef.current.injectJavaScript(script);
|
|
55
|
+
}
|
|
56
|
+
}, [messages]);
|
|
57
|
+
|
|
58
|
+
// Handle messages from WebView
|
|
59
|
+
const handleMessage = event => {
|
|
60
|
+
try {
|
|
61
|
+
const data = JSON.parse(event.nativeEvent.data);
|
|
62
|
+
console.log(`${LOG_PREFIX} Received message from WebView:`, data.type);
|
|
63
|
+
switch (data.type) {
|
|
64
|
+
case 'SEND_MESSAGE':
|
|
65
|
+
console.log(`${LOG_PREFIX} User sent message:`, data.payload.message);
|
|
66
|
+
onSendMessage(data.payload.message);
|
|
67
|
+
break;
|
|
68
|
+
case 'CLOSE_CHAT':
|
|
69
|
+
console.log(`${LOG_PREFIX} User closed chat`);
|
|
70
|
+
onClose();
|
|
71
|
+
break;
|
|
72
|
+
case 'WEBVIEW_LOG':
|
|
73
|
+
console.log(`${LOG_PREFIX} WebView log:`, data.payload);
|
|
74
|
+
break;
|
|
75
|
+
default:
|
|
76
|
+
console.log(`${LOG_PREFIX} Unknown message type:`, data.type);
|
|
77
|
+
}
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error(`${LOG_PREFIX} Failed to parse message:`, error);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Generate HTML for the widget
|
|
84
|
+
const generateHTML = () => {
|
|
85
|
+
const configJSON = JSON.stringify(config || {});
|
|
86
|
+
console.log(`${LOG_PREFIX} Generating HTML with config:`, config === null || config === void 0 ? void 0 : config.brandName);
|
|
87
|
+
return `
|
|
88
|
+
<!DOCTYPE html>
|
|
89
|
+
<html>
|
|
90
|
+
<head>
|
|
91
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
|
|
92
|
+
<style>
|
|
93
|
+
* {
|
|
94
|
+
margin: 0;
|
|
95
|
+
padding: 0;
|
|
96
|
+
box-sizing: border-box;
|
|
97
|
+
}
|
|
98
|
+
body {
|
|
99
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
}
|
|
102
|
+
#widget-container {
|
|
103
|
+
width: 100vw;
|
|
104
|
+
height: 100vh;
|
|
105
|
+
display: flex;
|
|
106
|
+
flex-direction: column;
|
|
107
|
+
}
|
|
108
|
+
#messages {
|
|
109
|
+
flex: 1;
|
|
110
|
+
overflow-y: auto;
|
|
111
|
+
padding: 16px;
|
|
112
|
+
background: white;
|
|
113
|
+
}
|
|
114
|
+
#input-container {
|
|
115
|
+
padding: 16px;
|
|
116
|
+
border-top: 1px solid #e5e7eb;
|
|
117
|
+
background: white;
|
|
118
|
+
}
|
|
119
|
+
#message-input {
|
|
120
|
+
width: 100%;
|
|
121
|
+
padding: 12px;
|
|
122
|
+
border: 1px solid #d1d5db;
|
|
123
|
+
border-radius: 8px;
|
|
124
|
+
font-size: 16px;
|
|
125
|
+
}
|
|
126
|
+
</style>
|
|
127
|
+
</head>
|
|
128
|
+
<body>
|
|
129
|
+
<div id="widget-container">
|
|
130
|
+
<div id="messages">
|
|
131
|
+
<div style="text-align: center; color: #9ca3af; padding: 20px;">
|
|
132
|
+
${(config === null || config === void 0 ? void 0 : config.greetingMessage) || 'Start chatting...'}
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
<div id="input-container">
|
|
136
|
+
<input
|
|
137
|
+
type="text"
|
|
138
|
+
id="message-input"
|
|
139
|
+
placeholder="Type a message..."
|
|
140
|
+
/>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
<script>
|
|
145
|
+
console.log('WebView initialized');
|
|
146
|
+
|
|
147
|
+
// Configuration from native
|
|
148
|
+
window.linguConfig = ${configJSON};
|
|
149
|
+
|
|
150
|
+
// Bridge to React Native
|
|
151
|
+
window.sendToNative = function(type, payload) {
|
|
152
|
+
console.log('Sending to native:', type, payload);
|
|
153
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
154
|
+
type: type,
|
|
155
|
+
payload: payload
|
|
156
|
+
}));
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// Log to native
|
|
160
|
+
window.logToNative = function(message) {
|
|
161
|
+
window.sendToNative('WEBVIEW_LOG', message);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Handle input
|
|
165
|
+
const input = document.getElementById('message-input');
|
|
166
|
+
input.addEventListener('keypress', function(e) {
|
|
167
|
+
if (e.key === 'Enter' && input.value.trim()) {
|
|
168
|
+
console.log('User pressed enter:', input.value);
|
|
169
|
+
window.sendToNative('SEND_MESSAGE', { message: input.value });
|
|
170
|
+
input.value = '';
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
console.log('Event listeners attached');
|
|
175
|
+
window.logToNative('WebView ready');
|
|
176
|
+
</script>
|
|
177
|
+
</body>
|
|
178
|
+
</html>
|
|
179
|
+
`;
|
|
180
|
+
};
|
|
181
|
+
return /*#__PURE__*/_react.default.createElement(_reactNativeWebview.WebView, {
|
|
182
|
+
ref: webViewRef,
|
|
183
|
+
source: {
|
|
184
|
+
html: generateHTML()
|
|
185
|
+
},
|
|
186
|
+
style: styles.webview,
|
|
187
|
+
onMessage: handleMessage,
|
|
188
|
+
javaScriptEnabled: true,
|
|
189
|
+
domStorageEnabled: true,
|
|
190
|
+
startInLoadingState: true,
|
|
191
|
+
scalesPageToFit: true,
|
|
192
|
+
onLoad: () => console.log(`${LOG_PREFIX} WebView loaded`),
|
|
193
|
+
onError: error => console.error(`${LOG_PREFIX} WebView error:`, error)
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
exports.LinguWebView = LinguWebView;
|
|
197
|
+
const styles = _reactNative.StyleSheet.create({
|
|
198
|
+
webview: {
|
|
199
|
+
flex: 1,
|
|
200
|
+
backgroundColor: 'white'
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
//# sourceMappingURL=LinguWebView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNativeWebview","_reactNative","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","LOG_PREFIX","LinguWebView","config","messages","onSendMessage","onClose","webViewRef","useRef","console","log","length","useEffect","current","script","JSON","stringify","map","msg","sender","text","join","injectJavaScript","handleMessage","event","data","parse","nativeEvent","type","payload","message","error","generateHTML","configJSON","brandName","greetingMessage","createElement","WebView","ref","source","html","style","styles","webview","onMessage","javaScriptEnabled","domStorageEnabled","startInLoadingState","scalesPageToFit","onLoad","onError","exports","StyleSheet","create","flex","backgroundColor"],"sources":["LinguWebView.tsx"],"sourcesContent":["/**\n * LinguWebView Component\n * Wraps the existing web widget in a WebView with native bridge\n * Now with comprehensive logging and message display\n */\n\nimport React, { useRef, useEffect } from 'react';\nimport { WebView, WebViewMessageEvent } from 'react-native-webview';\nimport { StyleSheet } from 'react-native';\nimport type { Message, WidgetConfig } from '../types';\n\nconst LOG_PREFIX = '[LinguWebView]';\n\ninterface LinguWebViewProps {\n config: WidgetConfig | null;\n messages: Message[];\n onSendMessage: (message: string) => void;\n onClose: () => void;\n}\n\nexport const LinguWebView: React.FC<LinguWebViewProps> = ({\n config,\n messages,\n onSendMessage,\n onClose,\n}) => {\n const webViewRef = useRef<WebView>(null);\n\n console.log(`${LOG_PREFIX} Rendering with ${messages.length} messages`);\n\n // Inject messages into WebView when they change\n useEffect(() => {\n if (webViewRef.current && messages.length > 0) {\n console.log(`${LOG_PREFIX} Injecting ${messages.length} messages into WebView`);\n const script = `\n (function() {\n const messagesContainer = document.getElementById('messages');\n if (messagesContainer) {\n messagesContainer.innerHTML = ${JSON.stringify(\n messages\n .map(\n (msg) => `\n <div style=\"margin-bottom: 12px; display: flex; justify-content: ${msg.sender === 'user' ? 'flex-end' : 'flex-start'\n };\">\n <div style=\"\n max-width: 70%;\n padding: 12px;\n border-radius: 12px;\n background: ${msg.sender === 'user' ? '#4ade80' : '#f3f4f6'};\n color: ${msg.sender === 'user' ? 'white' : 'black'};\n \">\n ${msg.text}\n </div>\n </div>\n `\n )\n .join('')\n )};\n messagesContainer.scrollTop = messagesContainer.scrollHeight;\n console.log('Messages updated in WebView');\n }\n })();\n true;\n `;\n webViewRef.current.injectJavaScript(script);\n }\n }, [messages]);\n\n // Handle messages from WebView\n const handleMessage = (event: WebViewMessageEvent) => {\n try {\n const data = JSON.parse(event.nativeEvent.data);\n console.log(`${LOG_PREFIX} Received message from WebView:`, data.type);\n\n switch (data.type) {\n case 'SEND_MESSAGE':\n console.log(`${LOG_PREFIX} User sent message:`, data.payload.message);\n onSendMessage(data.payload.message);\n break;\n case 'CLOSE_CHAT':\n console.log(`${LOG_PREFIX} User closed chat`);\n onClose();\n break;\n case 'WEBVIEW_LOG':\n console.log(`${LOG_PREFIX} WebView log:`, data.payload);\n break;\n default:\n console.log(`${LOG_PREFIX} Unknown message type:`, data.type);\n }\n } catch (error) {\n console.error(`${LOG_PREFIX} Failed to parse message:`, error);\n }\n };\n\n // Generate HTML for the widget\n const generateHTML = () => {\n const configJSON = JSON.stringify(config || {});\n console.log(`${LOG_PREFIX} Generating HTML with config:`, config?.brandName);\n\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0\">\n <style>\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n overflow: hidden;\n }\n #widget-container {\n width: 100vw;\n height: 100vh;\n display: flex;\n flex-direction: column;\n }\n #messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n background: white;\n }\n #input-container {\n padding: 16px;\n border-top: 1px solid #e5e7eb;\n background: white;\n }\n #message-input {\n width: 100%;\n padding: 12px;\n border: 1px solid #d1d5db;\n border-radius: 8px;\n font-size: 16px;\n }\n </style>\n </head>\n <body>\n <div id=\"widget-container\">\n <div id=\"messages\">\n <div style=\"text-align: center; color: #9ca3af; padding: 20px;\">\n ${config?.greetingMessage || 'Start chatting...'}\n </div>\n </div>\n <div id=\"input-container\">\n <input \n type=\"text\" \n id=\"message-input\"\n placeholder=\"Type a message...\"\n />\n </div>\n </div>\n \n <script>\n console.log('WebView initialized');\n \n // Configuration from native\n window.linguConfig = ${configJSON};\n \n // Bridge to React Native\n window.sendToNative = function(type, payload) {\n console.log('Sending to native:', type, payload);\n window.ReactNativeWebView.postMessage(JSON.stringify({\n type: type,\n payload: payload\n }));\n };\n \n // Log to native\n window.logToNative = function(message) {\n window.sendToNative('WEBVIEW_LOG', message);\n };\n \n // Handle input\n const input = document.getElementById('message-input');\n input.addEventListener('keypress', function(e) {\n if (e.key === 'Enter' && input.value.trim()) {\n console.log('User pressed enter:', input.value);\n window.sendToNative('SEND_MESSAGE', { message: input.value });\n input.value = '';\n }\n });\n \n console.log('Event listeners attached');\n window.logToNative('WebView ready');\n </script>\n </body>\n </html>\n `;\n };\n\n return (\n <WebView\n ref={webViewRef}\n source={{ html: generateHTML() }}\n style={styles.webview}\n onMessage={handleMessage}\n javaScriptEnabled\n domStorageEnabled\n startInLoadingState\n scalesPageToFit\n onLoad={() => console.log(`${LOG_PREFIX} WebView loaded`)}\n onError={(error) => console.error(`${LOG_PREFIX} WebView error:`, error)}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n webview: {\n flex: 1,\n backgroundColor: 'white',\n },\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.MessageBubble = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _theme = require("../theme");
|
|
10
|
+
var _formatters = require("../utils/formatters");
|
|
11
|
+
var _animations = require("../utils/animations");
|
|
12
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
13
|
+
/**
|
|
14
|
+
* Message Bubble Component
|
|
15
|
+
* Displays a single message with animations and styling
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const MessageBubble = ({
|
|
19
|
+
message,
|
|
20
|
+
showTimestamp = false
|
|
21
|
+
}) => {
|
|
22
|
+
const {
|
|
23
|
+
theme
|
|
24
|
+
} = (0, _theme.useTheme)();
|
|
25
|
+
const isUser = message.sender === 'user';
|
|
26
|
+
|
|
27
|
+
// Animation values
|
|
28
|
+
const translateY = (0, _react.useRef)(new _reactNative.Animated.Value(20)).current;
|
|
29
|
+
const opacity = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
30
|
+
(0, _react.useEffect)(() => {
|
|
31
|
+
// Animate message entrance
|
|
32
|
+
(0, _animations.messageEntrance)(translateY, opacity, theme.animations.normal).start();
|
|
33
|
+
}, []);
|
|
34
|
+
const bubbleStyle = isUser ? {
|
|
35
|
+
backgroundColor: theme.colors.userBubble
|
|
36
|
+
} : {
|
|
37
|
+
backgroundColor: theme.colors.botBubble,
|
|
38
|
+
...theme.shadows.sm
|
|
39
|
+
};
|
|
40
|
+
const textStyle = {
|
|
41
|
+
color: isUser ? theme.colors.userText : theme.colors.botText
|
|
42
|
+
};
|
|
43
|
+
return /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, {
|
|
44
|
+
style: [styles.container, isUser ? styles.userContainer : styles.botContainer, {
|
|
45
|
+
opacity,
|
|
46
|
+
transform: [{
|
|
47
|
+
translateY
|
|
48
|
+
}]
|
|
49
|
+
}]
|
|
50
|
+
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
51
|
+
style: [styles.bubble, bubbleStyle, {
|
|
52
|
+
borderRadius: theme.borderRadius.lg,
|
|
53
|
+
borderBottomRightRadius: isUser ? theme.borderRadius.sm : theme.borderRadius.lg,
|
|
54
|
+
borderBottomLeftRadius: isUser ? theme.borderRadius.lg : theme.borderRadius.sm,
|
|
55
|
+
paddingHorizontal: theme.spacing.md,
|
|
56
|
+
paddingVertical: theme.spacing.sm + 2
|
|
57
|
+
}]
|
|
58
|
+
}, /*#__PURE__*/_react.default.createElement(_reactNative.Text, {
|
|
59
|
+
style: [styles.text, textStyle, {
|
|
60
|
+
fontSize: theme.typography.fontSizes.base,
|
|
61
|
+
lineHeight: theme.typography.fontSizes.base * theme.typography.lineHeights.normal
|
|
62
|
+
}]
|
|
63
|
+
}, message.text), showTimestamp && /*#__PURE__*/_react.default.createElement(_reactNative.Text, {
|
|
64
|
+
style: [styles.timestamp, {
|
|
65
|
+
color: isUser ? theme.colors.gray100 : theme.colors.gray500,
|
|
66
|
+
fontSize: theme.typography.fontSizes.xs,
|
|
67
|
+
marginTop: theme.spacing.xs
|
|
68
|
+
}]
|
|
69
|
+
}, (0, _formatters.formatRelativeTime)(message.timestamp))));
|
|
70
|
+
};
|
|
71
|
+
exports.MessageBubble = MessageBubble;
|
|
72
|
+
const styles = _reactNative.StyleSheet.create({
|
|
73
|
+
container: {
|
|
74
|
+
marginBottom: 12,
|
|
75
|
+
flexDirection: 'row'
|
|
76
|
+
},
|
|
77
|
+
userContainer: {
|
|
78
|
+
justifyContent: 'flex-end'
|
|
79
|
+
},
|
|
80
|
+
botContainer: {
|
|
81
|
+
justifyContent: 'flex-start'
|
|
82
|
+
},
|
|
83
|
+
bubble: {
|
|
84
|
+
maxWidth: '75%'
|
|
85
|
+
},
|
|
86
|
+
text: {},
|
|
87
|
+
timestamp: {
|
|
88
|
+
fontSize: 11
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
//# sourceMappingURL=MessageBubble.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_theme","_formatters","_animations","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","MessageBubble","message","showTimestamp","theme","useTheme","isUser","sender","translateY","useRef","Animated","Value","current","opacity","useEffect","messageEntrance","animations","normal","start","bubbleStyle","backgroundColor","colors","userBubble","botBubble","shadows","sm","textStyle","color","userText","botText","createElement","View","style","styles","container","userContainer","botContainer","transform","bubble","borderRadius","lg","borderBottomRightRadius","borderBottomLeftRadius","paddingHorizontal","spacing","md","paddingVertical","Text","text","fontSize","typography","fontSizes","base","lineHeight","lineHeights","timestamp","gray100","gray500","xs","marginTop","formatRelativeTime","exports","StyleSheet","create","marginBottom","flexDirection","justifyContent","maxWidth"],"sources":["MessageBubble.tsx"],"sourcesContent":["/**\n * Message Bubble Component\n * Displays a single message with animations and styling\n */\n\nimport React, { useEffect, useRef } from 'react';\nimport { View, Text, StyleSheet, Animated } from 'react-native';\nimport { useTheme } from '../theme';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { messageEntrance } from '../utils/animations';\nimport type { Message } from '../types';\n\ninterface MessageBubbleProps {\n message: Message;\n showTimestamp?: boolean;\n}\n\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({\n message,\n showTimestamp = false,\n}) => {\n const { theme } = useTheme();\n const isUser = message.sender === 'user';\n\n // Animation values\n const translateY = useRef(new Animated.Value(20)).current;\n const opacity = useRef(new Animated.Value(0)).current;\n\n useEffect(() => {\n // Animate message entrance\n messageEntrance(translateY, opacity, theme.animations.normal).start();\n }, []);\n\n const bubbleStyle = isUser\n ? {\n backgroundColor: theme.colors.userBubble,\n }\n : {\n backgroundColor: theme.colors.botBubble,\n ...theme.shadows.sm,\n };\n\n const textStyle = {\n color: isUser ? theme.colors.userText : theme.colors.botText,\n };\n\n return (\n <Animated.View\n style={[\n styles.container,\n isUser ? styles.userContainer : styles.botContainer,\n {\n opacity,\n transform: [{ translateY }],\n },\n ]}\n >\n <View\n style={[\n styles.bubble,\n bubbleStyle,\n {\n borderRadius: theme.borderRadius.lg,\n borderBottomRightRadius: isUser ? theme.borderRadius.sm : theme.borderRadius.lg,\n borderBottomLeftRadius: isUser ? theme.borderRadius.lg : theme.borderRadius.sm,\n paddingHorizontal: theme.spacing.md,\n paddingVertical: theme.spacing.sm + 2,\n },\n ]}\n >\n <Text\n style={[\n styles.text,\n textStyle,\n {\n fontSize: theme.typography.fontSizes.base,\n lineHeight: theme.typography.fontSizes.base * theme.typography.lineHeights.normal,\n },\n ]}\n >\n {message.text}\n </Text>\n {showTimestamp && (\n <Text\n style={[\n styles.timestamp,\n {\n color: isUser ? theme.colors.gray100 : theme.colors.gray500,\n fontSize: theme.typography.fontSizes.xs,\n marginTop: theme.spacing.xs,\n },\n ]}\n >\n {formatRelativeTime(message.timestamp)}\n </Text>\n )}\n </View>\n </Animated.View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {\n marginBottom: 12,\n flexDirection: 'row',\n },\n userContainer: {\n justifyContent: 'flex-end',\n },\n botContainer: {\n justifyContent: 'flex-start',\n },\n bubble: {\n maxWidth: '75%',\n },\n text: {},\n timestamp: {\n fontSize: 11,\n },\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.NativeChatUI = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _theme = require("../theme");
|
|
10
|
+
var _MessageBubble = require("./MessageBubble");
|
|
11
|
+
var _TypingIndicator = require("./TypingIndicator");
|
|
12
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
13
|
+
/**
|
|
14
|
+
* Native Chat UI Component
|
|
15
|
+
* Pure React Native implementation without WebView
|
|
16
|
+
* Now with theme support and enhanced styling
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const LOG_PREFIX = '[NativeChatUI]';
|
|
20
|
+
const NativeChatUI = ({
|
|
21
|
+
config,
|
|
22
|
+
messages,
|
|
23
|
+
isLoading,
|
|
24
|
+
onSendMessage
|
|
25
|
+
}) => {
|
|
26
|
+
const {
|
|
27
|
+
theme
|
|
28
|
+
} = (0, _theme.useTheme)();
|
|
29
|
+
const [inputText, setInputText] = (0, _react.useState)('');
|
|
30
|
+
const flatListRef = (0, _react.useRef)(null);
|
|
31
|
+
console.log(`${LOG_PREFIX} Rendering with ${messages.length} messages`);
|
|
32
|
+
|
|
33
|
+
// Auto-scroll to bottom when new messages arrive
|
|
34
|
+
(0, _react.useEffect)(() => {
|
|
35
|
+
if (messages.length > 0 && flatListRef.current) {
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
var _flatListRef$current;
|
|
38
|
+
(_flatListRef$current = flatListRef.current) === null || _flatListRef$current === void 0 || _flatListRef$current.scrollToEnd({
|
|
39
|
+
animated: true
|
|
40
|
+
});
|
|
41
|
+
}, 100);
|
|
42
|
+
}
|
|
43
|
+
}, [messages]);
|
|
44
|
+
const handleSend = () => {
|
|
45
|
+
if (inputText.trim()) {
|
|
46
|
+
console.log(`${LOG_PREFIX} Sending message:`, inputText);
|
|
47
|
+
onSendMessage(inputText.trim());
|
|
48
|
+
setInputText('');
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const renderMessage = ({
|
|
52
|
+
item
|
|
53
|
+
}) => {
|
|
54
|
+
return /*#__PURE__*/_react.default.createElement(_MessageBubble.MessageBubble, {
|
|
55
|
+
message: item,
|
|
56
|
+
showTimestamp: false
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
const renderEmpty = () => /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
60
|
+
style: styles.emptyContainer
|
|
61
|
+
}, /*#__PURE__*/_react.default.createElement(_reactNative.Text, {
|
|
62
|
+
style: [styles.greetingText, {
|
|
63
|
+
color: theme.colors.gray500,
|
|
64
|
+
fontSize: theme.typography.fontSizes.base
|
|
65
|
+
}]
|
|
66
|
+
}, (config === null || config === void 0 ? void 0 : config.greetingMessage) || 'Hello! How can I help you today?'));
|
|
67
|
+
const renderFooter = () => {
|
|
68
|
+
if (isLoading) {
|
|
69
|
+
return /*#__PURE__*/_react.default.createElement(_TypingIndicator.TypingIndicator, null);
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
};
|
|
73
|
+
const charCount = inputText.length;
|
|
74
|
+
const maxChars = 5000;
|
|
75
|
+
const showCharCount = charCount > maxChars * 0.8;
|
|
76
|
+
return /*#__PURE__*/_react.default.createElement(_reactNative.KeyboardAvoidingView, {
|
|
77
|
+
style: [styles.container, {
|
|
78
|
+
backgroundColor: theme.colors.background
|
|
79
|
+
}],
|
|
80
|
+
behavior: _reactNative.Platform.OS === 'ios' ? 'padding' : undefined,
|
|
81
|
+
keyboardVerticalOffset: _reactNative.Platform.OS === 'ios' ? 90 : 0
|
|
82
|
+
}, /*#__PURE__*/_react.default.createElement(_reactNative.FlatList, {
|
|
83
|
+
ref: flatListRef,
|
|
84
|
+
data: messages,
|
|
85
|
+
renderItem: renderMessage,
|
|
86
|
+
keyExtractor: item => item.id,
|
|
87
|
+
contentContainerStyle: [styles.messagesList, {
|
|
88
|
+
padding: theme.spacing.lg
|
|
89
|
+
}],
|
|
90
|
+
ListEmptyComponent: renderEmpty,
|
|
91
|
+
ListFooterComponent: renderFooter,
|
|
92
|
+
showsVerticalScrollIndicator: false
|
|
93
|
+
}), /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
94
|
+
style: [styles.inputContainer, {
|
|
95
|
+
backgroundColor: theme.colors.background,
|
|
96
|
+
borderTopColor: theme.colors.inputBorder,
|
|
97
|
+
padding: theme.spacing.lg
|
|
98
|
+
}]
|
|
99
|
+
}, /*#__PURE__*/_react.default.createElement(_reactNative.TextInput, {
|
|
100
|
+
style: [styles.input, {
|
|
101
|
+
backgroundColor: theme.colors.inputBackground,
|
|
102
|
+
borderColor: theme.colors.inputBorder,
|
|
103
|
+
color: theme.colors.inputText,
|
|
104
|
+
fontSize: theme.typography.fontSizes.base,
|
|
105
|
+
borderRadius: theme.borderRadius.xl,
|
|
106
|
+
paddingHorizontal: theme.spacing.lg,
|
|
107
|
+
paddingVertical: theme.spacing.sm + 2,
|
|
108
|
+
marginRight: theme.spacing.sm
|
|
109
|
+
}],
|
|
110
|
+
value: inputText,
|
|
111
|
+
onChangeText: setInputText,
|
|
112
|
+
placeholder: "Type a message...",
|
|
113
|
+
placeholderTextColor: theme.colors.gray400,
|
|
114
|
+
multiline: true,
|
|
115
|
+
maxLength: maxChars,
|
|
116
|
+
onSubmitEditing: handleSend,
|
|
117
|
+
returnKeyType: "send",
|
|
118
|
+
blurOnSubmit: false
|
|
119
|
+
}), /*#__PURE__*/_react.default.createElement(_reactNative.TouchableOpacity, {
|
|
120
|
+
style: [styles.sendButton, {
|
|
121
|
+
backgroundColor: theme.colors.primary,
|
|
122
|
+
borderRadius: theme.borderRadius.xl,
|
|
123
|
+
paddingHorizontal: theme.spacing.lg,
|
|
124
|
+
paddingVertical: theme.spacing.sm + 2
|
|
125
|
+
}, !inputText.trim() && styles.sendButtonDisabled],
|
|
126
|
+
onPress: handleSend,
|
|
127
|
+
disabled: !inputText.trim() || isLoading
|
|
128
|
+
}, /*#__PURE__*/_react.default.createElement(_reactNative.Text, {
|
|
129
|
+
style: [styles.sendButtonText, {
|
|
130
|
+
fontSize: theme.typography.fontSizes.base,
|
|
131
|
+
fontWeight: theme.typography.fontWeights.semibold
|
|
132
|
+
}]
|
|
133
|
+
}, "Send"))), showCharCount && /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
134
|
+
style: [styles.charCountContainer, {
|
|
135
|
+
paddingHorizontal: theme.spacing.lg
|
|
136
|
+
}]
|
|
137
|
+
}, /*#__PURE__*/_react.default.createElement(_reactNative.Text, {
|
|
138
|
+
style: [styles.charCount, {
|
|
139
|
+
color: charCount >= maxChars ? theme.colors.errorText : theme.colors.gray500,
|
|
140
|
+
fontSize: theme.typography.fontSizes.xs
|
|
141
|
+
}]
|
|
142
|
+
}, charCount, "/", maxChars)));
|
|
143
|
+
};
|
|
144
|
+
exports.NativeChatUI = NativeChatUI;
|
|
145
|
+
const styles = _reactNative.StyleSheet.create({
|
|
146
|
+
container: {
|
|
147
|
+
flex: 1
|
|
148
|
+
},
|
|
149
|
+
messagesList: {
|
|
150
|
+
flexGrow: 1
|
|
151
|
+
},
|
|
152
|
+
emptyContainer: {
|
|
153
|
+
flex: 1,
|
|
154
|
+
justifyContent: 'center',
|
|
155
|
+
alignItems: 'center',
|
|
156
|
+
padding: 32
|
|
157
|
+
},
|
|
158
|
+
greetingText: {
|
|
159
|
+
textAlign: 'center'
|
|
160
|
+
},
|
|
161
|
+
inputContainer: {
|
|
162
|
+
flexDirection: 'row',
|
|
163
|
+
borderTopWidth: 1,
|
|
164
|
+
alignItems: 'flex-end'
|
|
165
|
+
},
|
|
166
|
+
input: {
|
|
167
|
+
flex: 1,
|
|
168
|
+
minHeight: 40,
|
|
169
|
+
maxHeight: 100,
|
|
170
|
+
borderWidth: 1
|
|
171
|
+
},
|
|
172
|
+
sendButton: {
|
|
173
|
+
justifyContent: 'center',
|
|
174
|
+
alignItems: 'center',
|
|
175
|
+
minWidth: 70
|
|
176
|
+
},
|
|
177
|
+
sendButtonDisabled: {
|
|
178
|
+
opacity: 0.5
|
|
179
|
+
},
|
|
180
|
+
sendButtonText: {
|
|
181
|
+
color: '#ffffff'
|
|
182
|
+
},
|
|
183
|
+
charCountContainer: {
|
|
184
|
+
position: 'absolute',
|
|
185
|
+
bottom: 70,
|
|
186
|
+
right: 0
|
|
187
|
+
},
|
|
188
|
+
charCount: {
|
|
189
|
+
textAlign: 'right'
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
//# sourceMappingURL=NativeChatUI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_theme","_MessageBubble","_TypingIndicator","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","LOG_PREFIX","NativeChatUI","config","messages","isLoading","onSendMessage","theme","useTheme","inputText","setInputText","useState","flatListRef","useRef","console","log","length","useEffect","current","setTimeout","_flatListRef$current","scrollToEnd","animated","handleSend","trim","renderMessage","item","createElement","MessageBubble","message","showTimestamp","renderEmpty","View","style","styles","emptyContainer","Text","greetingText","color","colors","gray500","fontSize","typography","fontSizes","base","greetingMessage","renderFooter","TypingIndicator","charCount","maxChars","showCharCount","KeyboardAvoidingView","container","backgroundColor","background","behavior","Platform","OS","undefined","keyboardVerticalOffset","FlatList","ref","data","renderItem","keyExtractor","id","contentContainerStyle","messagesList","padding","spacing","lg","ListEmptyComponent","ListFooterComponent","showsVerticalScrollIndicator","inputContainer","borderTopColor","inputBorder","TextInput","input","inputBackground","borderColor","borderRadius","xl","paddingHorizontal","paddingVertical","sm","marginRight","value","onChangeText","placeholder","placeholderTextColor","gray400","multiline","maxLength","onSubmitEditing","returnKeyType","blurOnSubmit","TouchableOpacity","sendButton","primary","sendButtonDisabled","onPress","disabled","sendButtonText","fontWeight","fontWeights","semibold","charCountContainer","errorText","xs","exports","StyleSheet","create","flex","flexGrow","justifyContent","alignItems","textAlign","flexDirection","borderTopWidth","minHeight","maxHeight","borderWidth","minWidth","opacity","position","bottom","right"],"sources":["NativeChatUI.tsx"],"sourcesContent":["/**\n * Native Chat UI Component\n * Pure React Native implementation without WebView\n * Now with theme support and enhanced styling\n */\n\nimport React, { useState, useRef, useEffect } from 'react';\nimport {\n View,\n Text,\n TextInput,\n TouchableOpacity,\n FlatList,\n StyleSheet,\n KeyboardAvoidingView,\n Platform,\n} from 'react-native';\nimport { useTheme } from '../theme';\nimport { MessageBubble } from './MessageBubble';\nimport { TypingIndicator } from './TypingIndicator';\nimport type { Message, WidgetConfig } from '../types';\n\nconst LOG_PREFIX = '[NativeChatUI]';\n\ninterface NativeChatUIProps {\n config: WidgetConfig | null;\n messages: Message[];\n isLoading: boolean;\n onSendMessage: (message: string) => void;\n}\n\nexport const NativeChatUI: React.FC<NativeChatUIProps> = ({\n config,\n messages,\n isLoading,\n onSendMessage,\n}) => {\n const { theme } = useTheme();\n const [inputText, setInputText] = useState('');\n const flatListRef = useRef<FlatList>(null);\n\n console.log(`${LOG_PREFIX} Rendering with ${messages.length} messages`);\n\n // Auto-scroll to bottom when new messages arrive\n useEffect(() => {\n if (messages.length > 0 && flatListRef.current) {\n setTimeout(() => {\n flatListRef.current?.scrollToEnd({ animated: true });\n }, 100);\n }\n }, [messages]);\n\n const handleSend = () => {\n if (inputText.trim()) {\n console.log(`${LOG_PREFIX} Sending message:`, inputText);\n onSendMessage(inputText.trim());\n setInputText('');\n }\n };\n\n const renderMessage = ({ item }: { item: Message }) => {\n return <MessageBubble message={item} showTimestamp={false} />;\n };\n\n const renderEmpty = () => (\n <View style={styles.emptyContainer}>\n <Text\n style={[\n styles.greetingText,\n {\n color: theme.colors.gray500,\n fontSize: theme.typography.fontSizes.base,\n },\n ]}\n >\n {config?.greetingMessage || 'Hello! How can I help you today?'}\n </Text>\n </View>\n );\n\n const renderFooter = () => {\n if (isLoading) {\n return <TypingIndicator />;\n }\n return null;\n };\n\n const charCount = inputText.length;\n const maxChars = 5000;\n const showCharCount = charCount > maxChars * 0.8;\n\n return (\n <KeyboardAvoidingView\n style={[styles.container, { backgroundColor: theme.colors.background }]}\n behavior={Platform.OS === 'ios' ? 'padding' : undefined}\n keyboardVerticalOffset={Platform.OS === 'ios' ? 90 : 0}\n >\n {/* Messages List */}\n <FlatList\n ref={flatListRef}\n data={messages}\n renderItem={renderMessage}\n keyExtractor={(item) => item.id}\n contentContainerStyle={[\n styles.messagesList,\n { padding: theme.spacing.lg },\n ]}\n ListEmptyComponent={renderEmpty}\n ListFooterComponent={renderFooter}\n showsVerticalScrollIndicator={false}\n />\n\n {/* Input Area */}\n <View\n style={[\n styles.inputContainer,\n {\n backgroundColor: theme.colors.background,\n borderTopColor: theme.colors.inputBorder,\n padding: theme.spacing.lg,\n },\n ]}\n >\n <TextInput\n style={[\n styles.input,\n {\n backgroundColor: theme.colors.inputBackground,\n borderColor: theme.colors.inputBorder,\n color: theme.colors.inputText,\n fontSize: theme.typography.fontSizes.base,\n borderRadius: theme.borderRadius.xl,\n paddingHorizontal: theme.spacing.lg,\n paddingVertical: theme.spacing.sm + 2,\n marginRight: theme.spacing.sm,\n },\n ]}\n value={inputText}\n onChangeText={setInputText}\n placeholder=\"Type a message...\"\n placeholderTextColor={theme.colors.gray400}\n multiline\n maxLength={maxChars}\n onSubmitEditing={handleSend}\n returnKeyType=\"send\"\n blurOnSubmit={false}\n />\n <TouchableOpacity\n style={[\n styles.sendButton,\n {\n backgroundColor: theme.colors.primary,\n borderRadius: theme.borderRadius.xl,\n paddingHorizontal: theme.spacing.lg,\n paddingVertical: theme.spacing.sm + 2,\n },\n !inputText.trim() && styles.sendButtonDisabled,\n ]}\n onPress={handleSend}\n disabled={!inputText.trim() || isLoading}\n >\n <Text\n style={[\n styles.sendButtonText,\n {\n fontSize: theme.typography.fontSizes.base,\n fontWeight: theme.typography.fontWeights.semibold,\n },\n ]}\n >\n Send\n </Text>\n </TouchableOpacity>\n </View>\n\n {/* Character count */}\n {showCharCount && (\n <View\n style={[\n styles.charCountContainer,\n { paddingHorizontal: theme.spacing.lg },\n ]}\n >\n <Text\n style={[\n styles.charCount,\n {\n color: charCount >= maxChars ? theme.colors.errorText : theme.colors.gray500,\n fontSize: theme.typography.fontSizes.xs,\n },\n ]}\n >\n {charCount}/{maxChars}\n </Text>\n </View>\n )}\n </KeyboardAvoidingView>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n },\n messagesList: {\n flexGrow: 1,\n },\n emptyContainer: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n padding: 32,\n },\n greetingText: {\n textAlign: 'center',\n },\n inputContainer: {\n flexDirection: 'row',\n borderTopWidth: 1,\n alignItems: 'flex-end',\n },\n input: {\n flex: 1,\n minHeight: 40,\n maxHeight: 100,\n borderWidth: 1,\n },\n sendButton: {\n justifyContent: 'center',\n alignItems: 'center',\n minWidth: 70,\n },\n sendButtonDisabled: {\n opacity: 0.5,\n },\n sendButtonText: {\n color: '#ffffff',\n },\n charCountContainer: {\n position: 'absolute',\n bottom: 70,\n right: 0,\n },\n charCount: {\n textAlign: 'right',\n },\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.TypingIndicator = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _theme = require("../theme");
|
|
10
|
+
var _animations = require("../utils/animations");
|
|
11
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
12
|
+
/**
|
|
13
|
+
* Typing Indicator Component
|
|
14
|
+
* Animated dots to show bot is typing
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const TypingIndicator = () => {
|
|
18
|
+
const {
|
|
19
|
+
theme
|
|
20
|
+
} = (0, _theme.useTheme)();
|
|
21
|
+
const dot1 = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
22
|
+
const dot2 = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
23
|
+
const dot3 = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
24
|
+
(0, _react.useEffect)(() => {
|
|
25
|
+
// Start animations with staggered delays
|
|
26
|
+
const anim1 = (0, _animations.typingDotAnimation)(dot1, 0);
|
|
27
|
+
const anim2 = (0, _animations.typingDotAnimation)(dot2, 150);
|
|
28
|
+
const anim3 = (0, _animations.typingDotAnimation)(dot3, 300);
|
|
29
|
+
anim1.start();
|
|
30
|
+
anim2.start();
|
|
31
|
+
anim3.start();
|
|
32
|
+
return () => {
|
|
33
|
+
anim1.stop();
|
|
34
|
+
anim2.stop();
|
|
35
|
+
anim3.stop();
|
|
36
|
+
};
|
|
37
|
+
}, []);
|
|
38
|
+
return /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
39
|
+
style: [styles.container, {
|
|
40
|
+
backgroundColor: theme.colors.botBubble
|
|
41
|
+
}]
|
|
42
|
+
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
43
|
+
style: styles.dotsContainer
|
|
44
|
+
}, /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, {
|
|
45
|
+
style: [styles.dot, {
|
|
46
|
+
backgroundColor: theme.colors.gray400
|
|
47
|
+
}, {
|
|
48
|
+
transform: [{
|
|
49
|
+
translateY: dot1
|
|
50
|
+
}]
|
|
51
|
+
}]
|
|
52
|
+
}), /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, {
|
|
53
|
+
style: [styles.dot, {
|
|
54
|
+
backgroundColor: theme.colors.gray400
|
|
55
|
+
}, {
|
|
56
|
+
transform: [{
|
|
57
|
+
translateY: dot2
|
|
58
|
+
}]
|
|
59
|
+
}]
|
|
60
|
+
}), /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, {
|
|
61
|
+
style: [styles.dot, {
|
|
62
|
+
backgroundColor: theme.colors.gray400
|
|
63
|
+
}, {
|
|
64
|
+
transform: [{
|
|
65
|
+
translateY: dot3
|
|
66
|
+
}]
|
|
67
|
+
}]
|
|
68
|
+
})));
|
|
69
|
+
};
|
|
70
|
+
exports.TypingIndicator = TypingIndicator;
|
|
71
|
+
const styles = _reactNative.StyleSheet.create({
|
|
72
|
+
container: {
|
|
73
|
+
maxWidth: '75%',
|
|
74
|
+
padding: 12,
|
|
75
|
+
borderRadius: 16,
|
|
76
|
+
borderBottomLeftRadius: 4,
|
|
77
|
+
marginBottom: 12
|
|
78
|
+
},
|
|
79
|
+
dotsContainer: {
|
|
80
|
+
flexDirection: 'row',
|
|
81
|
+
alignItems: 'center',
|
|
82
|
+
justifyContent: 'center',
|
|
83
|
+
height: 20
|
|
84
|
+
},
|
|
85
|
+
dot: {
|
|
86
|
+
width: 8,
|
|
87
|
+
height: 8,
|
|
88
|
+
borderRadius: 4,
|
|
89
|
+
marginHorizontal: 3
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=TypingIndicator.js.map
|