@modochats/widget 0.1.4 → 1.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.
Files changed (179) hide show
  1. package/.github/workflows/build-and-publish.yml +116 -174
  2. package/.releaserc +59 -0
  3. package/CHANGELOG.md +16 -0
  4. package/README.md +191 -191
  5. package/package.json +79 -76
  6. package/src/app.ts +117 -117
  7. package/src/constants/index.ts +21 -21
  8. package/src/constants/regex.ts +2 -2
  9. package/src/constants/version.ts +2 -0
  10. package/src/index.ts +16 -16
  11. package/src/services/chat/conversation.ts +135 -135
  12. package/src/services/chat/message-utils.ts +221 -221
  13. package/src/services/chat/model.ts +139 -139
  14. package/src/services/chatbot/chatbot.ts +66 -66
  15. package/src/services/checker.ts +10 -10
  16. package/src/services/listeners/fn.ts +77 -77
  17. package/src/services/socket/utils.ts +9 -9
  18. package/src/services/user/customer-data.ts +78 -78
  19. package/src/services/voice-chat/model.ts +79 -79
  20. package/src/services/voice-chat/utils.ts +137 -137
  21. package/src/tools/fetch.ts +7 -7
  22. package/src/types/app.ts +17 -17
  23. package/src/types/conversation.ts +14 -14
  24. package/src/types/socket.ts +7 -7
  25. package/src/types/window.ts +12 -12
  26. package/src/utils/audio.ts +67 -67
  27. package/src/utils/browser.ts +4 -4
  28. package/src/utils/fetch.ts +98 -98
  29. package/src/utils/uuid.ts +13 -13
  30. package/dist/src/app.d.ts +0 -29
  31. package/dist/src/app.js +0 -1
  32. package/dist/src/app.js.map +0 -1
  33. package/dist/src/constants/index.d.ts +0 -9
  34. package/dist/src/constants/index.js +0 -1
  35. package/dist/src/constants/index.js.map +0 -1
  36. package/dist/src/constants/regex.d.ts +0 -2
  37. package/dist/src/constants/regex.js +0 -1
  38. package/dist/src/constants/regex.js.map +0 -1
  39. package/dist/src/index.d.ts +0 -9
  40. package/dist/src/index.js +0 -1
  41. package/dist/src/index.js.map +0 -1
  42. package/dist/src/models/chatbot.d.ts +0 -23
  43. package/dist/src/models/chatbot.js +0 -1
  44. package/dist/src/models/chatbot.js.map +0 -1
  45. package/dist/src/models/conversation.d.ts +0 -22
  46. package/dist/src/models/conversation.js +0 -1
  47. package/dist/src/models/conversation.js.map +0 -1
  48. package/dist/src/models/customer-data.d.ts +0 -31
  49. package/dist/src/models/customer-data.js +0 -1
  50. package/dist/src/models/customer-data.js.map +0 -1
  51. package/dist/src/models/message-utils.d.ts +0 -12
  52. package/dist/src/models/message-utils.js +0 -1
  53. package/dist/src/models/message-utils.js.map +0 -1
  54. package/dist/src/services/chat/conversation.d.ts +0 -22
  55. package/dist/src/services/chat/conversation.js +0 -1
  56. package/dist/src/services/chat/conversation.js.map +0 -1
  57. package/dist/src/services/chat/message-utils.d.ts +0 -12
  58. package/dist/src/services/chat/message-utils.js +0 -1
  59. package/dist/src/services/chat/message-utils.js.map +0 -1
  60. package/dist/src/services/chat/model.d.ts +0 -27
  61. package/dist/src/services/chat/model.js +0 -1
  62. package/dist/src/services/chat/model.js.map +0 -1
  63. package/dist/src/services/chatbot/chatbot.d.ts +0 -23
  64. package/dist/src/services/chatbot/chatbot.js +0 -1
  65. package/dist/src/services/chatbot/chatbot.js.map +0 -1
  66. package/dist/src/services/checker.d.ts +0 -3
  67. package/dist/src/services/checker.js +0 -1
  68. package/dist/src/services/checker.js.map +0 -1
  69. package/dist/src/services/listeners/adders.d.ts +0 -3
  70. package/dist/src/services/listeners/adders.js +0 -1
  71. package/dist/src/services/listeners/adders.js.map +0 -1
  72. package/dist/src/services/listeners/fn.d.ts +0 -3
  73. package/dist/src/services/listeners/fn.js +0 -1
  74. package/dist/src/services/listeners/fn.js.map +0 -1
  75. package/dist/src/services/socket/utils.d.ts +0 -2
  76. package/dist/src/services/socket/utils.js +0 -1
  77. package/dist/src/services/socket/utils.js.map +0 -1
  78. package/dist/src/services/ui/fn.d.ts +0 -13
  79. package/dist/src/services/ui/fn.js +0 -1
  80. package/dist/src/services/ui/fn.js.map +0 -1
  81. package/dist/src/services/ui/html.d.ts +0 -3
  82. package/dist/src/services/ui/html.js +0 -1
  83. package/dist/src/services/ui/html.js.map +0 -1
  84. package/dist/src/services/user/customer-data.d.ts +0 -31
  85. package/dist/src/services/user/customer-data.js +0 -1
  86. package/dist/src/services/user/customer-data.js.map +0 -1
  87. package/dist/src/services/voice-chat/model.d.ts +0 -12
  88. package/dist/src/services/voice-chat/model.js +0 -1
  89. package/dist/src/services/voice-chat/model.js.map +0 -1
  90. package/dist/src/services/voice-chat/utils.d.ts +0 -9
  91. package/dist/src/services/voice-chat/utils.js +0 -1
  92. package/dist/src/services/voice-chat/utils.js.map +0 -1
  93. package/dist/src/tools/fetch.d.ts +0 -2
  94. package/dist/src/tools/fetch.js +0 -1
  95. package/dist/src/tools/fetch.js.map +0 -1
  96. package/dist/src/types/app.d.ts +0 -17
  97. package/dist/src/types/app.js +0 -1
  98. package/dist/src/types/app.js.map +0 -1
  99. package/dist/src/types/conversation.d.ts +0 -14
  100. package/dist/src/types/conversation.js +0 -1
  101. package/dist/src/types/conversation.js.map +0 -1
  102. package/dist/src/types/socket.d.ts +0 -6
  103. package/dist/src/types/socket.js +0 -1
  104. package/dist/src/types/socket.js.map +0 -1
  105. package/dist/src/types/window.d.ts +0 -9
  106. package/dist/src/types/window.js +0 -1
  107. package/dist/src/types/window.js.map +0 -1
  108. package/dist/src/utils/audio.d.ts +0 -3
  109. package/dist/src/utils/audio.js +0 -1
  110. package/dist/src/utils/audio.js.map +0 -1
  111. package/dist/src/utils/browser.d.ts +0 -2
  112. package/dist/src/utils/browser.js +0 -1
  113. package/dist/src/utils/browser.js.map +0 -1
  114. package/dist/src/utils/fetch.d.ts +0 -18
  115. package/dist/src/utils/fetch.js +0 -1
  116. package/dist/src/utils/fetch.js.map +0 -1
  117. package/dist/src/utils/uuid.d.ts +0 -6
  118. package/dist/src/utils/uuid.js +0 -1
  119. package/dist/src/utils/uuid.js.map +0 -1
  120. package/dist/types/src/app.d.ts +0 -30
  121. package/dist/types/src/app.d.ts.map +0 -1
  122. package/dist/types/src/constants/index.d.ts +0 -10
  123. package/dist/types/src/constants/index.d.ts.map +0 -1
  124. package/dist/types/src/constants/regex.d.ts +0 -3
  125. package/dist/types/src/constants/regex.d.ts.map +0 -1
  126. package/dist/types/src/index.d.ts +0 -10
  127. package/dist/types/src/index.d.ts.map +0 -1
  128. package/dist/types/src/models/chatbot.d.ts +0 -24
  129. package/dist/types/src/models/chatbot.d.ts.map +0 -1
  130. package/dist/types/src/models/conversation.d.ts +0 -23
  131. package/dist/types/src/models/conversation.d.ts.map +0 -1
  132. package/dist/types/src/models/customer-data.d.ts +0 -32
  133. package/dist/types/src/models/customer-data.d.ts.map +0 -1
  134. package/dist/types/src/models/message-utils.d.ts +0 -13
  135. package/dist/types/src/models/message-utils.d.ts.map +0 -1
  136. package/dist/types/src/services/chat/conversation.d.ts +0 -23
  137. package/dist/types/src/services/chat/conversation.d.ts.map +0 -1
  138. package/dist/types/src/services/chat/message-utils.d.ts +0 -13
  139. package/dist/types/src/services/chat/message-utils.d.ts.map +0 -1
  140. package/dist/types/src/services/chat/model.d.ts +0 -28
  141. package/dist/types/src/services/chat/model.d.ts.map +0 -1
  142. package/dist/types/src/services/chatbot/chatbot.d.ts +0 -24
  143. package/dist/types/src/services/chatbot/chatbot.d.ts.map +0 -1
  144. package/dist/types/src/services/checker.d.ts +0 -4
  145. package/dist/types/src/services/checker.d.ts.map +0 -1
  146. package/dist/types/src/services/listeners/adders.d.ts +0 -4
  147. package/dist/types/src/services/listeners/adders.d.ts.map +0 -1
  148. package/dist/types/src/services/listeners/fn.d.ts +0 -4
  149. package/dist/types/src/services/listeners/fn.d.ts.map +0 -1
  150. package/dist/types/src/services/socket/utils.d.ts +0 -3
  151. package/dist/types/src/services/socket/utils.d.ts.map +0 -1
  152. package/dist/types/src/services/ui/fn.d.ts +0 -14
  153. package/dist/types/src/services/ui/fn.d.ts.map +0 -1
  154. package/dist/types/src/services/ui/html.d.ts +0 -4
  155. package/dist/types/src/services/ui/html.d.ts.map +0 -1
  156. package/dist/types/src/services/user/customer-data.d.ts +0 -32
  157. package/dist/types/src/services/user/customer-data.d.ts.map +0 -1
  158. package/dist/types/src/services/voice-chat/model.d.ts +0 -13
  159. package/dist/types/src/services/voice-chat/model.d.ts.map +0 -1
  160. package/dist/types/src/services/voice-chat/utils.d.ts +0 -10
  161. package/dist/types/src/services/voice-chat/utils.d.ts.map +0 -1
  162. package/dist/types/src/tools/fetch.d.ts +0 -3
  163. package/dist/types/src/tools/fetch.d.ts.map +0 -1
  164. package/dist/types/src/types/app.d.ts +0 -18
  165. package/dist/types/src/types/app.d.ts.map +0 -1
  166. package/dist/types/src/types/conversation.d.ts +0 -15
  167. package/dist/types/src/types/conversation.d.ts.map +0 -1
  168. package/dist/types/src/types/socket.d.ts +0 -7
  169. package/dist/types/src/types/socket.d.ts.map +0 -1
  170. package/dist/types/src/types/window.d.ts +0 -10
  171. package/dist/types/src/types/window.d.ts.map +0 -1
  172. package/dist/types/src/utils/audio.d.ts +0 -4
  173. package/dist/types/src/utils/audio.d.ts.map +0 -1
  174. package/dist/types/src/utils/browser.d.ts +0 -3
  175. package/dist/types/src/utils/browser.d.ts.map +0 -1
  176. package/dist/types/src/utils/fetch.d.ts +0 -19
  177. package/dist/types/src/utils/fetch.d.ts.map +0 -1
  178. package/dist/types/src/utils/uuid.d.ts +0 -7
  179. package/dist/types/src/utils/uuid.d.ts.map +0 -1
