ajaxter-chat 3.1.0 → 3.2.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/dist/components/ChatWidget.d.ts.map +1 -1
- package/dist/components/ChatWidget.js +302 -265
- package/dist/components/ChatWidget.js.map +1 -1
- package/dist/config/index.d.ts +6 -3
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +68 -22
- package/dist/config/index.js.map +1 -1
- package/dist/hooks/useRemoteConfig.d.ts.map +1 -1
- package/dist/hooks/useRemoteConfig.js +10 -7
- package/dist/hooks/useRemoteConfig.js.map +1 -1
- package/dist/hooks/useSocket.d.ts +23 -4
- package/dist/hooks/useSocket.d.ts.map +1 -1
- package/dist/hooks/useSocket.js +170 -157
- package/dist/hooks/useSocket.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +128 -48
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +8 -4
- package/src/components/ChatWidget.tsx +513 -514
- package/src/config/index.ts +87 -26
- package/src/hooks/useRemoteConfig.ts +8 -3
- package/src/hooks/useSocket.ts +187 -166
- package/src/index.ts +9 -3
- package/src/types/index.ts +177 -143
package/src/types/index.ts
CHANGED
|
@@ -1,208 +1,242 @@
|
|
|
1
|
-
// ───
|
|
1
|
+
// ─── Ajaxter Server Config Shape ─────────────────────────────────────────────
|
|
2
|
+
|
|
3
|
+
export interface AjaxterWidgetTheme {
|
|
4
|
+
header: { background: string; text: string };
|
|
5
|
+
agent: { messageBackground: string; messageText: string };
|
|
6
|
+
visitor: { messageBackground: string; messageText: string };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface AjaxterWidgetFeatures {
|
|
10
|
+
emoji: boolean;
|
|
11
|
+
rating: boolean;
|
|
12
|
+
transcript: boolean;
|
|
13
|
+
voice: boolean;
|
|
14
|
+
attachment: boolean;
|
|
15
|
+
webCall: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AjaxterMinimized {
|
|
19
|
+
desktop: { type: 'slide' | 'round' | 'square'; height?: number; width?: number; borderRadiusTop?: number; borderRadiusBottom?: number };
|
|
20
|
+
mobile: { type: 'round' | 'slide' | 'square' };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface AjaxterWidgetSettings {
|
|
24
|
+
type: 'inline' | 'popup' | 'embed';
|
|
25
|
+
language: string;
|
|
26
|
+
minimized: AjaxterMinimized;
|
|
27
|
+
maximized: { desktop: { height: number; width: number } };
|
|
28
|
+
theme: AjaxterWidgetTheme;
|
|
29
|
+
notification?: {
|
|
30
|
+
all?: { sound?: boolean; agentTyping?: boolean; visitorTyping?: boolean };
|
|
31
|
+
desktop?: { preview?: boolean };
|
|
32
|
+
mobile?: { preview?: boolean };
|
|
33
|
+
};
|
|
34
|
+
behavior?: { defaultView?: string };
|
|
35
|
+
visibility?: {
|
|
36
|
+
all?: { showWhenOffline?: boolean };
|
|
37
|
+
desktop?: { position?: string; show?: boolean };
|
|
38
|
+
mobile?: { position?: string; show?: boolean };
|
|
39
|
+
};
|
|
40
|
+
features: AjaxterWidgetFeatures;
|
|
41
|
+
scheduler?: { enabled: boolean; config?: unknown };
|
|
42
|
+
states?: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Internal fields that drive the npm widget behaviour */
|
|
46
|
+
export interface AjaxterInternalConfig {
|
|
47
|
+
id: string;
|
|
48
|
+
apiKey: string;
|
|
49
|
+
status: ChatStatus;
|
|
50
|
+
chatType: ChatType;
|
|
51
|
+
/** 'slider' = side drawer, 'popup' = centered modal, 'inline' = embedded in page */
|
|
52
|
+
displayMode: DisplayMode;
|
|
53
|
+
primaryColor: string;
|
|
54
|
+
buttonLabel: string;
|
|
55
|
+
brandName: string | null;
|
|
56
|
+
supportPhone: string | null;
|
|
57
|
+
privacyPolicyUrl: string | null;
|
|
58
|
+
showPrivacyNotice: boolean;
|
|
59
|
+
allowVoiceMessage: boolean;
|
|
60
|
+
allowAttachment: boolean;
|
|
61
|
+
allowEmoji: boolean;
|
|
62
|
+
allowWebCall: boolean;
|
|
63
|
+
maxEmojiCount: number;
|
|
64
|
+
allowTranscript: boolean;
|
|
65
|
+
allowReport: boolean;
|
|
66
|
+
allowBlock: boolean;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Full response shape from GET /api/chat-config */
|
|
70
|
+
export interface AjaxterConfigResponse {
|
|
71
|
+
ok: boolean;
|
|
72
|
+
data: {
|
|
73
|
+
settingsVersion: string;
|
|
74
|
+
propertyName: string;
|
|
75
|
+
branding: { name: string };
|
|
76
|
+
widget: AjaxterWidgetSettings;
|
|
77
|
+
_internal: AjaxterInternalConfig;
|
|
78
|
+
developers: ChatUser[];
|
|
79
|
+
users: ChatUser[];
|
|
80
|
+
sampleChats: Record<string, ChatMessage[]>;
|
|
81
|
+
sampleTickets: Ticket[];
|
|
82
|
+
blockedUsers: string[];
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** The merged WidgetConfig shape used throughout the widget components */
|
|
2
87
|
export interface WidgetConfig {
|
|
3
|
-
id:
|
|
4
|
-
apiKey:
|
|
5
|
-
status:
|
|
6
|
-
chatType:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
branch?:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* and lists customers; “New Conversation” lists other developers (excl. viewerUid).
|
|
21
|
-
*/
|
|
22
|
-
viewerType?: 'user' | 'developer';
|
|
23
|
-
/** Current user id when viewerType is developer — excluded from developer pick lists */
|
|
24
|
-
viewerUid?: string;
|
|
25
|
-
/** Display name for transfer notes (optional) */
|
|
26
|
-
viewerName?: string;
|
|
27
|
-
/**
|
|
28
|
-
* Host app project scope (set when embedding passes `viewer.projectId`).
|
|
29
|
-
* Use for API calls; lists can be filtered to users in the same project.
|
|
30
|
-
*/
|
|
31
|
-
viewerProjectId?: string;
|
|
32
|
-
/** Privacy Policy URL (linked from chat consent banner) */
|
|
88
|
+
id: string;
|
|
89
|
+
apiKey: string;
|
|
90
|
+
status: ChatStatus;
|
|
91
|
+
chatType: ChatType;
|
|
92
|
+
displayMode: DisplayMode;
|
|
93
|
+
primaryColor: string;
|
|
94
|
+
buttonLabel: string;
|
|
95
|
+
buttonPosition: 'bottom-right' | 'bottom-left';
|
|
96
|
+
welcomeTitle: string;
|
|
97
|
+
welcomeSubtitle: string;
|
|
98
|
+
branch?: string;
|
|
99
|
+
footerPoweredBy?: string;
|
|
100
|
+
supportPhone?: string;
|
|
101
|
+
viewerType?: 'user' | 'developer';
|
|
102
|
+
viewerUid?: string;
|
|
103
|
+
viewerName?: string;
|
|
104
|
+
viewerProjectId?: string;
|
|
33
105
|
privacyPolicyUrl?: string;
|
|
34
|
-
/** Set false to hide the consent note above the composer */
|
|
35
106
|
showPrivacyNotice?: boolean;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
websiteTourUrl?: string;
|
|
40
|
-
/** Optional override for the lead line in the promotion card */
|
|
41
|
-
promotionLead?: string;
|
|
107
|
+
brandName?: string;
|
|
108
|
+
websiteTourUrl?: string;
|
|
109
|
+
promotionLead?: string;
|
|
42
110
|
allowVoiceMessage: boolean;
|
|
43
|
-
allowAttachment:
|
|
44
|
-
allowEmoji:
|
|
45
|
-
allowWebCall:
|
|
46
|
-
maxEmojiCount:
|
|
111
|
+
allowAttachment: boolean;
|
|
112
|
+
allowEmoji: boolean;
|
|
113
|
+
allowWebCall: boolean;
|
|
114
|
+
maxEmojiCount: number;
|
|
47
115
|
allowTranscriptDownload: boolean;
|
|
48
|
-
allowReport:
|
|
49
|
-
allowBlock:
|
|
50
|
-
|
|
51
|
-
* When `true` (set by the server if this viewer is spam-blocked or not in allowed user/ticket/chat lists),
|
|
52
|
-
* the widget hides all normal navigation and shows only the blocked-user screen with a re-enable request form.
|
|
53
|
-
*/
|
|
54
|
-
viewerBlocked?: boolean;
|
|
55
|
-
/** Optional override for the blocked message (default is a fixed spam notice). */
|
|
116
|
+
allowReport: boolean;
|
|
117
|
+
allowBlock: boolean;
|
|
118
|
+
viewerBlocked?: boolean;
|
|
56
119
|
blockedViewerMessage?: string;
|
|
57
|
-
/**
|
|
58
|
-
* Absolute URL for `POST` JSON re-enable requests. If omitted, the submit button explains that no endpoint is configured.
|
|
59
|
-
* @example https://api.example.com/widgets/reenable-request
|
|
60
|
-
*/
|
|
61
120
|
reenableRequestUrl?: string;
|
|
62
|
-
|
|
63
|
-
* Current presence from your API/DB (include in chatData or a session payload).
|
|
64
|
-
* When set, it initializes the status control and overrides session-only cache.
|
|
65
|
-
*/
|
|
66
|
-
presenceStatus?: PresenceStatus;
|
|
67
|
-
/**
|
|
68
|
-
* Production: `POST` JSON `{ widgetId, apiKey, viewerUid?, status }` to save presence in your database.
|
|
69
|
-
* The client still mirrors to sessionStorage as a local fallback.
|
|
70
|
-
*/
|
|
121
|
+
presenceStatus?: PresenceStatus;
|
|
71
122
|
presenceUpdateUrl?: string;
|
|
123
|
+
/** Full Ajaxter settings from server (for display-mode, theming, etc.) */
|
|
124
|
+
ajaxterSettings?: AjaxterWidgetSettings;
|
|
72
125
|
}
|
|
73
126
|
|
|
74
127
|
export interface RemoteChatData {
|
|
75
|
-
widget:
|
|
76
|
-
developers:
|
|
77
|
-
users:
|
|
78
|
-
sampleChats:
|
|
128
|
+
widget: WidgetConfig;
|
|
129
|
+
developers: ChatUser[];
|
|
130
|
+
users: ChatUser[];
|
|
131
|
+
sampleChats: Record<string, ChatMessage[]>;
|
|
79
132
|
sampleTickets: Ticket[];
|
|
80
133
|
blockedUsers: string[];
|
|
81
134
|
}
|
|
82
135
|
|
|
83
|
-
// ─── Enums
|
|
136
|
+
// ─── Enums ───────────────────────────────────────────────────────────────────
|
|
84
137
|
export type ChatStatus = 'ACTIVE' | 'DISABLE' | 'MAINTENANCE';
|
|
85
138
|
export type ChatType = 'SUPPORT' | 'CHAT' | 'BOTH';
|
|
139
|
+
export type DisplayMode = 'slider' | 'popup' | 'inline';
|
|
86
140
|
export type UserType = 'developer' | 'user';
|
|
87
141
|
export type OnlineStatus = 'online' | 'away' | 'offline';
|
|
88
142
|
export type BottomTab = 'home' | 'chats' | 'tickets';
|
|
89
|
-
export type Screen
|
|
90
|
-
| 'home'
|
|
91
|
-
| '
|
|
92
|
-
| '
|
|
93
|
-
| 'recent-chats'
|
|
94
|
-
| 'tickets'
|
|
95
|
-
| 'ticket-new'
|
|
96
|
-
| 'ticket-detail'
|
|
97
|
-
| 'block-list'
|
|
98
|
-
| 'call';
|
|
143
|
+
export type Screen =
|
|
144
|
+
| 'home' | 'user-list' | 'chat' | 'recent-chats'
|
|
145
|
+
| 'tickets' | 'ticket-new' | 'ticket-detail'
|
|
146
|
+
| 'block-list' | 'call';
|
|
99
147
|
export type UserListContext = 'support' | 'conversation';
|
|
100
148
|
export type MessageType = 'text' | 'voice' | 'attachment' | 'emoji';
|
|
101
|
-
|
|
102
|
-
/** Home status selector; persist via `presenceUpdateUrl` in production */
|
|
103
149
|
export type PresenceStatus = 'ACTIVE' | 'AWAY' | 'DND';
|
|
104
150
|
|
|
105
|
-
// ─── User
|
|
151
|
+
// ─── User ────────────────────────────────────────────────────────────────────
|
|
106
152
|
export interface ChatUser {
|
|
107
|
-
uid:
|
|
108
|
-
name:
|
|
109
|
-
email:
|
|
110
|
-
mobile:
|
|
111
|
-
project:
|
|
112
|
-
type:
|
|
113
|
-
avatar:
|
|
114
|
-
status:
|
|
153
|
+
uid: string;
|
|
154
|
+
name: string;
|
|
155
|
+
email: string;
|
|
156
|
+
mobile: string;
|
|
157
|
+
project: string;
|
|
158
|
+
type: UserType;
|
|
159
|
+
avatar: string | null;
|
|
160
|
+
status: OnlineStatus;
|
|
115
161
|
designation: string;
|
|
116
|
-
/**
|
|
117
|
-
* When `true` for the row matching the current viewer (`viewerUid` / `viewer.uid`),
|
|
118
|
-
* the widget shows the spam/blocked screen (same as `widget.viewerBlocked`).
|
|
119
|
-
*/
|
|
120
162
|
viewerBlocked?: boolean;
|
|
121
163
|
}
|
|
122
164
|
|
|
123
|
-
// ─── Message
|
|
165
|
+
// ─── Message ─────────────────────────────────────────────────────────────────
|
|
124
166
|
export interface ChatMessage {
|
|
125
|
-
id:
|
|
126
|
-
senderId:
|
|
127
|
-
receiverId:
|
|
128
|
-
text:
|
|
129
|
-
timestamp:
|
|
130
|
-
type:
|
|
131
|
-
status:
|
|
167
|
+
id: string;
|
|
168
|
+
senderId: string;
|
|
169
|
+
receiverId: string;
|
|
170
|
+
text: string;
|
|
171
|
+
timestamp: string;
|
|
172
|
+
type: MessageType;
|
|
173
|
+
status: 'sent' | 'delivered' | 'read';
|
|
132
174
|
attachmentName?: string;
|
|
133
175
|
attachmentSize?: string;
|
|
134
|
-
|
|
135
|
-
attachmentUrl?: string;
|
|
136
|
-
/** e.g. image/png — used for inline image preview in bubbles */
|
|
176
|
+
attachmentUrl?: string;
|
|
137
177
|
attachmentMime?: string;
|
|
138
|
-
voiceDuration?:
|
|
139
|
-
|
|
140
|
-
voiceUrl?: string;
|
|
178
|
+
voiceDuration?: number;
|
|
179
|
+
voiceUrl?: string;
|
|
141
180
|
}
|
|
142
181
|
|
|
143
|
-
// ─── Ticket
|
|
182
|
+
// ─── Ticket ──────────────────────────────────────────────────────────────────
|
|
144
183
|
export interface Ticket {
|
|
145
|
-
id:
|
|
146
|
-
title:
|
|
184
|
+
id: string;
|
|
185
|
+
title: string;
|
|
147
186
|
description: string;
|
|
148
|
-
status:
|
|
149
|
-
priority:
|
|
150
|
-
createdAt:
|
|
151
|
-
updatedAt:
|
|
152
|
-
assignedTo:
|
|
187
|
+
status: 'open' | 'in-progress' | 'resolved' | 'closed';
|
|
188
|
+
priority: 'low' | 'medium' | 'high';
|
|
189
|
+
createdAt: string;
|
|
190
|
+
updatedAt: string;
|
|
191
|
+
assignedTo: string | null;
|
|
153
192
|
}
|
|
154
193
|
|
|
155
194
|
// ─── Recent Chat ─────────────────────────────────────────────────────────────
|
|
156
195
|
export interface RecentChat {
|
|
157
|
-
id:
|
|
158
|
-
user:
|
|
196
|
+
id: string;
|
|
197
|
+
user: ChatUser;
|
|
159
198
|
lastMessage: string;
|
|
160
|
-
lastTime:
|
|
161
|
-
unread:
|
|
162
|
-
isPaused:
|
|
199
|
+
lastTime: string;
|
|
200
|
+
unread: number;
|
|
201
|
+
isPaused: boolean;
|
|
163
202
|
}
|
|
164
203
|
|
|
165
|
-
// ─── Call
|
|
204
|
+
// ─── Call ────────────────────────────────────────────────────────────────────
|
|
166
205
|
export type CallState = 'idle' | 'calling' | 'connected' | 'ended';
|
|
167
|
-
|
|
168
206
|
export interface CallSession {
|
|
169
|
-
state:
|
|
170
|
-
peer:
|
|
171
|
-
startedAt:
|
|
172
|
-
isMuted:
|
|
207
|
+
state: CallState;
|
|
208
|
+
peer: ChatUser | null;
|
|
209
|
+
startedAt: Date | null;
|
|
210
|
+
isMuted: boolean;
|
|
173
211
|
isCameraOn: boolean;
|
|
174
212
|
}
|
|
175
213
|
|
|
176
214
|
// ─── Local env config ────────────────────────────────────────────────────────
|
|
177
215
|
export interface LocalEnvConfig {
|
|
178
|
-
apiKey:
|
|
216
|
+
apiKey: string;
|
|
179
217
|
widgetId: string;
|
|
218
|
+
socketUrl: string;
|
|
180
219
|
}
|
|
181
220
|
|
|
182
|
-
// ─── Theme prop
|
|
221
|
+
// ─── Theme prop ──────────────────────────────────────────────────────────────
|
|
183
222
|
export interface ChatWidgetTheme {
|
|
184
|
-
primaryColor?:
|
|
185
|
-
fontFamily?:
|
|
186
|
-
buttonColor?:
|
|
223
|
+
primaryColor?: string;
|
|
224
|
+
fontFamily?: string;
|
|
225
|
+
buttonColor?: string;
|
|
187
226
|
buttonTextColor?: string;
|
|
188
|
-
buttonLabel?:
|
|
189
|
-
buttonPosition?:
|
|
190
|
-
borderRadius?:
|
|
227
|
+
buttonLabel?: string;
|
|
228
|
+
buttonPosition?: 'bottom-right' | 'bottom-left';
|
|
229
|
+
borderRadius?: string;
|
|
191
230
|
}
|
|
192
231
|
|
|
193
|
-
/**
|
|
194
|
-
* Pass the logged-in user from your React app so the widget matches identity and UI (user vs developer).
|
|
195
|
-
* Overrides `viewerUid`, `viewerName`, `viewerType` from remote `chatData.json` when provided.
|
|
196
|
-
*/
|
|
197
232
|
export interface ChatWidgetViewer {
|
|
198
|
-
uid:
|
|
199
|
-
name:
|
|
200
|
-
type:
|
|
201
|
-
/** When set, directory lists only include users whose `ChatUser.project` equals this string (exact match). */
|
|
233
|
+
uid: string;
|
|
234
|
+
name: string;
|
|
235
|
+
type: UserType;
|
|
202
236
|
projectId?: string;
|
|
203
237
|
}
|
|
204
238
|
|
|
205
239
|
export interface ChatWidgetProps {
|
|
206
|
-
theme?:
|
|
240
|
+
theme?: ChatWidgetTheme;
|
|
207
241
|
viewer?: ChatWidgetViewer;
|
|
208
242
|
}
|