@modochats/widget 0.1.0 → 0.1.2
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/src/models/conversation.js +1 -1
- package/dist/src/types/app.js +1 -0
- package/package.json +1 -1
- package/.vscode/settings.json +0 -3
- package/.yarn/install-state.gz +0 -0
- package/cdn-dist/README.md +0 -42
- package/cdn-dist/modo-web-component.js +0 -1344
- package/cdn-dist/modo-web-component.min.js +0 -1
- package/cdn-dist/package.json +0 -27
- package/dist/types/src/app.d.ts +0 -30
- package/dist/types/src/app.d.ts.map +0 -1
- package/dist/types/src/constants/index.d.ts +0 -10
- package/dist/types/src/constants/index.d.ts.map +0 -1
- package/dist/types/src/constants/regex.d.ts +0 -3
- package/dist/types/src/constants/regex.d.ts.map +0 -1
- package/dist/types/src/index.d.ts +0 -10
- package/dist/types/src/index.d.ts.map +0 -1
- package/dist/types/src/models/chatbot.d.ts +0 -24
- package/dist/types/src/models/chatbot.d.ts.map +0 -1
- package/dist/types/src/models/conversation.d.ts +0 -23
- package/dist/types/src/models/conversation.d.ts.map +0 -1
- package/dist/types/src/models/customer-data.d.ts +0 -32
- package/dist/types/src/models/customer-data.d.ts.map +0 -1
- package/dist/types/src/models/message-utils.d.ts +0 -13
- package/dist/types/src/models/message-utils.d.ts.map +0 -1
- package/dist/types/src/services/chat/conversation.d.ts +0 -23
- package/dist/types/src/services/chat/conversation.d.ts.map +0 -1
- package/dist/types/src/services/chat/message-utils.d.ts +0 -13
- package/dist/types/src/services/chat/message-utils.d.ts.map +0 -1
- package/dist/types/src/services/chat/model.d.ts +0 -28
- package/dist/types/src/services/chat/model.d.ts.map +0 -1
- package/dist/types/src/services/chatbot/chatbot.d.ts +0 -24
- package/dist/types/src/services/chatbot/chatbot.d.ts.map +0 -1
- package/dist/types/src/services/checker.d.ts +0 -4
- package/dist/types/src/services/checker.d.ts.map +0 -1
- package/dist/types/src/services/listeners/adders.d.ts +0 -4
- package/dist/types/src/services/listeners/adders.d.ts.map +0 -1
- package/dist/types/src/services/listeners/fn.d.ts +0 -4
- package/dist/types/src/services/listeners/fn.d.ts.map +0 -1
- package/dist/types/src/services/socket/utils.d.ts +0 -3
- package/dist/types/src/services/socket/utils.d.ts.map +0 -1
- package/dist/types/src/services/ui/fn.d.ts +0 -14
- package/dist/types/src/services/ui/fn.d.ts.map +0 -1
- package/dist/types/src/services/ui/html.d.ts +0 -4
- package/dist/types/src/services/ui/html.d.ts.map +0 -1
- package/dist/types/src/services/user/customer-data.d.ts +0 -32
- package/dist/types/src/services/user/customer-data.d.ts.map +0 -1
- package/dist/types/src/services/voice-chat/model.d.ts +0 -13
- package/dist/types/src/services/voice-chat/model.d.ts.map +0 -1
- package/dist/types/src/services/voice-chat/utils.d.ts +0 -10
- package/dist/types/src/services/voice-chat/utils.d.ts.map +0 -1
- package/dist/types/src/tools/fetch.d.ts +0 -3
- package/dist/types/src/tools/fetch.d.ts.map +0 -1
- package/dist/types/src/types/app.d.ts +0 -18
- package/dist/types/src/types/app.d.ts.map +0 -1
- package/dist/types/src/types/conversation.d.ts +0 -15
- package/dist/types/src/types/conversation.d.ts.map +0 -1
- package/dist/types/src/types/socket.d.ts +0 -7
- package/dist/types/src/types/socket.d.ts.map +0 -1
- package/dist/types/src/types/window.d.ts +0 -10
- package/dist/types/src/types/window.d.ts.map +0 -1
- package/dist/types/src/utils/audio.d.ts +0 -4
- package/dist/types/src/utils/audio.d.ts.map +0 -1
- package/dist/types/src/utils/browser.d.ts +0 -3
- package/dist/types/src/utils/browser.d.ts.map +0 -1
- package/dist/types/src/utils/fetch.d.ts +0 -19
- package/dist/types/src/utils/fetch.d.ts.map +0 -1
- package/dist/types/src/utils/uuid.d.ts +0 -7
- package/dist/types/src/utils/uuid.d.ts.map +0 -1
- package/rollup.config.js +0 -18
- package/rollup.dev.config.js +0 -22
- package/scripts/create-umd-bundle.js +0 -213
- package/scripts/terser-minify.js +0 -112
- package/src/app.ts +0 -117
- package/src/constants/index.ts +0 -21
- package/src/constants/regex.ts +0 -2
- package/src/index.ts +0 -16
- package/src/services/chat/conversation.ts +0 -135
- package/src/services/chat/message-utils.ts +0 -221
- package/src/services/chat/model.ts +0 -139
- package/src/services/chatbot/chatbot.ts +0 -66
- package/src/services/checker.ts +0 -10
- package/src/services/listeners/adders.ts +0 -178
- package/src/services/listeners/fn.ts +0 -77
- package/src/services/socket/utils.ts +0 -9
- package/src/services/ui/fn.ts +0 -254
- package/src/services/ui/html.ts +0 -192
- package/src/services/user/customer-data.ts +0 -78
- package/src/services/voice-chat/model.ts +0 -79
- package/src/services/voice-chat/utils.ts +0 -137
- package/src/tools/fetch.ts +0 -7
- package/src/types/app.ts +0 -17
- package/src/types/conversation.ts +0 -14
- package/src/types/socket.ts +0 -7
- package/src/types/window.ts +0 -12
- package/src/utils/audio.ts +0 -67
- package/src/utils/browser.ts +0 -4
- package/src/utils/fetch.ts +0 -98
- package/src/utils/uuid.ts +0 -13
- package/temp/audio/new-message.mp3 +0 -0
- package/temp/audio/on-hold.mp3 +0 -0
- package/temp/audio-processor.js +0 -261
- package/temp/css/index.css +0 -2283
- package/temp/dev.html +0 -87
- package/temp/index.html +0 -16
- package/tsconfig.json +0 -119
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import {promises as fs} from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import {fileURLToPath} from "url";
|
|
4
|
-
import {minify} from "terser";
|
|
5
|
-
|
|
6
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
-
const __dirname = path.dirname(__filename);
|
|
8
|
-
|
|
9
|
-
async function createUMDBundle() {
|
|
10
|
-
const distDir = path.resolve(__dirname, "../dist");
|
|
11
|
-
const outputDir = path.resolve(__dirname, "../cdn-dist");
|
|
12
|
-
|
|
13
|
-
console.log("Creating UMD bundle...");
|
|
14
|
-
console.log("Dist directory:", distDir);
|
|
15
|
-
console.log("Output directory:", outputDir);
|
|
16
|
-
|
|
17
|
-
// Ensure output directory exists
|
|
18
|
-
await fs.mkdir(outputDir, {recursive: true});
|
|
19
|
-
|
|
20
|
-
// Read the main app file from rollup output
|
|
21
|
-
const appPath = path.join(distDir, "../temp/app.js");
|
|
22
|
-
let appCode = "";
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
appCode = await fs.readFile(appPath, "utf8");
|
|
26
|
-
} catch (error) {
|
|
27
|
-
console.error("Error reading app.js from temp directory:", error);
|
|
28
|
-
// Fallback to dist/src/app.js if temp doesn't exist
|
|
29
|
-
const fallbackPath = path.join(distDir, "src/app.js");
|
|
30
|
-
try {
|
|
31
|
-
appCode = await fs.readFile(fallbackPath, "utf8");
|
|
32
|
-
} catch (fallbackError) {
|
|
33
|
-
console.error("Error reading app.js from dist directory:", fallbackError);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Clean up the app code
|
|
39
|
-
let cleanedAppCode = appCode;
|
|
40
|
-
|
|
41
|
-
// Remove 'use strict' from the beginning if it exists
|
|
42
|
-
cleanedAppCode = cleanedAppCode.replace(/^['"]use strict['"];\s*/, "");
|
|
43
|
-
|
|
44
|
-
// Check if Widget is properly defined and exported
|
|
45
|
-
const hasWidget = cleanedAppCode.includes("class Widget") || cleanedAppCode.includes("function Widget");
|
|
46
|
-
const hasWindowExport = cleanedAppCode.includes("window.Widget");
|
|
47
|
-
|
|
48
|
-
if (!hasWidget) {
|
|
49
|
-
console.error("Widget class not found in the bundle!");
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Create UMD wrapper
|
|
54
|
-
const umdCode = `(function (global, factory) {
|
|
55
|
-
if (typeof exports === 'object' && typeof module !== 'undefined') {
|
|
56
|
-
module.exports = factory();
|
|
57
|
-
} else if (typeof define === 'function' && define.amd) {
|
|
58
|
-
define(factory);
|
|
59
|
-
} else {
|
|
60
|
-
global.ModoWebComponent = factory();
|
|
61
|
-
}
|
|
62
|
-
})(typeof globalThis !== 'undefined' ? globalThis : typeof self !== 'undefined' ? self : this, function () {
|
|
63
|
-
'use strict';
|
|
64
|
-
|
|
65
|
-
${cleanedAppCode}
|
|
66
|
-
|
|
67
|
-
// Return the ModoChat class for UMD usage
|
|
68
|
-
return typeof ModoChat !== 'undefined' ? ModoChat : (typeof window !== 'undefined' && window.ModoChat ? window.ModoChat : null);
|
|
69
|
-
});`;
|
|
70
|
-
|
|
71
|
-
// Write UMD bundle
|
|
72
|
-
const umdPath = path.join(outputDir, "modo-widget.js");
|
|
73
|
-
const legacyUmdPath = path.join(outputDir, "modo-web-component.js");
|
|
74
|
-
await fs.writeFile(umdPath, umdCode);
|
|
75
|
-
await fs.writeFile(legacyUmdPath, umdCode);
|
|
76
|
-
console.log("Created UMD bundle:", umdPath);
|
|
77
|
-
|
|
78
|
-
// Create minified version using Terser
|
|
79
|
-
console.log("Minifying UMD bundle...");
|
|
80
|
-
try {
|
|
81
|
-
const result = await minify(umdCode, {
|
|
82
|
-
sourceMap: false,
|
|
83
|
-
mangle: true,
|
|
84
|
-
compress: true,
|
|
85
|
-
keep_classnames: false,
|
|
86
|
-
keep_fnames: false
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
if (result.error) {
|
|
90
|
-
throw result.error;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (result.code) {
|
|
94
|
-
const minPath = path.join(outputDir, "modo-widget.min.js");
|
|
95
|
-
const legacyMinPath = path.join(outputDir, "modo-web-component.min.js");
|
|
96
|
-
await fs.writeFile(minPath, result.code);
|
|
97
|
-
await fs.writeFile(legacyMinPath, result.code);
|
|
98
|
-
console.log("Created minified bundle:", minPath);
|
|
99
|
-
} else {
|
|
100
|
-
console.warn("No minified code generated. Using original code.");
|
|
101
|
-
const minPath = path.join(outputDir, "modo-widget.min.js");
|
|
102
|
-
const legacyMinPath = path.join(outputDir, "modo-web-component.min.js");
|
|
103
|
-
await fs.writeFile(minPath, umdCode);
|
|
104
|
-
await fs.writeFile(legacyMinPath, umdCode);
|
|
105
|
-
}
|
|
106
|
-
} catch (error) {
|
|
107
|
-
console.error("Error during minification:", error);
|
|
108
|
-
console.log("Falling back to original code for minified version...");
|
|
109
|
-
const minPath = path.join(outputDir, "modo-widget.min.js");
|
|
110
|
-
const legacyMinPath = path.join(outputDir, "modo-web-component.min.js");
|
|
111
|
-
await fs.writeFile(minPath, umdCode);
|
|
112
|
-
await fs.writeFile(legacyMinPath, umdCode);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Copy dist folder
|
|
116
|
-
await copyDirectory(distDir, path.join(outputDir, "dist"));
|
|
117
|
-
|
|
118
|
-
// Create package.json for CDN
|
|
119
|
-
const packageJson = {
|
|
120
|
-
name: "modochat-widget",
|
|
121
|
-
version: "1.0.0",
|
|
122
|
-
description: "Modo Web Component - A lightweight web component library",
|
|
123
|
-
main: "modo-widget.js",
|
|
124
|
-
files: ["modo-widget.js", "modo-widget.min.js", "dist/"],
|
|
125
|
-
keywords: ["web-component", "modo", "javascript", "umd"],
|
|
126
|
-
author: "",
|
|
127
|
-
license: "ISC",
|
|
128
|
-
repository: {
|
|
129
|
-
type: "git",
|
|
130
|
-
url: "https://github.com/your-username/modochat-widget.git"
|
|
131
|
-
},
|
|
132
|
-
homepage: "https://github.com/your-username/modochat-widget#readme",
|
|
133
|
-
bugs: {
|
|
134
|
-
url: "https://github.com/your-username/modochat-widget/issues"
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
await fs.writeFile(path.join(outputDir, "package.json"), JSON.stringify(packageJson, null, 2));
|
|
139
|
-
|
|
140
|
-
// Create README for CDN
|
|
141
|
-
const readmeContent = `# Modo Web Component
|
|
142
|
-
|
|
143
|
-
A lightweight web component library.
|
|
144
|
-
|
|
145
|
-
## CDN Usage
|
|
146
|
-
|
|
147
|
-
### jsDelivr
|
|
148
|
-
\`\`\`html
|
|
149
|
-
<script src="https://cdn.jsdelivr.net/gh/your-username/modochat-widget@main/cdn-dist/modo-widget.min.js"></script>
|
|
150
|
-
\`\`\`
|
|
151
|
-
|
|
152
|
-
### GitHub Raw
|
|
153
|
-
\`\`\`html
|
|
154
|
-
<script src="https://raw.githubusercontent.com/your-username/modochat-widget/main/cdn-dist/modo-widget.min.js"></script>
|
|
155
|
-
\`\`\`
|
|
156
|
-
|
|
157
|
-
## Usage
|
|
158
|
-
|
|
159
|
-
\`\`\`javascript
|
|
160
|
-
// Initialize the chat widget
|
|
161
|
-
const chat = new ModoChat('your-public-key', {
|
|
162
|
-
position: 'right', // 'left' or 'right'
|
|
163
|
-
theme: 'dark', // 'dark' or 'light'
|
|
164
|
-
primaryColor: '#667eea',
|
|
165
|
-
title: 'پشتیبانی چت'
|
|
166
|
-
});
|
|
167
|
-
\`\`\`
|
|
168
|
-
|
|
169
|
-
## Features
|
|
170
|
-
|
|
171
|
-
- 🌙 Dark/Light theme support
|
|
172
|
-
- 🌐 RTL (Persian/Farsi) language support
|
|
173
|
-
- 📱 Mobile responsive design
|
|
174
|
-
- 💬 Real-time chat functionality
|
|
175
|
-
- 🔗 WebSocket connection status
|
|
176
|
-
- 📝 Markdown message support
|
|
177
|
-
|
|
178
|
-
## Files
|
|
179
|
-
|
|
180
|
-
- \`modo-widget.js\` - Development version
|
|
181
|
-
- \`modo-widget.min.js\` - Production version (minified)
|
|
182
|
-
- \`dist/\` - Full distribution files
|
|
183
|
-
`;
|
|
184
|
-
|
|
185
|
-
await fs.writeFile(path.join(outputDir, "README.md"), readmeContent);
|
|
186
|
-
|
|
187
|
-
console.log("UMD bundle created successfully!");
|
|
188
|
-
console.log("Files created:");
|
|
189
|
-
console.log("- modo-widget.js");
|
|
190
|
-
console.log("- modo-widget.min.js");
|
|
191
|
-
console.log("- dist/ (copied from build)");
|
|
192
|
-
console.log("- package.json");
|
|
193
|
-
console.log("- README.md");
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
async function copyDirectory(src, dest) {
|
|
197
|
-
await fs.mkdir(dest, {recursive: true});
|
|
198
|
-
|
|
199
|
-
const entries = await fs.readdir(src, {withFileTypes: true});
|
|
200
|
-
|
|
201
|
-
for (const entry of entries) {
|
|
202
|
-
const srcPath = path.join(src, entry.name);
|
|
203
|
-
const destPath = path.join(dest, entry.name);
|
|
204
|
-
|
|
205
|
-
if (entry.isDirectory()) {
|
|
206
|
-
await copyDirectory(srcPath, destPath);
|
|
207
|
-
} else {
|
|
208
|
-
await fs.copyFile(srcPath, destPath);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
createUMDBundle().catch(console.error);
|
package/scripts/terser-minify.js
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
// scripts/minify.js
|
|
2
|
-
import {promises as fs} from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import {fileURLToPath} from "url";
|
|
5
|
-
import {minify} from "terser";
|
|
6
|
-
|
|
7
|
-
// --- Configuration ---
|
|
8
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
-
const __dirname = path.dirname(__filename);
|
|
10
|
-
// Resolve the dist directory relative to the project root (assuming scripts/ is one level down)
|
|
11
|
-
const distDir = path.resolve(__dirname, "../dist");
|
|
12
|
-
// Set to true to minify files in subdirectories as well
|
|
13
|
-
const recursive = true;
|
|
14
|
-
// Set to true to keep the original file extension (e.g., file.js -> file.js)
|
|
15
|
-
// Set to false to add .min.js (e.g., file.js -> file.min.js) - Requires output modification
|
|
16
|
-
const overwriteOriginals = true; // WARNING: This will replace your original files in dist!
|
|
17
|
-
// --- End Configuration ---
|
|
18
|
-
|
|
19
|
-
async function findJsFiles(dir) {
|
|
20
|
-
let jsFiles = [];
|
|
21
|
-
try {
|
|
22
|
-
const entries = await fs.readdir(dir, {withFileTypes: true});
|
|
23
|
-
for (const entry of entries) {
|
|
24
|
-
const fullPath = path.join(dir, entry.name);
|
|
25
|
-
if (entry.isDirectory() && recursive) {
|
|
26
|
-
jsFiles = jsFiles.concat(await findJsFiles(fullPath));
|
|
27
|
-
} else if (entry.isFile() && entry.name.endsWith(".js") && !entry.name.endsWith(".min.js")) {
|
|
28
|
-
// Avoid minifying already minified files if using .min.js extension
|
|
29
|
-
jsFiles.push(fullPath);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
} catch (err) {
|
|
33
|
-
// If distDir doesn't exist, treat it as no JS files found
|
|
34
|
-
if (err.code === "ENOENT") {
|
|
35
|
-
console.warn(`Warning: Directory not found: ${dir}`);
|
|
36
|
-
return [];
|
|
37
|
-
}
|
|
38
|
-
console.error(`Error reading directory ${dir}:`, err);
|
|
39
|
-
throw err; // Rethrow other errors
|
|
40
|
-
}
|
|
41
|
-
return jsFiles;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async function minifyFile(filePath) {
|
|
45
|
-
try {
|
|
46
|
-
const code = await fs.readFile(filePath, "utf8");
|
|
47
|
-
console.log(`Minifying: ${path.relative(distDir, filePath)}`);
|
|
48
|
-
|
|
49
|
-
const result = await minify(code, {
|
|
50
|
-
sourceMap: false, // Set to true or options object if you need source maps
|
|
51
|
-
mangle: true, // Enable variable name mangling
|
|
52
|
-
compress: true, // Enable compression options
|
|
53
|
-
// Add other Terser options here if needed:
|
|
54
|
-
// https://github.com/terser/terser#minify-options ,
|
|
55
|
-
keep_classnames: false,
|
|
56
|
-
keep_fnames: false
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
if (result.error) {
|
|
60
|
-
throw result.error; // Throw Terser specific errors
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (result.code) {
|
|
64
|
-
const outputPath = overwriteOriginals ? filePath : filePath.replace(/\.js$/, ".min.js"); // Example for adding .min.js
|
|
65
|
-
|
|
66
|
-
if (!overwriteOriginals && outputPath === filePath) {
|
|
67
|
-
console.warn(` -> Skipping write for ${filePath} as output path is the same and overwriteOriginals is false.`);
|
|
68
|
-
return; // Prevent accidental overwrite if logic fails
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
await fs.writeFile(outputPath, result.code, "utf8");
|
|
72
|
-
console.log(` -> Success: ${path.relative(distDir, outputPath)}`);
|
|
73
|
-
} else {
|
|
74
|
-
console.warn(` -> No code generated for ${filePath}. Skipping write.`);
|
|
75
|
-
}
|
|
76
|
-
} catch (error) {
|
|
77
|
-
console.error(`\nError minifying ${path.relative(distDir, filePath)}:`);
|
|
78
|
-
console.error(error);
|
|
79
|
-
// Decide if you want to stop the whole process on error or continue
|
|
80
|
-
// throw error; // Uncomment to stop on first error
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async function runMinification() {
|
|
85
|
-
console.log(`Starting minification in: ${distDir}`);
|
|
86
|
-
console.log(`Recursive: ${recursive}, Overwrite Originals: ${overwriteOriginals}`);
|
|
87
|
-
console.log("---");
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
const jsFiles = await findJsFiles(distDir);
|
|
91
|
-
|
|
92
|
-
if (jsFiles.length === 0) {
|
|
93
|
-
console.log("No .js files found to minify.");
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
console.log(`Found ${jsFiles.length} .js file(s).`);
|
|
98
|
-
|
|
99
|
-
// Run minification tasks potentially in parallel (adjust if memory becomes an issue)
|
|
100
|
-
await Promise.all(jsFiles.map(filePath => minifyFile(filePath)));
|
|
101
|
-
|
|
102
|
-
console.log("---");
|
|
103
|
-
console.log("Minification process finished.");
|
|
104
|
-
} catch (error) {
|
|
105
|
-
console.error("\n---");
|
|
106
|
-
console.error("An error occurred during the minification process:", error);
|
|
107
|
-
process.exit(1); // Exit with an error code
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// --- Execute the script ---
|
|
112
|
-
runMinification();
|
package/src/app.ts
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import {WidgetOptions} from "./types/app.js";
|
|
2
|
-
import {Chatbot} from "./services/chatbot/chatbot.js";
|
|
3
|
-
import {fetchChatbot} from "./utils/fetch.js";
|
|
4
|
-
import {checkIfHostIsAllowed} from "./services/checker.js";
|
|
5
|
-
import {createChatContainer} from "./services/ui/html.js";
|
|
6
|
-
import {CustomerData} from "./services/user/customer-data.js";
|
|
7
|
-
import {loadStarters, updateChatToggleImage, updateChatTitle, applyModoOptions, loadCss} from "./services/ui/fn.js";
|
|
8
|
-
import {VERSION} from "./constants/index.js";
|
|
9
|
-
import {VoiceChat} from "./services/voice-chat/model.js";
|
|
10
|
-
import {Chat} from "./services/chat/model.js";
|
|
11
|
-
|
|
12
|
-
class Widget {
|
|
13
|
-
container?: HTMLDivElement;
|
|
14
|
-
publicKey: string;
|
|
15
|
-
chatbot?: Chatbot;
|
|
16
|
-
customerData: CustomerData;
|
|
17
|
-
chat: Chat;
|
|
18
|
-
|
|
19
|
-
options: Partial<WidgetOptions> = {};
|
|
20
|
-
openedCount: number = 0;
|
|
21
|
-
version: string;
|
|
22
|
-
isInitialized: boolean = false;
|
|
23
|
-
isOpen: boolean = false;
|
|
24
|
-
voiceChat?: VoiceChat;
|
|
25
|
-
|
|
26
|
-
constructor(publicKey: string, options?: Partial<WidgetOptions>) {
|
|
27
|
-
this.publicKey = publicKey;
|
|
28
|
-
this.customerData = new CustomerData(this, options?.userData);
|
|
29
|
-
this.chat = new Chat();
|
|
30
|
-
this.version = VERSION;
|
|
31
|
-
this.options = {
|
|
32
|
-
position: options?.position || "right",
|
|
33
|
-
theme: options?.theme,
|
|
34
|
-
primaryColor: options?.primaryColor,
|
|
35
|
-
title: options?.title || "",
|
|
36
|
-
userData: options?.userData,
|
|
37
|
-
foregroundColor: options?.foregroundColor,
|
|
38
|
-
fullScreen: typeof options?.fullScreen === "boolean" ? options?.fullScreen : false
|
|
39
|
-
};
|
|
40
|
-
if (options?.autoInit) this.init();
|
|
41
|
-
}
|
|
42
|
-
async init() {
|
|
43
|
-
if (this.isInitialized) throw new Error("Widget already initialized");
|
|
44
|
-
const chatbotRes = await fetchChatbot(this.publicKey);
|
|
45
|
-
this.chatbot = new Chatbot(chatbotRes);
|
|
46
|
-
this.options = {
|
|
47
|
-
...this.options,
|
|
48
|
-
theme: this.options?.theme || this.chatbot?.uiConfig?.theme || "dark",
|
|
49
|
-
primaryColor: this.options?.primaryColor || this.chatbot?.uiConfig?.primaryColor || "#667eea",
|
|
50
|
-
foregroundColor: this.options?.foregroundColor || this.chatbot?.uiConfig?.foregroundColor || "#fff"
|
|
51
|
-
};
|
|
52
|
-
if (checkIfHostIsAllowed(this)) {
|
|
53
|
-
await loadCss();
|
|
54
|
-
window.getMWidget = () => this;
|
|
55
|
-
createChatContainer(this);
|
|
56
|
-
applyModoOptions();
|
|
57
|
-
loadStarters();
|
|
58
|
-
updateChatToggleImage();
|
|
59
|
-
updateChatTitle();
|
|
60
|
-
|
|
61
|
-
this.isInitialized = true;
|
|
62
|
-
this.chatbot.showTooltip();
|
|
63
|
-
|
|
64
|
-
// In fullscreen mode, automatically open the chat
|
|
65
|
-
if (this.options.fullScreen) {
|
|
66
|
-
// Ensure chat body is visible in fullscreen mode
|
|
67
|
-
const chatBody = this.container?.querySelector(".mw-chat-body");
|
|
68
|
-
if (chatBody) {
|
|
69
|
-
chatBody.classList.remove("mw-hidden");
|
|
70
|
-
chatBody.classList.add("mw-active");
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
this.chat.initInstance();
|
|
74
|
-
} finally {
|
|
75
|
-
this.onOpen();
|
|
76
|
-
}
|
|
77
|
-
} else this.chat.initInstance();
|
|
78
|
-
} else throw new Error("host not allowed");
|
|
79
|
-
}
|
|
80
|
-
async onOpen() {
|
|
81
|
-
this.isOpen = true;
|
|
82
|
-
this.openedCount++;
|
|
83
|
-
|
|
84
|
-
// Hide tooltip when chat is opened
|
|
85
|
-
this.conversation?.hideTooltip();
|
|
86
|
-
this.chatbot?.hideTooltip();
|
|
87
|
-
this.conversation?.markAsRead();
|
|
88
|
-
this.conversation?.scrollToBottom();
|
|
89
|
-
if (this.openedCount === 1) {
|
|
90
|
-
if (this.chat.conversationD) {
|
|
91
|
-
await this.conversation?.loadMessages();
|
|
92
|
-
await this.chat?.socket?.connect();
|
|
93
|
-
}
|
|
94
|
-
if (this.chatbot?.voiceChat) this.voiceChat = new VoiceChat();
|
|
95
|
-
await this.customerData.fetchUpdate();
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
onClose() {
|
|
99
|
-
this.isOpen = false;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Update user data with new values
|
|
104
|
-
* @param newUserData - Object containing new user data to merge
|
|
105
|
-
*/
|
|
106
|
-
async updateUserData(newUserData: Record<string, any>) {
|
|
107
|
-
await this.customerData.updateUserData(newUserData);
|
|
108
|
-
}
|
|
109
|
-
get conversation() {
|
|
110
|
-
return this.chat.conversation;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
window.ModoChat = Widget;
|
|
115
|
-
window.ModoWidget = Widget;
|
|
116
|
-
|
|
117
|
-
export type {Widget};
|
package/src/constants/index.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
const getEnvironment = () => {
|
|
2
|
-
// Check for browser global variable
|
|
3
|
-
if (typeof window !== "undefined" && (window as any).ENVIRONMENT) {
|
|
4
|
-
return (window as any).ENVIRONMENT;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
// Check for NODE_ENV in build process
|
|
8
|
-
if (typeof process !== "undefined" && process.env?.NODE_ENV) {
|
|
9
|
-
return process.env.NODE_ENV.toUpperCase();
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
return "PROD"; // Default to production
|
|
13
|
-
};
|
|
14
|
-
const isDev = getEnvironment() === "DEV";
|
|
15
|
-
const isProd = getEnvironment() === "PROD";
|
|
16
|
-
const BASE_API_URL = isDev ? "https://dev-api.modochats.com" : "https://api.modochats.com";
|
|
17
|
-
const BASE_WEBSOCKET_URL = isDev ? "wss://dev-api.modochats.com/ws" : "wss://api.modochats.com/ws";
|
|
18
|
-
const VERSION = "0.51";
|
|
19
|
-
const BASE_STORAGE_URL = "https://modochats.s3.ir-thr-at1.arvanstorage.ir";
|
|
20
|
-
const NEW_MESSAGE_AUDIO_URL = `${BASE_STORAGE_URL}/new-message.mp3`;
|
|
21
|
-
export {BASE_API_URL, BASE_WEBSOCKET_URL, VERSION, isDev, isProd, getEnvironment, NEW_MESSAGE_AUDIO_URL, BASE_STORAGE_URL};
|
package/src/constants/regex.ts
DELETED
package/src/index.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// Main exports
|
|
2
|
-
export {Widget as ModoChat} from "./app.js";
|
|
3
|
-
export type {WidgetOptions, FetchPaginationRes} from "./types/app.js";
|
|
4
|
-
|
|
5
|
-
// Models
|
|
6
|
-
export {Chatbot} from "./services/chatbot/chatbot.js";
|
|
7
|
-
export {Conversation} from "./services/chat/conversation.js";
|
|
8
|
-
export {CustomerData} from "./services/user/customer-data.js";
|
|
9
|
-
|
|
10
|
-
// Services
|
|
11
|
-
export {VoiceChat} from "./services/voice-chat/model.js";
|
|
12
|
-
export {Chat} from "./services/chat/model.js";
|
|
13
|
-
|
|
14
|
-
// Types
|
|
15
|
-
export type {ConversationStatus, MessageType} from "./types/conversation.js";
|
|
16
|
-
export type {SocketMessage} from "./types/socket.js";
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import {NEW_MESSAGE_AUDIO_URL} from "#src/constants/index.js";
|
|
2
|
-
import {setConversationType, switchToConversationLayout, switchToStarterLayout} from "#src/services/ui/fn.js";
|
|
3
|
-
import {playAudio, preloadAudio} from "#src/utils/audio.js";
|
|
4
|
-
import {initMessageElement, showMessageTooltip} from "./message-utils.js";
|
|
5
|
-
import {ConversationMessage} from "@modochats/chat-client";
|
|
6
|
-
|
|
7
|
-
class Conversation {
|
|
8
|
-
constructor() {}
|
|
9
|
-
// d = data
|
|
10
|
-
get d() {
|
|
11
|
-
return window.getMWidget?.().chat?.conversationD;
|
|
12
|
-
}
|
|
13
|
-
addMessage(message: ConversationMessage, options?: {incoming: boolean}) {
|
|
14
|
-
const widget = window.getMWidget?.();
|
|
15
|
-
initMessageElement(message);
|
|
16
|
-
if (options?.incoming) {
|
|
17
|
-
if (widget?.isOpen) this.markAsRead();
|
|
18
|
-
else {
|
|
19
|
-
this.addBadge();
|
|
20
|
-
showMessageTooltip(message);
|
|
21
|
-
playAudio(NEW_MESSAGE_AUDIO_URL).catch(console.warn);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
this.scrollToBottom();
|
|
25
|
-
}
|
|
26
|
-
clearContainerEl() {
|
|
27
|
-
const chatMessagesContainer = document.querySelector(".mw-chat-messages-con");
|
|
28
|
-
if (chatMessagesContainer) {
|
|
29
|
-
chatMessagesContainer.innerHTML = "";
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
addSystemMessage(message: string) {
|
|
33
|
-
const chatMessagesContainer = document.querySelector(".mw-chat-messages-con");
|
|
34
|
-
if (chatMessagesContainer) {
|
|
35
|
-
const systemMessageElement = document.createElement("div");
|
|
36
|
-
systemMessageElement.className = "mw-system-message";
|
|
37
|
-
systemMessageElement.innerHTML = `
|
|
38
|
-
<div class="mw-system-message-content">
|
|
39
|
-
${message}
|
|
40
|
-
</div>
|
|
41
|
-
`;
|
|
42
|
-
chatMessagesContainer.appendChild(systemMessageElement);
|
|
43
|
-
this.scrollToBottom();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
scrollToBottom() {
|
|
48
|
-
const chatMessagesContainer = document.querySelector(".mw-chat-messages-con");
|
|
49
|
-
if (chatMessagesContainer) {
|
|
50
|
-
chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
clear() {
|
|
55
|
-
this.d?.clear();
|
|
56
|
-
this.d!.messages = [];
|
|
57
|
-
const widget = window.getMWidget?.();
|
|
58
|
-
localStorage.removeItem(`modo-chat:${widget?.publicKey}-conversation-uuid`);
|
|
59
|
-
this.clearContainerEl();
|
|
60
|
-
switchToStarterLayout();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
onInit() {
|
|
64
|
-
switchToConversationLayout();
|
|
65
|
-
preloadAudio("./audio/new-message.mp3").catch(console.warn);
|
|
66
|
-
if (this?.d?.status) setConversationType(this.d?.status!);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
setStatus() {
|
|
70
|
-
setConversationType(this.d?.status!);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async loadMessages() {
|
|
74
|
-
const widget = window.getMWidget?.();
|
|
75
|
-
const messages = await this.d?.loadMessages();
|
|
76
|
-
const chatMessagesContainer = widget?.container?.querySelector(".mw-chat-messages-con");
|
|
77
|
-
if (chatMessagesContainer) chatMessagesContainer.innerHTML = "";
|
|
78
|
-
for (const message of messages || []) this.addMessage(message);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
addBadge() {
|
|
82
|
-
const widget = window.getMWidget?.();
|
|
83
|
-
if (!widget?.isOpen && this.unreadCount > 0 && widget) {
|
|
84
|
-
const badge = widget.container?.querySelector(".mw-badge");
|
|
85
|
-
const badgeText = widget.container?.querySelector(".mw-badge-text");
|
|
86
|
-
|
|
87
|
-
if (badge && badgeText) {
|
|
88
|
-
// Show the badge
|
|
89
|
-
badge.classList.remove("mw-hidden");
|
|
90
|
-
|
|
91
|
-
// Update badge text
|
|
92
|
-
const displayCount = this.unreadCount > 99 ? "99+" : this.unreadCount.toString();
|
|
93
|
-
badgeText.textContent = displayCount;
|
|
94
|
-
|
|
95
|
-
// Add plus class for 99+ counts
|
|
96
|
-
if (this.unreadCount > 99) {
|
|
97
|
-
badge.classList.add("mw-badge-plus");
|
|
98
|
-
} else {
|
|
99
|
-
badge.classList.remove("mw-badge-plus");
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
get unreadCount() {
|
|
106
|
-
return this.d?.unreadCount || 0;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
hideBadge() {
|
|
110
|
-
const widget = window.getMWidget?.();
|
|
111
|
-
const badge = widget?.container?.querySelector(".mw-badge");
|
|
112
|
-
if (badge) {
|
|
113
|
-
badge.classList.add("mw-hidden");
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
hideTooltip() {
|
|
118
|
-
const widget = window.getMWidget?.();
|
|
119
|
-
const tooltip = widget?.container?.querySelector(".mw-toggle-tooltip");
|
|
120
|
-
if (tooltip) {
|
|
121
|
-
tooltip.classList.add("mw-hidden");
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
async markAsRead() {
|
|
126
|
-
const widget = window.getMWidget?.();
|
|
127
|
-
await this.d?.markAsRead();
|
|
128
|
-
this.hideBadge();
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
get containerElement(): HTMLDivElement | null {
|
|
132
|
-
return document.querySelector(".mw-chat-messages-con");
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
export {Conversation};
|