ajaxter-chat 3.0.1 → 3.0.3

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.
@@ -1,3 +1,7 @@
1
1
  import { LocalEnvConfig, RemoteChatData } from '../types';
2
- export declare function loadLocalConfig(): LocalEnvConfig;
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;
@@ -1,4 +1,5 @@
1
- const REMOTE_URL = 'https://window.mscorpres.com/TEST/chatData.json';
1
+ /** Default JSON endpoint; override with REACT_APP_CHAT_CONFIG_URL / NEXT_PUBLIC_CHAT_CONFIG_URL */
2
+ const DEFAULT_CHAT_DATA_BASE = 'https://window.mscorpres.com/TEST/chatData.json';
2
3
  const DEMO_API_KEY = 'demo1234';
3
4
  const DEMO_WIDGET_ID = 'demo';
4
5
  function getEnv(key) {
@@ -8,23 +9,33 @@ function getEnv(key) {
8
9
  }
9
10
  return undefined;
10
11
  }
11
- export function loadLocalConfig() {
12
- var _a, _b;
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
- };
12
+ function getChatDataBaseUrl() {
13
+ var _a;
14
+ return ((_a = getEnv('CHAT_CONFIG_URL')) === null || _a === void 0 ? void 0 : _a.trim()) || DEFAULT_CHAT_DATA_BASE;
17
15
  }
16
+ /**
17
+ * Loads remote widget config once via GET. Uses query params `key` and `widget` so the
18
+ * server can validate the request without custom headers (avoids CORS preflight failures).
19
+ */
18
20
  export async function fetchRemoteChatData(apiKey, widgetId) {
19
- const url = REMOTE_URL;
20
- const res = await fetch(url, {
21
- headers: {
22
- 'X-Chat-Api-Key': apiKey,
23
- 'X-Chat-Widget-Id': widgetId,
24
- 'Content-Type': 'application/json',
25
- },
21
+ const base = getChatDataBaseUrl();
22
+ const url = new URL(base, typeof window !== 'undefined' ? window.location.origin : 'https://localhost');
23
+ url.searchParams.set('key', apiKey);
24
+ url.searchParams.set('widget', widgetId);
25
+ const res = await fetch(url.toString(), {
26
+ method: 'GET',
27
+ credentials: 'omit',
28
+ mode: 'cors',
29
+ headers: { Accept: 'application/json' },
26
30
  });
27
31
  if (!res.ok)
28
32
  throw new Error(`Failed to load chat config: ${res.status}`);
29
33
  return res.json();
30
34
  }
35
+ export function loadLocalConfig() {
36
+ var _a, _b;
37
+ return {
38
+ apiKey: (_a = getEnv('CHAT_API_KEY')) !== null && _a !== void 0 ? _a : DEMO_API_KEY,
39
+ widgetId: (_b = getEnv('CHAT_WIDGET_ID')) !== null && _b !== void 0 ? _b : DEMO_WIDGET_ID,
40
+ };
41
+ }
@@ -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 => { if (!cancelled) {
16
- setError(e.message);
17
- setLoading(false);
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").RefObject<HTMLVideoElement | null>;
5
- remoteVideoRef: import("react").RefObject<HTMLVideoElement | null>;
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.1",
3
+ "version": "3.0.3",
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,
@@ -1,6 +1,7 @@
1
1
  import { LocalEnvConfig, RemoteChatData } from '../types';
2
2
 
3
- const REMOTE_URL = 'https://window.mscorpres.com/TEST/chatData.json';
3
+ /** Default JSON endpoint; override with REACT_APP_CHAT_CONFIG_URL / NEXT_PUBLIC_CHAT_CONFIG_URL */
4
+ const DEFAULT_CHAT_DATA_BASE = 'https://window.mscorpres.com/TEST/chatData.json';
4
5
  const DEMO_API_KEY = 'demo1234';
5
6
  const DEMO_WIDGET_ID = 'demo';
6
7
 
@@ -16,25 +17,36 @@ function getEnv(key: string): string | undefined {
16
17
  return undefined;
17
18
  }
18
19
 
19
- export function loadLocalConfig(): LocalEnvConfig {
20
- return {
21
- apiKey: getEnv('CHAT_API_KEY') ?? DEMO_API_KEY,
22
- widgetId: getEnv('CHAT_WIDGET_ID') ?? DEMO_WIDGET_ID,
23
- };
20
+ function getChatDataBaseUrl(): string {
21
+ return getEnv('CHAT_CONFIG_URL')?.trim() || DEFAULT_CHAT_DATA_BASE;
24
22
  }
25
23
 
24
+ /**
25
+ * Loads remote widget config once via GET. Uses query params `key` and `widget` so the
26
+ * server can validate the request without custom headers (avoids CORS preflight failures).
27
+ */
26
28
  export async function fetchRemoteChatData(
27
29
  apiKey: string,
28
30
  widgetId: string
29
31
  ): Promise<RemoteChatData> {
30
- const url = REMOTE_URL;
31
- const res = await fetch(url, {
32
- headers: {
33
- 'X-Chat-Api-Key': apiKey,
34
- 'X-Chat-Widget-Id': widgetId,
35
- 'Content-Type': 'application/json',
36
- },
32
+ const base = getChatDataBaseUrl();
33
+ const url = new URL(base, typeof window !== 'undefined' ? window.location.origin : 'https://localhost');
34
+ url.searchParams.set('key', apiKey);
35
+ url.searchParams.set('widget', widgetId);
36
+
37
+ const res = await fetch(url.toString(), {
38
+ method: 'GET',
39
+ credentials: 'omit',
40
+ mode: 'cors',
41
+ headers: { Accept: 'application/json' },
37
42
  });
38
43
  if (!res.ok) throw new Error(`Failed to load chat config: ${res.status}`);
39
44
  return res.json() as Promise<RemoteChatData>;
40
45
  }
46
+
47
+ export function loadLocalConfig(): LocalEnvConfig {
48
+ return {
49
+ apiKey: getEnv('CHAT_API_KEY') ?? DEMO_API_KEY,
50
+ widgetId: getEnv('CHAT_WIDGET_ID') ?? DEMO_WIDGET_ID,
51
+ };
52
+ }
@@ -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 => { if (!cancelled) { setError(e.message); setLoading(false); } });
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