ajaxter-chat 3.0.1 → 3.0.4
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/config/index.d.ts +5 -1
- package/dist/config/index.js +29 -14
- package/dist/hooks/useRemoteConfig.js +8 -4
- package/dist/hooks/useWebRTC.d.ts +2 -2
- package/package.json +1 -1
- package/src/components/CallScreen/index.tsx +2 -2
- package/src/config/index.ts +29 -13
- package/src/hooks/useRemoteConfig.ts +8 -2
package/dist/config/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { LocalEnvConfig, RemoteChatData } from '../types';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Loads remote widget config once via GET. Uses query params `key` and `widget` so the
|
|
4
|
+
* server can validate the request without custom headers (avoids CORS preflight failures).
|
|
5
|
+
*/
|
|
3
6
|
export declare function fetchRemoteChatData(apiKey: string, widgetId: string): Promise<RemoteChatData>;
|
|
7
|
+
export declare function loadLocalConfig(): LocalEnvConfig;
|
package/dist/config/index.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Default JSON endpoint. Override with `REACT_APP_CHAT_CONFIG_URL` / `NEXT_PUBLIC_CHAT_CONFIG_URL`.
|
|
3
|
+
* If the remote host does not send CORS headers, set this to a same-origin path (e.g. `/api/chat-config`)
|
|
4
|
+
* and proxy the JSON from your server — see `examples/next-app-router-chat-proxy.ts`.
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_CHAT_DATA_BASE = 'https://window.mscorpres.com/TEST/chatData.json';
|
|
2
7
|
const DEMO_API_KEY = 'demo1234';
|
|
3
8
|
const DEMO_WIDGET_ID = 'demo';
|
|
4
9
|
function getEnv(key) {
|
|
@@ -8,23 +13,33 @@ function getEnv(key) {
|
|
|
8
13
|
}
|
|
9
14
|
return undefined;
|
|
10
15
|
}
|
|
11
|
-
|
|
12
|
-
var _a
|
|
13
|
-
return
|
|
14
|
-
apiKey: (_a = getEnv('CHAT_API_KEY')) !== null && _a !== void 0 ? _a : DEMO_API_KEY,
|
|
15
|
-
widgetId: (_b = getEnv('CHAT_WIDGET_ID')) !== null && _b !== void 0 ? _b : DEMO_WIDGET_ID,
|
|
16
|
-
};
|
|
16
|
+
function getChatDataBaseUrl() {
|
|
17
|
+
var _a;
|
|
18
|
+
return ((_a = getEnv('CHAT_CONFIG_URL')) === null || _a === void 0 ? void 0 : _a.trim()) || DEFAULT_CHAT_DATA_BASE;
|
|
17
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Loads remote widget config once via GET. Uses query params `key` and `widget` so the
|
|
22
|
+
* server can validate the request without custom headers (avoids CORS preflight failures).
|
|
23
|
+
*/
|
|
18
24
|
export async function fetchRemoteChatData(apiKey, widgetId) {
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
const base = getChatDataBaseUrl();
|
|
26
|
+
const url = new URL(base, typeof window !== 'undefined' ? window.location.origin : 'https://localhost');
|
|
27
|
+
url.searchParams.set('key', apiKey);
|
|
28
|
+
url.searchParams.set('widget', widgetId);
|
|
29
|
+
const res = await fetch(url.toString(), {
|
|
30
|
+
method: 'GET',
|
|
31
|
+
credentials: 'omit',
|
|
32
|
+
mode: 'cors',
|
|
33
|
+
headers: { Accept: 'application/json' },
|
|
26
34
|
});
|
|
27
35
|
if (!res.ok)
|
|
28
36
|
throw new Error(`Failed to load chat config: ${res.status}`);
|
|
29
37
|
return res.json();
|
|
30
38
|
}
|
|
39
|
+
export function loadLocalConfig() {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
return {
|
|
42
|
+
apiKey: (_a = getEnv('CHAT_API_KEY')) !== null && _a !== void 0 ? _a : DEMO_API_KEY,
|
|
43
|
+
widgetId: (_b = getEnv('CHAT_WIDGET_ID')) !== null && _b !== void 0 ? _b : DEMO_WIDGET_ID,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -10,12 +10,16 @@ export function useRemoteConfig(apiKey, widgetId) {
|
|
|
10
10
|
fetchRemoteChatData(apiKey, widgetId)
|
|
11
11
|
.then(d => { if (!cancelled) {
|
|
12
12
|
setData(d);
|
|
13
|
+
setError(null);
|
|
13
14
|
setLoading(false);
|
|
14
15
|
} })
|
|
15
|
-
.catch(e => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
.catch(e => {
|
|
17
|
+
if (!cancelled) {
|
|
18
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
19
|
+
setError(msg || 'Network error while loading configuration');
|
|
20
|
+
setLoading(false);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
19
23
|
return () => { cancelled = true; };
|
|
20
24
|
}, [apiKey, widgetId]);
|
|
21
25
|
return { data, loading, error };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CallSession, ChatUser } from '../types';
|
|
2
2
|
export declare function useWebRTC(): {
|
|
3
3
|
session: CallSession;
|
|
4
|
-
localVideoRef: import("react").
|
|
5
|
-
remoteVideoRef: import("react").
|
|
4
|
+
localVideoRef: import("react").MutableRefObject<HTMLVideoElement | null>;
|
|
5
|
+
remoteVideoRef: import("react").MutableRefObject<HTMLVideoElement | null>;
|
|
6
6
|
startCall: (peer: ChatUser, withVideo?: boolean) => Promise<void>;
|
|
7
7
|
acceptCall: (offer: RTCSessionDescriptionInit, peer: ChatUser, withVideo?: boolean) => Promise<void>;
|
|
8
8
|
endCall: () => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ajaxter-chat",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.4",
|
|
4
4
|
"description": "Drawer-based chat widget with support chat, tickets, WebRTC calling, voice messages, block list, and transcript download.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -38,12 +38,12 @@ export const CallScreen: React.FC<CallScreenProps> = ({
|
|
|
38
38
|
position:'relative', overflow:'hidden',
|
|
39
39
|
}}>
|
|
40
40
|
{/* Remote video (background) */}
|
|
41
|
-
<video ref={remoteVideoRef} autoPlay playsInline
|
|
41
|
+
<video ref={remoteVideoRef as React.Ref<HTMLVideoElement>} autoPlay playsInline
|
|
42
42
|
style={{ position:'absolute', inset:0, width:'100%', height:'100%', objectFit:'cover', opacity: session.state==='connected'?1:0 }}
|
|
43
43
|
/>
|
|
44
44
|
|
|
45
45
|
{/* Local video (PiP) */}
|
|
46
|
-
<video ref={localVideoRef} autoPlay playsInline muted
|
|
46
|
+
<video ref={localVideoRef as React.Ref<HTMLVideoElement>} autoPlay playsInline muted
|
|
47
47
|
style={{
|
|
48
48
|
position:'absolute', bottom:120, right:14,
|
|
49
49
|
width:90, height:120, borderRadius:10,
|
package/src/config/index.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { LocalEnvConfig, RemoteChatData } from '../types';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Default JSON endpoint. Override with `REACT_APP_CHAT_CONFIG_URL` / `NEXT_PUBLIC_CHAT_CONFIG_URL`.
|
|
5
|
+
* If the remote host does not send CORS headers, set this to a same-origin path (e.g. `/api/chat-config`)
|
|
6
|
+
* and proxy the JSON from your server — see `examples/next-app-router-chat-proxy.ts`.
|
|
7
|
+
*/
|
|
8
|
+
const DEFAULT_CHAT_DATA_BASE = 'https://window.mscorpres.com/TEST/chatData.json';
|
|
4
9
|
const DEMO_API_KEY = 'demo1234';
|
|
5
10
|
const DEMO_WIDGET_ID = 'demo';
|
|
6
11
|
|
|
@@ -16,25 +21,36 @@ function getEnv(key: string): string | undefined {
|
|
|
16
21
|
return undefined;
|
|
17
22
|
}
|
|
18
23
|
|
|
19
|
-
|
|
20
|
-
return
|
|
21
|
-
apiKey: getEnv('CHAT_API_KEY') ?? DEMO_API_KEY,
|
|
22
|
-
widgetId: getEnv('CHAT_WIDGET_ID') ?? DEMO_WIDGET_ID,
|
|
23
|
-
};
|
|
24
|
+
function getChatDataBaseUrl(): string {
|
|
25
|
+
return getEnv('CHAT_CONFIG_URL')?.trim() || DEFAULT_CHAT_DATA_BASE;
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Loads remote widget config once via GET. Uses query params `key` and `widget` so the
|
|
30
|
+
* server can validate the request without custom headers (avoids CORS preflight failures).
|
|
31
|
+
*/
|
|
26
32
|
export async function fetchRemoteChatData(
|
|
27
33
|
apiKey: string,
|
|
28
34
|
widgetId: string
|
|
29
35
|
): Promise<RemoteChatData> {
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
const base = getChatDataBaseUrl();
|
|
37
|
+
const url = new URL(base, typeof window !== 'undefined' ? window.location.origin : 'https://localhost');
|
|
38
|
+
url.searchParams.set('key', apiKey);
|
|
39
|
+
url.searchParams.set('widget', widgetId);
|
|
40
|
+
|
|
41
|
+
const res = await fetch(url.toString(), {
|
|
42
|
+
method: 'GET',
|
|
43
|
+
credentials: 'omit',
|
|
44
|
+
mode: 'cors',
|
|
45
|
+
headers: { Accept: 'application/json' },
|
|
37
46
|
});
|
|
38
47
|
if (!res.ok) throw new Error(`Failed to load chat config: ${res.status}`);
|
|
39
48
|
return res.json() as Promise<RemoteChatData>;
|
|
40
49
|
}
|
|
50
|
+
|
|
51
|
+
export function loadLocalConfig(): LocalEnvConfig {
|
|
52
|
+
return {
|
|
53
|
+
apiKey: getEnv('CHAT_API_KEY') ?? DEMO_API_KEY,
|
|
54
|
+
widgetId: getEnv('CHAT_WIDGET_ID') ?? DEMO_WIDGET_ID,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -11,8 +11,14 @@ export function useRemoteConfig(apiKey: string, widgetId: string) {
|
|
|
11
11
|
let cancelled = false;
|
|
12
12
|
setLoading(true);
|
|
13
13
|
fetchRemoteChatData(apiKey, widgetId)
|
|
14
|
-
.then(d => { if (!cancelled) { setData(d); setLoading(false); } })
|
|
15
|
-
.catch(e => {
|
|
14
|
+
.then(d => { if (!cancelled) { setData(d); setError(null); setLoading(false); } })
|
|
15
|
+
.catch(e => {
|
|
16
|
+
if (!cancelled) {
|
|
17
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
18
|
+
setError(msg || 'Network error while loading configuration');
|
|
19
|
+
setLoading(false);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
16
22
|
return () => { cancelled = true; };
|
|
17
23
|
}, [apiKey, widgetId]);
|
|
18
24
|
|