@@ -1,78 +1,78 @@
1
- import {Widget} from "#src/app.js";
2
- import {fetchUpdateUserData} from "#src/utils/fetch.js";
3
- import {generateUUID} from "#src/utils/uuid.js";
4
-
5
- class CustomerData {
6
- private _uniqueId?: string;
7
- private _userData?: Record<string, any>;
8
- private widget: Widget;
9
- phoneNumber?: string;
10
-
11
- constructor(widget: Widget, userData?: Record<string, any>) {
12
- this.widget = widget;
13
- this.initializeUniqueId();
14
- this.updateUserData(userData);
15
- this.initializePhoneNumber();
16
- }
17
-
18
- initializePhoneNumber() {
19
- const savedPhoneNumber = localStorage.getItem(`modo-chat:${this.widget.publicKey}-user-phone-number`);
20
- if (savedPhoneNumber) {
21
- this.phoneNumber = savedPhoneNumber;
22
- }
23
- }
24
-
25
- /**
26
- * Initialize unique ID from localStorage or generate a new one
27
- * Unique ID is independent of user key/data and is generated by ourselves
28
- */
29
- private initializeUniqueId(): void {
30
- const savedUniqueId = localStorage.getItem(`modo-chat:${this.widget.publicKey}-user-unique-id`);
31
-
32
- if (savedUniqueId) {
33
- this._uniqueId = savedUniqueId;
34
- } else {
35
- // Generate a new UUID if no saved unique ID exists
36
- this._uniqueId = crypto.randomUUID ? crypto.randomUUID() : generateUUID();
37
- localStorage.setItem(`modo-chat:${this.widget.publicKey}-user-unique-id`, this._uniqueId);
38
- }
39
- }
40
-
41
- /**
42
- * Get the current unique ID
43
- */
44
- get uniqueId(): string {
45
- return this._uniqueId!;
46
- }
47
-
48
- /**
49
- * Get the current user data
50
- */
51
- get userData(): Record<string, any> {
52
- return this._userData || {};
53
- }
54
-
55
- /**
56
- * Update user data with new values
57
- * @param newUserData - Object containing new user data to merge
58
- */
59
- async updateUserData(newUserData?: Record<string, any>): Promise<void> {
60
- if (newUserData && typeof newUserData === "object") {
61
- this._userData = newUserData;
62
- } else if (newUserData) console.warn("Invalid user data");
63
- }
64
-
65
- hasSubmittedPhoneForm(): boolean {
66
- return Boolean(this.phoneNumber);
67
- }
68
-
69
- savePhoneNumber(phoneNumber?: string) {
70
- this.phoneNumber = phoneNumber || "no phone number";
71
- localStorage.setItem(`modo-chat:${this.widget.publicKey}-user-phone-number`, phoneNumber || "no phone number");
72
- }
73
-
74
- async fetchUpdate() {
75
- await fetchUpdateUserData(this.widget.chatbot?.uuid as string, this.uniqueId, this.userData);
76
- }
77
- }
78
- export {CustomerData};
1
+ import {Widget} from "#src/app.js";
2
+ import {fetchUpdateUserData} from "#src/utils/fetch.js";
3
+ import {generateUUID} from "#src/utils/uuid.js";
4
+
5
+ class CustomerData {
6
+ private _uniqueId?: string;
7
+ private _userData?: Record<string, any>;
8
+ private widget: Widget;
9
+ phoneNumber?: string;
10
+
11
+ constructor(widget: Widget, userData?: Record<string, any>) {
12
+ this.widget = widget;
13
+ this.initializeUniqueId();
14
+ this.updateUserData(userData);
15
+ this.initializePhoneNumber();
16
+ }
17
+
18
+ initializePhoneNumber() {
19
+ const savedPhoneNumber = localStorage.getItem(`modo-chat:${this.widget.publicKey}-user-phone-number`);
20
+ if (savedPhoneNumber) {
21
+ this.phoneNumber = savedPhoneNumber;
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Initialize unique ID from localStorage or generate a new one
27
+ * Unique ID is independent of user key/data and is generated by ourselves
28
+ */
29
+ private initializeUniqueId(): void {
30
+ const savedUniqueId = localStorage.getItem(`modo-chat:${this.widget.publicKey}-user-unique-id`);
31
+
32
+ if (savedUniqueId) {
33
+ this._uniqueId = savedUniqueId;
34
+ } else {
35
+ // Generate a new UUID if no saved unique ID exists
36
+ this._uniqueId = crypto.randomUUID ? crypto.randomUUID() : generateUUID();
37
+ localStorage.setItem(`modo-chat:${this.widget.publicKey}-user-unique-id`, this._uniqueId);
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Get the current unique ID
43
+ */
44
+ get uniqueId(): string {
45
+ return this._uniqueId!;
46
+ }
47
+
48
+ /**
49
+ * Get the current user data
50
+ */
51
+ get userData(): Record<string, any> {
52
+ return this._userData || {};
53
+ }
54
+
55
+ /**
56
+ * Update user data with new values
57
+ * @param newUserData - Object containing new user data to merge
58
+ */
59
+ async updateUserData(newUserData?: Record<string, any>): Promise<void> {
60
+ if (newUserData && typeof newUserData === "object") {
61
+ this._userData = newUserData;
62
+ } else if (newUserData) console.warn("Invalid user data");
63
+ }
64
+
65
+ hasSubmittedPhoneForm(): boolean {
66
+ return Boolean(this.phoneNumber);
67
+ }
68
+
69
+ savePhoneNumber(phoneNumber?: string) {
70
+ this.phoneNumber = phoneNumber || "no phone number";
71
+ localStorage.setItem(`modo-chat:${this.widget.publicKey}-user-phone-number`, phoneNumber || "no phone number");
72
+ }
73
+
74
+ async fetchUpdate() {
75
+ await fetchUpdateUserData(this.widget.chatbot?.uuid as string, this.uniqueId, this.userData);
76
+ }
77
+ }
78
+ export {CustomerData};
@@ -1,79 +1,79 @@
1
- import {VoiceClient, EventType} from "@modochats/voice-client";
2
-
3
- import {
4
- initVoiceChatLayout,
5
- handleVoiceConnected,
6
- handleVoiceDisconnected,
7
- handleVoiceConnectionError,
8
- handleMicrophonePaused,
9
- handleMicrophoneResumed
10
- } from "./utils.js";
11
-
12
- class VoiceChat {
13
- instance?: VoiceClient;
14
- isFirstInSession: boolean = true;
15
- constructor() {
16
- const widget = window.getMWidget?.();
17
- this.instance = new VoiceClient({
18
- apiBase: "https://live.modochats.com",
19
- // apiBase: "http://localhost:8000",
20
- chatbotUuid: widget?.chatbot?.uuid as string,
21
- userUniqueId: widget?.customerData.uniqueId as string
22
- });
23
- this.instance.on(EventType.CONNECTED, (event: any) => {
24
- handleVoiceConnected();
25
- });
26
-
27
- this.instance.on(EventType.DISCONNECTED, (event: any) => {
28
- if (event.reason) {
29
- }
30
- handleVoiceDisconnected(event.reason);
31
- });
32
-
33
- this.instance.on(EventType.CONNECTION_ERROR, (event: any) => {
34
- // console.error("🔴 Connection Error:", event.message);
35
- handleVoiceConnectionError(event.message);
36
- });
37
-
38
- this.instance.on(EventType.MICROPHONE_PAUSED, () => {
39
- handleMicrophonePaused();
40
- });
41
-
42
- this.instance.on(EventType.MICROPHONE_RESUMED, () => {
43
- handleMicrophoneResumed();
44
- });
45
- // Initialize the voice agent UI
46
- this.initHtml();
47
-
48
- // session check
49
- const hasSeen = sessionStorage.getItem("modochats:voice-agent-seen") === "true";
50
- if (hasSeen) this.isFirstInSession = false;
51
- else sessionStorage.setItem("modochats:voice-agent-seen", "true");
52
- if (this.isFirstInSession) this.showTooltip();
53
- }
54
- async connect() {
55
- try {
56
- await this.instance?.connect();
57
- } catch (error) {
58
- // console.error("Failed to connect:", error);
59
- }
60
- }
61
- async disconnect() {
62
- await this.instance?.disconnect();
63
- }
64
- initHtml() {
65
- initVoiceChatLayout();
66
- }
67
- toggleLayout() {
68
- this.toggleLayout();
69
- }
70
-
71
- showTooltip() {
72
- const tooltip = document.querySelector(".mw-voice-call-tooltip");
73
- tooltip?.classList.remove("mw-hidden");
74
- setTimeout(() => {
75
- tooltip?.classList.add("mw-hidden");
76
- }, 6000);
77
- }
78
- }
79
- export {VoiceChat};
1
+ import {VoiceClient, EventType} from "@modochats/voice-client";
2
+
3
+ import {
4
+ initVoiceChatLayout,
5
+ handleVoiceConnected,
6
+ handleVoiceDisconnected,
7
+ handleVoiceConnectionError,
8
+ handleMicrophonePaused,
9
+ handleMicrophoneResumed
10
+ } from "./utils.js";
11
+
12
+ class VoiceChat {
13
+ instance?: VoiceClient;
14
+ isFirstInSession: boolean = true;
15
+ constructor() {
16
+ const widget = window.getMWidget?.();
17
+ this.instance = new VoiceClient({
18
+ apiBase: "https://live.modochats.com",
19
+ // apiBase: "http://localhost:8000",
20
+ chatbotUuid: widget?.chatbot?.uuid as string,
21
+ userUniqueId: widget?.customerData.uniqueId as string
22
+ });
23
+ this.instance.on(EventType.CONNECTED, (event: any) => {
24
+ handleVoiceConnected();
25
+ });
26
+
27
+ this.instance.on(EventType.DISCONNECTED, (event: any) => {
28
+ if (event.reason) {
29
+ }
30
+ handleVoiceDisconnected(event.reason);
31
+ });
32
+
33
+ this.instance.on(EventType.CONNECTION_ERROR, (event: any) => {
34
+ // console.error("🔴 Connection Error:", event.message);
35
+ handleVoiceConnectionError(event.message);
36
+ });
37
+
38
+ this.instance.on(EventType.MICROPHONE_PAUSED, () => {
39
+ handleMicrophonePaused();
40
+ });
41
+
42
+ this.instance.on(EventType.MICROPHONE_RESUMED, () => {
43
+ handleMicrophoneResumed();
44
+ });
45
+ // Initialize the voice agent UI
46
+ this.initHtml();
47
+
48
+ // session check
49
+ const hasSeen = sessionStorage.getItem("modochats:voice-agent-seen") === "true";
50
+ if (hasSeen) this.isFirstInSession = false;
51
+ else sessionStorage.setItem("modochats:voice-agent-seen", "true");
52
+ if (this.isFirstInSession) this.showTooltip();
53
+ }
54
+ async connect() {
55
+ try {
56
+ await this.instance?.connect();
57
+ } catch (error) {
58
+ // console.error("Failed to connect:", error);
59
+ }
60
+ }
61
+ async disconnect() {
62
+ await this.instance?.disconnect();
63
+ }
64
+ initHtml() {
65
+ initVoiceChatLayout();
66
+ }
67
+ toggleLayout() {
68
+ this.toggleLayout();
69
+ }
70
+
71
+ showTooltip() {
72
+ const tooltip = document.querySelector(".mw-voice-call-tooltip");
73
+ tooltip?.classList.remove("mw-hidden");
74
+ setTimeout(() => {
75
+ tooltip?.classList.add("mw-hidden");
76
+ }, 6000);
77
+ }
78
+ }
79
+ export {VoiceChat};
@@ -1,137 +1,137 @@
1
- function toggleVoiceChatLayout() {
2
- const widget = window.getMWidget?.();
3
- const voiceOverlay = widget?.container?.querySelector(".mw-voice-agent-overlay");
4
-
5
- if (voiceOverlay) {
6
- voiceOverlay.classList.toggle("mw-active");
7
- voiceOverlay.classList.toggle("mw-hidden");
8
- }
9
- }
10
-
11
- function initVoiceChatLayout() {
12
- const widget = window.getMWidget?.();
13
- const voiceOverlay = widget?.container?.querySelector(".mw-voice-agent-overlay");
14
- const voiceCloseBtn = voiceOverlay?.querySelector(".mw-voice-close-btn");
15
- const voiceDisconnectBtn = voiceOverlay?.querySelector(".mw-voice-disconnect-btn");
16
- const voiceCallBtn = widget?.container?.querySelector(".mw-voice-call-btn");
17
-
18
- // Show voice call button
19
- if (voiceCallBtn) {
20
- voiceCallBtn.classList.remove("mw-hidden");
21
- voiceCallBtn.classList.add("mw-visible");
22
- }
23
-
24
- // Set logo from chatbot data
25
- const logoImg = voiceOverlay?.querySelector(".mw-voice-agent-logo") as HTMLImageElement;
26
- if (logoImg && widget?.chatbot?.image) {
27
- logoImg.src = widget.chatbot.image;
28
- logoImg.alt = widget.chatbot.name || "چت بات";
29
- }
30
-
31
- // Set title
32
- const titleEl = voiceOverlay?.querySelector(".mw-voice-agent-title") as HTMLElement;
33
- if (titleEl) {
34
- titleEl.textContent = widget?.chatbot?.name || "تماس صوتی";
35
- }
36
-
37
- // Call button click handler
38
- voiceCallBtn?.addEventListener("click", () => {
39
- if (voiceOverlay) {
40
- voiceOverlay.classList.remove("mw-hidden");
41
- voiceOverlay.classList.add("mw-active");
42
- // Connect to voice instance
43
- widget?.voiceChat?.connect();
44
- }
45
- });
46
-
47
- // Close button click handler
48
- voiceCloseBtn?.addEventListener("click", () => {
49
- if (voiceOverlay) {
50
- voiceOverlay.classList.remove("mw-active");
51
- voiceOverlay.classList.add("mw-hidden");
52
- // Disconnect from voice instance
53
- widget?.voiceChat?.disconnect();
54
- }
55
- });
56
-
57
- // Disconnect button click handler
58
- voiceDisconnectBtn?.addEventListener("click", () => {
59
- if (voiceOverlay) {
60
- voiceOverlay.classList.remove("mw-active");
61
- voiceOverlay.classList.add("mw-hidden");
62
- // Disconnect from voice instance
63
- widget?.voiceChat?.disconnect();
64
- }
65
- });
66
- }
67
-
68
- function updateVoiceChatStatus(status: string, color?: string) {
69
- const widget = window.getMWidget?.();
70
- const statusEl = widget?.container?.querySelector(".mw-voice-agent-status") as HTMLElement;
71
-
72
- if (statusEl) {
73
- statusEl.textContent = status;
74
- if (color) {
75
- statusEl.style.color = color;
76
- }
77
- }
78
- }
79
-
80
- function handleVoiceConnected() {
81
- const widget = window.getMWidget?.();
82
- const logoEl = widget?.container?.querySelector(".mw-voice-agent-logo") as HTMLElement;
83
- const statusEl = widget?.container?.querySelector(".mw-voice-agent-status") as HTMLElement;
84
-
85
- // Add animation classes when connected
86
- if (logoEl) {
87
- logoEl.style.animation = "mw-voice-pulse 2s ease-in-out infinite";
88
- }
89
- if (statusEl) {
90
- statusEl.style.animation = "mw-pulse 1.5s ease-in-out infinite";
91
- }
92
-
93
- updateVoiceChatStatus("متصل ✓", "#68d391"); // Green
94
- }
95
-
96
- function handleVoiceDisconnected(reason?: string) {
97
- const widget = window.getMWidget?.();
98
- const logoEl = widget?.container?.querySelector(".mw-voice-agent-logo") as HTMLElement;
99
- const statusEl = widget?.container?.querySelector(".mw-voice-agent-status") as HTMLElement;
100
-
101
- // Remove animations when disconnected
102
- if (logoEl) {
103
- logoEl.style.animation = "none";
104
- }
105
- if (statusEl) {
106
- statusEl.style.animation = "none";
107
- }
108
-
109
- const statusText = reason ? `قطع شد: ${reason}` : "قطع شد";
110
- updateVoiceChatStatus(statusText, "#fc8181"); // Red
111
- }
112
-
113
- function handleVoiceConnectionError(message: string) {
114
- updateVoiceChatStatus(`خطا: ${message}`, "#fbb040"); // Warning/Orange
115
-
116
- // Also show error in console with better visibility
117
- console.error("🔴 Voice Connection Error:", message);
118
- }
119
-
120
- function handleMicrophonePaused() {
121
- updateVoiceChatStatus("⏸ میکروفن متوقف شد", "#fbb040"); // Orange
122
- }
123
-
124
- function handleMicrophoneResumed() {
125
- updateVoiceChatStatus("🎤 میکروفن فعال", "#68d391"); // Green
126
- }
127
-
128
- export {
129
- toggleVoiceChatLayout,
130
- initVoiceChatLayout,
131
- updateVoiceChatStatus,
132
- handleVoiceConnected,
133
- handleVoiceDisconnected,
134
- handleVoiceConnectionError,
135
- handleMicrophonePaused,
136
- handleMicrophoneResumed
137
- };
1
+ function toggleVoiceChatLayout() {
2
+ const widget = window.getMWidget?.();
3
+ const voiceOverlay = widget?.container?.querySelector(".mw-voice-agent-overlay");
4
+
5
+ if (voiceOverlay) {
6
+ voiceOverlay.classList.toggle("mw-active");
7
+ voiceOverlay.classList.toggle("mw-hidden");
8
+ }
9
+ }
10
+
11
+ function initVoiceChatLayout() {
12
+ const widget = window.getMWidget?.();
13
+ const voiceOverlay = widget?.container?.querySelector(".mw-voice-agent-overlay");
14
+ const voiceCloseBtn = voiceOverlay?.querySelector(".mw-voice-close-btn");
15
+ const voiceDisconnectBtn = voiceOverlay?.querySelector(".mw-voice-disconnect-btn");
16
+ const voiceCallBtn = widget?.container?.querySelector(".mw-voice-call-btn");
17
+
18
+ // Show voice call button
19
+ if (voiceCallBtn) {
20
+ voiceCallBtn.classList.remove("mw-hidden");
21
+ voiceCallBtn.classList.add("mw-visible");
22
+ }
23
+
24
+ // Set logo from chatbot data
25
+ const logoImg = voiceOverlay?.querySelector(".mw-voice-agent-logo") as HTMLImageElement;
26
+ if (logoImg && widget?.chatbot?.image) {
27
+ logoImg.src = widget.chatbot.image;
28
+ logoImg.alt = widget.chatbot.name || "چت بات";
29
+ }
30
+
31
+ // Set title
32
+ const titleEl = voiceOverlay?.querySelector(".mw-voice-agent-title") as HTMLElement;
33
+ if (titleEl) {
34
+ titleEl.textContent = widget?.chatbot?.name || "تماس صوتی";
35
+ }
36
+
37
+ // Call button click handler
38
+ voiceCallBtn?.addEventListener("click", () => {
39
+ if (voiceOverlay) {
40
+ voiceOverlay.classList.remove("mw-hidden");
41
+ voiceOverlay.classList.add("mw-active");
42
+ // Connect to voice instance
43
+ widget?.voiceChat?.connect();
44
+ }
45
+ });
46
+
47
+ // Close button click handler
48
+ voiceCloseBtn?.addEventListener("click", () => {
49
+ if (voiceOverlay) {
50
+ voiceOverlay.classList.remove("mw-active");
51
+ voiceOverlay.classList.add("mw-hidden");
52
+ // Disconnect from voice instance
53
+ widget?.voiceChat?.disconnect();
54
+ }
55
+ });
56
+
57
+ // Disconnect button click handler
58
+ voiceDisconnectBtn?.addEventListener("click", () => {
59
+ if (voiceOverlay) {
60
+ voiceOverlay.classList.remove("mw-active");
61
+ voiceOverlay.classList.add("mw-hidden");
62
+ // Disconnect from voice instance
63
+ widget?.voiceChat?.disconnect();
64
+ }
65
+ });
66
+ }
67
+
68
+ function updateVoiceChatStatus(status: string, color?: string) {
69
+ const widget = window.getMWidget?.();
70
+ const statusEl = widget?.container?.querySelector(".mw-voice-agent-status") as HTMLElement;
71
+
72
+ if (statusEl) {
73
+ statusEl.textContent = status;
74
+ if (color) {
75
+ statusEl.style.color = color;
76
+ }
77
+ }
78
+ }
79
+
80
+ function handleVoiceConnected() {
81
+ const widget = window.getMWidget?.();
82
+ const logoEl = widget?.container?.querySelector(".mw-voice-agent-logo") as HTMLElement;
83
+ const statusEl = widget?.container?.querySelector(".mw-voice-agent-status") as HTMLElement;
84
+
85
+ // Add animation classes when connected
86
+ if (logoEl) {
87
+ logoEl.style.animation = "mw-voice-pulse 2s ease-in-out infinite";
88
+ }
89
+ if (statusEl) {
90
+ statusEl.style.animation = "mw-pulse 1.5s ease-in-out infinite";
91
+ }
92
+
93
+ updateVoiceChatStatus("متصل ✓", "#68d391"); // Green
94
+ }
95
+
96
+ function handleVoiceDisconnected(reason?: string) {
97
+ const widget = window.getMWidget?.();
98
+ const logoEl = widget?.container?.querySelector(".mw-voice-agent-logo") as HTMLElement;
99
+ const statusEl = widget?.container?.querySelector(".mw-voice-agent-status") as HTMLElement;
100
+
101
+ // Remove animations when disconnected
102
+ if (logoEl) {
103
+ logoEl.style.animation = "none";
104
+ }
105
+ if (statusEl) {
106
+ statusEl.style.animation = "none";
107
+ }
108
+
109
+ const statusText = reason ? `قطع شد: ${reason}` : "قطع شد";
110
+ updateVoiceChatStatus(statusText, "#fc8181"); // Red
111
+ }
112
+
113
+ function handleVoiceConnectionError(message: string) {
114
+ updateVoiceChatStatus(`خطا: ${message}`, "#fbb040"); // Warning/Orange
115
+
116
+ // Also show error in console with better visibility
117
+ console.error("🔴 Voice Connection Error:", message);
118
+ }
119
+
120
+ function handleMicrophonePaused() {
121
+ updateVoiceChatStatus("⏸ میکروفن متوقف شد", "#fbb040"); // Orange
122
+ }
123
+
124
+ function handleMicrophoneResumed() {
125
+ updateVoiceChatStatus("🎤 میکروفن فعال", "#68d391"); // Green
126
+ }
127
+
128
+ export {
129
+ toggleVoiceChatLayout,
130
+ initVoiceChatLayout,
131
+ updateVoiceChatStatus,
132
+ handleVoiceConnected,
133
+ handleVoiceDisconnected,
134
+ handleVoiceConnectionError,
135
+ handleMicrophonePaused,
136
+ handleMicrophoneResumed
137
+ };
@@ -1,7 +1,7 @@
1
- import {BASE_API_URL} from "#src/constants/index.js";
2
- import {ofetch} from "ofetch";
3
-
4
- const $fetch = ofetch.create({
5
- baseURL: BASE_API_URL
6
- });
7
- export {$fetch};
1
+ import {BASE_API_URL} from "#src/constants/index.js";
2
+ import {ofetch} from "ofetch";
3
+
4
+ const $fetch = ofetch.create({
5
+ baseURL: BASE_API_URL
6
+ });
7
+ export {$fetch};
package/src/types/app.ts CHANGED
@@ -1,17 +1,17 @@
1
- interface WidgetOptions {
2
- position: "left" | "right";
3
- theme: "dark" | "light";
4
- primaryColor: string;
5
- title: string;
6
- foregroundColor: string;
7
- userData?: Record<string, any>;
8
- autoInit?: boolean;
9
- fullScreen: boolean;
10
- }
11
- interface FetchPaginationRes<T = any> {
12
- results: T[];
13
- next: string | null;
14
- prev: string | null;
15
- count: number;
16
- }
17
- export {WidgetOptions, FetchPaginationRes};
1
+ interface WidgetOptions {
2
+ position: "left" | "right";
3
+ theme: "dark" | "light";
4
+ primaryColor: string;
5
+ title: string;
6
+ foregroundColor: string;
7
+ userData?: Record<string, any>;
8
+ autoInit?: boolean;
9
+ fullScreen: boolean;
10
+ }
11
+ interface FetchPaginationRes<T = any> {
12
+ results: T[];
13
+ next: string | null;
14
+ prev: string | null;
15
+ count: number;
16
+ }
17
+ export {WidgetOptions, FetchPaginationRes};
@@ -1,14 +1,14 @@
1
- enum ConversationStatus {
2
- AI_CHAT,
3
- SUPPORTER_CHAT,
4
- RESOLVED,
5
- UNKNOWN
6
- }
7
- enum MessageType {
8
- USER,
9
- AI,
10
- SUPPORTER,
11
- SYSTEM,
12
- UNKNOWN
13
- }
14
- export type {ConversationStatus, MessageType};
1
+ enum ConversationStatus {
2
+ AI_CHAT,
3
+ SUPPORTER_CHAT,
4
+ RESOLVED,
5
+ UNKNOWN
6
+ }
7
+ enum MessageType {
8
+ USER,
9
+ AI,
10
+ SUPPORTER,
11
+ SYSTEM,
12
+ UNKNOWN
13
+ }
14
+ export type {ConversationStatus, MessageType};