@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.
Files changed (106) hide show
  1. package/dist/src/models/conversation.js +1 -1
  2. package/dist/src/types/app.js +1 -0
  3. package/package.json +1 -1
  4. package/.vscode/settings.json +0 -3
  5. package/.yarn/install-state.gz +0 -0
  6. package/cdn-dist/README.md +0 -42
  7. package/cdn-dist/modo-web-component.js +0 -1344
  8. package/cdn-dist/modo-web-component.min.js +0 -1
  9. package/cdn-dist/package.json +0 -27
  10. package/dist/types/src/app.d.ts +0 -30
  11. package/dist/types/src/app.d.ts.map +0 -1
  12. package/dist/types/src/constants/index.d.ts +0 -10
  13. package/dist/types/src/constants/index.d.ts.map +0 -1
  14. package/dist/types/src/constants/regex.d.ts +0 -3
  15. package/dist/types/src/constants/regex.d.ts.map +0 -1
  16. package/dist/types/src/index.d.ts +0 -10
  17. package/dist/types/src/index.d.ts.map +0 -1
  18. package/dist/types/src/models/chatbot.d.ts +0 -24
  19. package/dist/types/src/models/chatbot.d.ts.map +0 -1
  20. package/dist/types/src/models/conversation.d.ts +0 -23
  21. package/dist/types/src/models/conversation.d.ts.map +0 -1
  22. package/dist/types/src/models/customer-data.d.ts +0 -32
  23. package/dist/types/src/models/customer-data.d.ts.map +0 -1
  24. package/dist/types/src/models/message-utils.d.ts +0 -13
  25. package/dist/types/src/models/message-utils.d.ts.map +0 -1
  26. package/dist/types/src/services/chat/conversation.d.ts +0 -23
  27. package/dist/types/src/services/chat/conversation.d.ts.map +0 -1
  28. package/dist/types/src/services/chat/message-utils.d.ts +0 -13
  29. package/dist/types/src/services/chat/message-utils.d.ts.map +0 -1
  30. package/dist/types/src/services/chat/model.d.ts +0 -28
  31. package/dist/types/src/services/chat/model.d.ts.map +0 -1
  32. package/dist/types/src/services/chatbot/chatbot.d.ts +0 -24
  33. package/dist/types/src/services/chatbot/chatbot.d.ts.map +0 -1
  34. package/dist/types/src/services/checker.d.ts +0 -4
  35. package/dist/types/src/services/checker.d.ts.map +0 -1
  36. package/dist/types/src/services/listeners/adders.d.ts +0 -4
  37. package/dist/types/src/services/listeners/adders.d.ts.map +0 -1
  38. package/dist/types/src/services/listeners/fn.d.ts +0 -4
  39. package/dist/types/src/services/listeners/fn.d.ts.map +0 -1
  40. package/dist/types/src/services/socket/utils.d.ts +0 -3
  41. package/dist/types/src/services/socket/utils.d.ts.map +0 -1
  42. package/dist/types/src/services/ui/fn.d.ts +0 -14
  43. package/dist/types/src/services/ui/fn.d.ts.map +0 -1
  44. package/dist/types/src/services/ui/html.d.ts +0 -4
  45. package/dist/types/src/services/ui/html.d.ts.map +0 -1
  46. package/dist/types/src/services/user/customer-data.d.ts +0 -32
  47. package/dist/types/src/services/user/customer-data.d.ts.map +0 -1
  48. package/dist/types/src/services/voice-chat/model.d.ts +0 -13
  49. package/dist/types/src/services/voice-chat/model.d.ts.map +0 -1
  50. package/dist/types/src/services/voice-chat/utils.d.ts +0 -10
  51. package/dist/types/src/services/voice-chat/utils.d.ts.map +0 -1
  52. package/dist/types/src/tools/fetch.d.ts +0 -3
  53. package/dist/types/src/tools/fetch.d.ts.map +0 -1
  54. package/dist/types/src/types/app.d.ts +0 -18
  55. package/dist/types/src/types/app.d.ts.map +0 -1
  56. package/dist/types/src/types/conversation.d.ts +0 -15
  57. package/dist/types/src/types/conversation.d.ts.map +0 -1
  58. package/dist/types/src/types/socket.d.ts +0 -7
  59. package/dist/types/src/types/socket.d.ts.map +0 -1
  60. package/dist/types/src/types/window.d.ts +0 -10
  61. package/dist/types/src/types/window.d.ts.map +0 -1
  62. package/dist/types/src/utils/audio.d.ts +0 -4
  63. package/dist/types/src/utils/audio.d.ts.map +0 -1
  64. package/dist/types/src/utils/browser.d.ts +0 -3
  65. package/dist/types/src/utils/browser.d.ts.map +0 -1
  66. package/dist/types/src/utils/fetch.d.ts +0 -19
  67. package/dist/types/src/utils/fetch.d.ts.map +0 -1
  68. package/dist/types/src/utils/uuid.d.ts +0 -7
  69. package/dist/types/src/utils/uuid.d.ts.map +0 -1
  70. package/rollup.config.js +0 -18
  71. package/rollup.dev.config.js +0 -22
  72. package/scripts/create-umd-bundle.js +0 -213
  73. package/scripts/terser-minify.js +0 -112
  74. package/src/app.ts +0 -117
  75. package/src/constants/index.ts +0 -21
  76. package/src/constants/regex.ts +0 -2
  77. package/src/index.ts +0 -16
  78. package/src/services/chat/conversation.ts +0 -135
  79. package/src/services/chat/message-utils.ts +0 -221
  80. package/src/services/chat/model.ts +0 -139
  81. package/src/services/chatbot/chatbot.ts +0 -66
  82. package/src/services/checker.ts +0 -10
  83. package/src/services/listeners/adders.ts +0 -178
  84. package/src/services/listeners/fn.ts +0 -77
  85. package/src/services/socket/utils.ts +0 -9
  86. package/src/services/ui/fn.ts +0 -254
  87. package/src/services/ui/html.ts +0 -192
  88. package/src/services/user/customer-data.ts +0 -78
  89. package/src/services/voice-chat/model.ts +0 -79
  90. package/src/services/voice-chat/utils.ts +0 -137
  91. package/src/tools/fetch.ts +0 -7
  92. package/src/types/app.ts +0 -17
  93. package/src/types/conversation.ts +0 -14
  94. package/src/types/socket.ts +0 -7
  95. package/src/types/window.ts +0 -12
  96. package/src/utils/audio.ts +0 -67
  97. package/src/utils/browser.ts +0 -4
  98. package/src/utils/fetch.ts +0 -98
  99. package/src/utils/uuid.ts +0 -13
  100. package/temp/audio/new-message.mp3 +0 -0
  101. package/temp/audio/on-hold.mp3 +0 -0
  102. package/temp/audio-processor.js +0 -261
  103. package/temp/css/index.css +0 -2283
  104. package/temp/dev.html +0 -87
  105. package/temp/index.html +0 -16
  106. 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);
@@ -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};
@@ -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};
@@ -1,2 +0,0 @@
1
- const PhoneNumberRegex = /^(\+98|0)?9\d{9}$/;
2
- export {PhoneNumberRegex};
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};