@ethora/chat-component 26.10.7 → 26.10.8
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/README.md +88 -3
- package/dist/ChatProfileModal-83t5BRkI.js +2298 -0
- package/dist/{FilePreviewModal-DlOjnYzv.js → FilePreviewModal-DxUGjSHe.js} +130 -130
- package/dist/{ManageDataModal-BZLGJZze.js → ManageDataModal-DFE_Wegj.js} +14 -14
- package/dist/{MarkdownBody-CtArwCDa.js → MarkdownBody-uFITrPjT.js} +1 -1
- package/dist/{MessageSearchModal-CcUnfZlU.js → MessageSearchModal-CsbTWgNm.js} +32 -32
- package/dist/{PublicChatsModal-BWn0NXVo.js → PublicChatsModal-bDOp3IL9.js} +19 -19
- package/dist/{SideDrawer-CqZl9sxK.js → SideDrawer-A_1ECqD2.js} +28 -28
- package/dist/{UserProfileModal-D0JZ3-uy.js → UserProfileModal-Ca5wHYvr.js} +124 -120
- package/dist/{UserSettingsModal-OvykYDsT.js → UserSettingsModal-CAyyQGV6.js} +2 -2
- package/dist/{VideoCallOverlay-DrvO2v_g.js → VideoCallOverlay-BMiQh8kI.js} +5908 -4168
- package/dist/{VisibilityModal-pOF9-UXR.js → VisibilityModal-BXyIy7_J.js} +7 -7
- package/dist/assets/icons.d.ts +4 -0
- package/dist/calls/callDisplay.d.ts +22 -0
- package/dist/calls/callMode.d.ts +105 -0
- package/dist/calls/openScheduledCall.d.ts +20 -0
- package/dist/calls/p2p/P2PCallController.d.ts +160 -0
- package/dist/calls/p2p/icePolicy.d.ts +36 -0
- package/dist/calls/p2p/negotiator.d.ts +56 -0
- package/dist/calls/p2p/p2pRuntime.d.ts +35 -0
- package/dist/calls/p2p/signalInbox.d.ts +34 -0
- package/dist/calls/p2p/signalStanza.d.ts +51 -0
- package/dist/calls/placeCall.d.ts +20 -0
- package/dist/calls/scheduledCall.d.ts +101 -0
- package/dist/calls/scheduledCallActions.d.ts +12 -0
- package/dist/calls/scheduledCallFormat.d.ts +13 -0
- package/dist/calls/scheduledCallsConfig.d.ts +27 -0
- package/dist/calls/senderTrust.d.ts +7 -0
- package/dist/calls/startCall.d.ts +16 -0
- package/dist/components/MainComponents/ChatWrapper.d.ts +1 -0
- package/dist/components/MainComponents/LoginWrapper.d.ts +1 -0
- package/dist/components/MainComponents/ProfileImagePlaceholder.d.ts +1 -0
- package/dist/components/MainComponents/ReduxWrapper.d.ts +6 -0
- package/dist/components/MenuRoom/MenuRoom.d.ts +1 -0
- package/dist/components/Modals/NewChatModal/styledNewChatComponents.d.ts +27 -0
- package/dist/components/Modals/styledModalComponents.d.ts +21 -0
- package/dist/components/ScheduledCalls/ScheduleCallModal.d.ts +3 -0
- package/dist/components/ScheduledCalls/ScheduledCallCancelConfirm.d.ts +8 -0
- package/dist/components/ScheduledCalls/ScheduledCallCard.d.ts +7 -0
- package/dist/components/ScheduledCalls/ScheduledCallLayer.d.ts +15 -0
- package/dist/components/ScheduledCalls/ScheduledCallPreJoin.d.ts +3 -0
- package/dist/components/VideoCalls/P2PCallRunner.d.ts +1 -0
- package/dist/components/VideoCalls/P2PCallSession.d.ts +14 -0
- package/dist/components/VideoCalls/VideoCallSession.d.ts +37 -0
- package/dist/{handleCopyClick-BUbVvd2G.js → handleCopyClick-BX1fcFGN.js} +1 -1
- package/dist/helpers/callPush.d.ts +2 -0
- package/dist/helpers/canLeaveRoom.d.ts +3 -0
- package/dist/helpers/chatComponentConfigEvents.d.ts +16 -0
- package/dist/helpers/liveConfig.d.ts +46 -0
- package/dist/helpers/reportRoom.d.ts +18 -0
- package/dist/helpers/scheduledCallMessage.d.ts +23 -0
- package/dist/helpers/storeConsole.d.ts +1 -0
- package/dist/hooks/useNow.d.ts +6 -0
- package/dist/hooks/useRemoteAppearance.d.ts +21 -0
- package/dist/hooks/useTypography.d.ts +4 -0
- package/dist/{main-CpHMnydn.js → main-B25iFKAC.js} +15794 -13324
- package/dist/main.d.ts +3 -1
- package/dist/main.js +28 -26
- package/dist/networking/api-requests/callState.api.d.ts +24 -0
- package/dist/networking/api-requests/remoteAppearance.api.d.ts +20 -0
- package/dist/networking/api-requests/rooms.api.d.ts +2 -1
- package/dist/networking/api-requests/scheduledCalls.api.d.ts +19 -0
- package/dist/networking/ethoraEvents.d.ts +14 -1
- package/dist/networking/xmpp/notifyXmppEvent.d.ts +6 -0
- package/dist/roomStore/callSlice.d.ts +23 -1
- package/dist/roomStore/chatSettingsSlice.d.ts +9 -1
- package/dist/roomStore/index.d.ts +4 -0
- package/dist/roomStore/scheduledCallSlice.d.ts +47 -0
- package/dist/types/models/config.model.d.ts +71 -1
- package/dist/types/models/message.model.d.ts +2 -0
- package/dist/types/models/room.model.d.ts +2 -0
- package/dist/types/models/scheduledCall.model.d.ts +116 -0
- package/package.json +1 -1
- package/dist/ChatProfileModal-BDZvd0rm.js +0 -2168
package/dist/main.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export { useRoomMute } from './hooks/useRoomMute';
|
|
|
14
14
|
export type { UseRoomMuteResult } from './hooks/useRoomMute';
|
|
15
15
|
export { parseQuickReplies } from './helpers/quickReplies';
|
|
16
16
|
export type { QuickReply } from './helpers/quickReplies';
|
|
17
|
+
export { openScheduledCall, parseScheduledCallLink } from './calls/openScheduledCall';
|
|
17
18
|
export { applyTypography, clearTypography } from './helpers/applyTypography';
|
|
18
19
|
export { useTypography } from './hooks/useTypography';
|
|
19
20
|
export type { TypographyConfig, FontFaceSource, } from './types/models/config.model';
|
|
@@ -22,7 +23,8 @@ export { ChatInputTestIds, MessageBubbleTestIds, RoomListTestIds, AuthTestIds, }
|
|
|
22
23
|
export { refreshAuthTokens, refreshAuthTokensQuietly, RefreshFatalError, isRefreshFatalError, } from './networking/authRefresh';
|
|
23
24
|
export type { RefreshErrorCode, RefreshResult, RefreshOptions, } from './networking/authRefresh';
|
|
24
25
|
export type { ChatWrapperProps as ChatProps } from './components/MainComponents/ReduxWrapper';
|
|
25
|
-
export type { IConfig } from './types/models/config.model';
|
|
26
|
+
export type { IConfig, XmppMessageEvent } from './types/models/config.model';
|
|
27
|
+
export type { ScheduledCallsConfig, ScheduledCallOpenError, ScheduledCall, ScheduledCallKind, } from './types/models/scheduledCall.model';
|
|
26
28
|
export type { VideoCallsConfig, VideoCallIcons, FBConfig, } from './types/models/config.model';
|
|
27
29
|
export type { User, IUser, ConfigUser, StorageUser, } from './types/models/user.model';
|
|
28
30
|
export type { IMessage, IReply, LastMessage, MessageProps, MediaMessageType, ReactionMessage, } from './types/models/message.model';
|
package/dist/main.js
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bS as a, bT as r, bU as o, bV as t, bW as c, bX as u, bY as p, bZ as h, b_ as i, b$ as l, c0 as n, v as d, c1 as b, af as T, c2 as f, c3 as m, c4 as y, c5 as I, c6 as R, c7 as g, c8 as C, c9 as Q, ca as k, cb as A, cc as E, aP as P, aQ as S, cd as v, ce as F } from "./main-B25iFKAC.js";
|
|
2
2
|
export {
|
|
3
|
-
|
|
3
|
+
a as AuthTestIds,
|
|
4
4
|
r as Chat,
|
|
5
5
|
o as ChatInputTestIds,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
g as
|
|
23
|
-
C as
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
A as
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
6
|
+
t as MessageBubbleTestIds,
|
|
7
|
+
c as RefreshFatalError,
|
|
8
|
+
u as RoomListTestIds,
|
|
9
|
+
p as XmppProvider,
|
|
10
|
+
h as applyTypography,
|
|
11
|
+
i as clearTypography,
|
|
12
|
+
l as formatFingerprint,
|
|
13
|
+
n as handleQRChatId,
|
|
14
|
+
d as isE2eeEnabled,
|
|
15
|
+
b as isRefreshFatalError,
|
|
16
|
+
T as logoutService,
|
|
17
|
+
f as omemo,
|
|
18
|
+
m as openScheduledCall,
|
|
19
|
+
y as parseQuickReplies,
|
|
20
|
+
I as parseScheduledCallLink,
|
|
21
|
+
R as refreshAuthTokens,
|
|
22
|
+
g as refreshAuthTokensQuietly,
|
|
23
|
+
C as resendMessage,
|
|
24
|
+
Q as useInAppNotifications,
|
|
25
|
+
k as useIsUserOnline,
|
|
26
|
+
A as usePushNotifications,
|
|
27
|
+
E as useQRCodeChat,
|
|
28
|
+
P as useRoomMute,
|
|
29
|
+
S as useRoomPresence,
|
|
30
|
+
v as useTypography,
|
|
31
|
+
F as useUnread
|
|
30
32
|
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { IceServerConfig } from '../../calls/callMode';
|
|
2
|
+
/** Callee: the incoming UI is on screen. */
|
|
3
|
+
export declare const reportCallRinging: (callId: string | null) => void;
|
|
4
|
+
/** Callee: the user rejected the call. The server relays it to the caller. */
|
|
5
|
+
export declare const reportCallDeclined: (callId: string | null) => void;
|
|
6
|
+
/** Media is flowing (ICE connected). Starts the server-side call timer. */
|
|
7
|
+
export declare const reportCallConnected: (callId: string | null) => void;
|
|
8
|
+
/**
|
|
9
|
+
* A ringing or connected call ended for any reason. Idempotent on the server
|
|
10
|
+
* (a second report returns `ended:false`), so both peers may send it.
|
|
11
|
+
*/
|
|
12
|
+
export declare const reportCallEnded: (callId: string | null) => void;
|
|
13
|
+
export interface IceServersResponse {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
iceServers: IceServerConfig[];
|
|
16
|
+
ttlSeconds: number | null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* GET /v1/calls/ice-servers: fresh STUN/TURN credentials. Used by a callee
|
|
20
|
+
* whose call-token carried no `ice` list, and to refresh the (ephemeral)
|
|
21
|
+
* credentials before an ICE restart. Returns null on any failure so callers
|
|
22
|
+
* can carry on with the servers they already have.
|
|
23
|
+
*/
|
|
24
|
+
export declare function fetchIceServers(): Promise<IceServersResponse | null>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { RemoteConfigRecord } from '../../helpers/liveConfig';
|
|
2
|
+
export interface RemoteAppearanceSnapshot {
|
|
3
|
+
record: RemoteConfigRecord;
|
|
4
|
+
/** `'0'` when the App never saved anything. */
|
|
5
|
+
version: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const isValidRemoteAppId: (appId: unknown) => appId is string;
|
|
8
|
+
export declare const remoteAppearanceUrl: (baseUrl: string | undefined, appId: string, version?: string) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Reads the App's public chat component config. Unauthenticated on purpose
|
|
11
|
+
* (no token, no cookies, no refresh logic): it is the same public endpoint
|
|
12
|
+
* the web app reads at load. Pass the `version` the server announced to get
|
|
13
|
+
* past the endpoint's 30 s cache. Throws on a network or HTTP failure; the
|
|
14
|
+
* caller keeps what it has.
|
|
15
|
+
*/
|
|
16
|
+
export declare function fetchRemoteAppearance(opts: {
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
appId: string;
|
|
19
|
+
version?: string;
|
|
20
|
+
}, signal?: AbortSignal): Promise<RemoteAppearanceSnapshot>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApiRoom, DeleteRoomMember, PostAddRoomMember, PostReportRoom, PostRoom, RoomMember } from '../../types/types';
|
|
2
|
+
import { CallCreateResult } from '../../calls/callMode';
|
|
2
3
|
export interface BlockedUserEntry {
|
|
3
4
|
_id: string;
|
|
4
5
|
firstName?: string;
|
|
@@ -58,4 +59,4 @@ export declare function deleteRoom(name: string): Promise<any>;
|
|
|
58
59
|
export declare function declineChatCall(callId: string): Promise<boolean>;
|
|
59
60
|
export declare function createChatCall(chatName: string, options?: {
|
|
60
61
|
kind?: 'audio' | 'video';
|
|
61
|
-
}): Promise<
|
|
62
|
+
}): Promise<CallCreateResult>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CreateScheduledCallInput, ScheduledCall, ScheduledCallDetails, ScheduledCallOpenError, ScheduledCallWithLinks, UpdateScheduledCallInput } from '../../types/models/scheduledCall.model';
|
|
2
|
+
/** What went wrong, in the terms the UI needs. */
|
|
3
|
+
export declare class ScheduledCallApiError extends Error {
|
|
4
|
+
readonly status: number | null;
|
|
5
|
+
readonly reason: ScheduledCallOpenError;
|
|
6
|
+
/** The server's own `code` (or `error`) string, when it sent one. */
|
|
7
|
+
readonly code: string | null;
|
|
8
|
+
constructor(status: number | null, reason: ScheduledCallOpenError, code: string | null);
|
|
9
|
+
}
|
|
10
|
+
export declare function createScheduledCall(input: CreateScheduledCallInput): Promise<ScheduledCallWithLinks>;
|
|
11
|
+
export declare function listScheduledCalls(params: {
|
|
12
|
+
chatName: string;
|
|
13
|
+
from?: string;
|
|
14
|
+
to?: string;
|
|
15
|
+
}): Promise<ScheduledCallWithLinks[]>;
|
|
16
|
+
/** GET one call by slug. 404 -> `not-found`, 403 -> `not-a-member`. */
|
|
17
|
+
export declare function getScheduledCall(slug: string): Promise<ScheduledCallDetails>;
|
|
18
|
+
export declare function updateScheduledCall(slug: string, patch: UpdateScheduledCallInput): Promise<ScheduledCallWithLinks>;
|
|
19
|
+
export declare function cancelScheduledCall(slug: string): Promise<ScheduledCall>;
|
|
@@ -5,6 +5,13 @@ import { Element } from 'ltx';
|
|
|
5
5
|
*
|
|
6
6
|
* user-profile-updated xmppUsername="<appId>_<userId>" uuid appId
|
|
7
7
|
* chat-meta-updated chatName="<appId>_<roomId>" appId
|
|
8
|
+
* chat-component-config-updated appId version
|
|
9
|
+
*
|
|
10
|
+
* The last one is how a change in the admin's Chat component tab reaches
|
|
11
|
+
* open chats. The server sends it to every online session of its XMPP host
|
|
12
|
+
* in one go (ejabberd `announce/online`), so it arrives FROM the bare server
|
|
13
|
+
* domain and for any App on the host: it is only acted on when `appId` is
|
|
14
|
+
* this session's own App.
|
|
8
15
|
*
|
|
9
16
|
* The payload is a pointer only. The client re-reads the user or the room
|
|
10
17
|
* through the normal API, so nothing in the stanza is ever shown or stored.
|
|
@@ -13,6 +20,7 @@ import { Element } from 'ltx';
|
|
|
13
20
|
export declare const ETHORA_EVENT_XMLNS = "urn:ethora:events:1";
|
|
14
21
|
export declare const ETHORA_EVENT_USER_PROFILE = "user-profile-updated";
|
|
15
22
|
export declare const ETHORA_EVENT_CHAT_META = "chat-meta-updated";
|
|
23
|
+
export declare const ETHORA_EVENT_CHAT_COMPONENT_CONFIG = "chat-component-config-updated";
|
|
16
24
|
type HostLike = {
|
|
17
25
|
host?: string;
|
|
18
26
|
client?: {
|
|
@@ -30,8 +38,13 @@ type HostLike = {
|
|
|
30
38
|
* - when config.trustedEventSenders is set, the sender must be listed
|
|
31
39
|
* The server's admin local part is deployment config (XMPP_ADMIN), so it
|
|
32
40
|
* cannot be hard-coded here.
|
|
41
|
+
*
|
|
42
|
+
* `allowServerDomain` also accepts the bare server domain itself as the
|
|
43
|
+
* sender (what ejabberd stamps on a host-wide announcement). A client cannot
|
|
44
|
+
* send as the domain: the server fixes `from` on every client stanza. A
|
|
45
|
+
* pinned `trustedEventSenders` list then has to name the domain.
|
|
33
46
|
*/
|
|
34
|
-
export declare const isTrustedEventSender: (stanza: Element, xmppWs: HostLike | undefined) => boolean;
|
|
47
|
+
export declare const isTrustedEventSender: (stanza: Element, xmppWs: HostLike | undefined, allowServerDomain?: boolean) => boolean;
|
|
35
48
|
/**
|
|
36
49
|
* Handles `<ethora-event>` headlines. Returns true when the stanza carried
|
|
37
50
|
* one (trusted or not), so the caller can stop routing it. Unknown types,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CallMode, IceServerConfig } from '../calls/callMode';
|
|
1
2
|
export type CallPhase = 'idle' | 'requesting' | 'ringing-incoming' | 'connecting' | 'in-call' | 'error';
|
|
2
3
|
export type CallDirection = 'outgoing' | 'incoming' | null;
|
|
3
4
|
export type CallKind = 'audio' | 'video';
|
|
@@ -16,6 +17,12 @@ export interface CallState {
|
|
|
16
17
|
error: string | null;
|
|
17
18
|
startedAt: number | null;
|
|
18
19
|
connectedAt: number | null;
|
|
20
|
+
mode: CallMode;
|
|
21
|
+
isGroup: boolean;
|
|
22
|
+
livekitUrl: string | null;
|
|
23
|
+
iceServers: IceServerConfig[] | null;
|
|
24
|
+
callerName: string | null;
|
|
25
|
+
callerXmppUsername: string | null;
|
|
19
26
|
}
|
|
20
27
|
export declare const startOutgoingCall: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
21
28
|
roomJid: string;
|
|
@@ -23,6 +30,7 @@ export declare const startOutgoingCall: import('@reduxjs/toolkit').ActionCreator
|
|
|
23
30
|
roomBareName?: string | null;
|
|
24
31
|
kind?: CallKind;
|
|
25
32
|
peerXmppUsername?: string | null;
|
|
33
|
+
isGroup?: boolean;
|
|
26
34
|
}, "call/startOutgoingCall">, setIncomingCallToken: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
27
35
|
roomJid: string;
|
|
28
36
|
roomName?: string | null;
|
|
@@ -31,11 +39,25 @@ export declare const startOutgoingCall: import('@reduxjs/toolkit').ActionCreator
|
|
|
31
39
|
kind?: CallKind;
|
|
32
40
|
callId?: string | null;
|
|
33
41
|
peerXmppUsername?: string | null;
|
|
42
|
+
mode?: CallMode;
|
|
43
|
+
isGroup?: boolean;
|
|
44
|
+
iceServers?: IceServerConfig[] | null;
|
|
45
|
+
livekitUrl?: string | null;
|
|
46
|
+
callerName?: string | null;
|
|
47
|
+
callerXmppUsername?: string | null;
|
|
34
48
|
}, "call/setIncomingCallToken">, setOutgoingCallToken: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
35
49
|
roomJid: string;
|
|
36
50
|
token: string;
|
|
37
51
|
callId?: string | null;
|
|
38
|
-
|
|
52
|
+
livekitUrl?: string | null;
|
|
53
|
+
}, "call/setOutgoingCallToken">, setOutgoingCallRoute: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
54
|
+
startedAt: number | null;
|
|
55
|
+
callId: string | null;
|
|
56
|
+
mode: CallMode;
|
|
57
|
+
group?: boolean | null;
|
|
58
|
+
livekitUrl?: string | null;
|
|
59
|
+
iceServers?: IceServerConfig[] | null;
|
|
60
|
+
}, "call/setOutgoingCallRoute">, acceptIncomingCall: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"call/acceptIncomingCall">, declineIncomingCall: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"call/declineIncomingCall">, endCall: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"call/endCall">, setCallError: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<string, "call/setCallError">, setCallPhase: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<CallPhase, "call/setCallPhase">, setCallKind: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<CallKind, "call/setCallKind">, setCallE2eeKey: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
39
61
|
key: string;
|
|
40
62
|
callId: string | null;
|
|
41
63
|
}, "call/setCallE2eeKey">, resetCall: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"call/resetCall">;
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { DeleteModal, IConfig, Iso639_1Codes, IUser, ModalFile, ModalType, User } from '../types/types';
|
|
2
|
+
import { RemoteConfigRecord } from '../helpers/liveConfig';
|
|
2
3
|
interface ChatState {
|
|
3
4
|
user: User;
|
|
4
5
|
config?: IConfig;
|
|
6
|
+
/**
|
|
7
|
+
* The operator-saved look read for `config.remoteAppearance` (validated,
|
|
8
|
+
* live keys only). Kept next to `config` so that whoever writes `config`
|
|
9
|
+
* (the chat, the provider, the init hook) gets it laid over their value,
|
|
10
|
+
* and one writer cannot undo what another applied. Not persisted.
|
|
11
|
+
*/
|
|
12
|
+
remoteConfig?: RemoteConfigRecord | null;
|
|
5
13
|
appId?: string;
|
|
6
14
|
activeModal?: ModalType;
|
|
7
15
|
deleteModal?: DeleteModal;
|
|
@@ -34,7 +42,7 @@ interface ChatState {
|
|
|
34
42
|
translateMode?: 'auto' | 'manual';
|
|
35
43
|
blockedUserIds: string[];
|
|
36
44
|
}
|
|
37
|
-
export declare const setUser: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<User, "chatSettingStore/setUser">, setConfig: import('@reduxjs/toolkit').ActionCreatorWithNonInferrablePayload<"chatSettingStore/setConfig">, refreshTokens: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
45
|
+
export declare const setUser: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<User, "chatSettingStore/setUser">, setConfig: import('@reduxjs/toolkit').ActionCreatorWithNonInferrablePayload<"chatSettingStore/setConfig">, setRemoteConfig: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<RemoteConfigRecord, "chatSettingStore/setRemoteConfig">, refreshTokens: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
38
46
|
token: string;
|
|
39
47
|
refreshToken: string;
|
|
40
48
|
fileToken?: string;
|
|
@@ -62,11 +62,13 @@ declare const rootReducer: Reducer<{
|
|
|
62
62
|
rooms: Record<string, any> & import('redux-persist/es/persistReducer').PersistPartial;
|
|
63
63
|
roomHeapSlice: import('./roomHeapSlice').roomHeapSliceState;
|
|
64
64
|
call: import('immer').WritableDraft<import('./callSlice').CallState>;
|
|
65
|
+
scheduledCall: import('immer').WritableDraft<import('./scheduledCallSlice').ScheduledCallState>;
|
|
65
66
|
}, import('redux').UnknownAction, Partial<{
|
|
66
67
|
chatSettingStore: Record<string, any> & import('redux-persist/es/persistReducer').PersistPartial;
|
|
67
68
|
rooms: Record<string, any> & import('redux-persist/es/persistReducer').PersistPartial;
|
|
68
69
|
roomHeapSlice: import('./roomHeapSlice').roomHeapSliceState;
|
|
69
70
|
call: import('immer').WritableDraft<import('./callSlice').CallState>;
|
|
71
|
+
scheduledCall: import('immer').WritableDraft<import('./scheduledCallSlice').ScheduledCallState>;
|
|
70
72
|
}>>;
|
|
71
73
|
export type RootState = ReturnType<typeof rootReducer>;
|
|
72
74
|
export declare const getActiveRoom: (state: RootState) => IRoom | null;
|
|
@@ -75,12 +77,14 @@ export declare const store: import('@reduxjs/toolkit').EnhancedStore<{
|
|
|
75
77
|
rooms: Record<string, any> & import('redux-persist/es/persistReducer').PersistPartial;
|
|
76
78
|
roomHeapSlice: import('./roomHeapSlice').roomHeapSliceState;
|
|
77
79
|
call: import('immer').WritableDraft<import('./callSlice').CallState>;
|
|
80
|
+
scheduledCall: import('immer').WritableDraft<import('./scheduledCallSlice').ScheduledCallState>;
|
|
78
81
|
}, AnyAction, import('@reduxjs/toolkit').Tuple<[import('redux').StoreEnhancer<{
|
|
79
82
|
dispatch: import('redux-thunk').ThunkDispatch<{
|
|
80
83
|
chatSettingStore: Record<string, any> & import('redux-persist/es/persistReducer').PersistPartial;
|
|
81
84
|
rooms: Record<string, any> & import('redux-persist/es/persistReducer').PersistPartial;
|
|
82
85
|
roomHeapSlice: import('./roomHeapSlice').roomHeapSliceState;
|
|
83
86
|
call: import('immer').WritableDraft<import('./callSlice').CallState>;
|
|
87
|
+
scheduledCall: import('immer').WritableDraft<import('./scheduledCallSlice').ScheduledCallState>;
|
|
84
88
|
}, undefined, import('redux').UnknownAction>;
|
|
85
89
|
}>, import('redux').StoreEnhancer]>>;
|
|
86
90
|
export type AppDispatch = typeof store.dispatch;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ScheduledCallDetails, ScheduledCallOpenError } from '../types/models/scheduledCall.model';
|
|
2
|
+
export interface ScheduledCallDetailsEntry {
|
|
3
|
+
status: 'loading' | 'ready' | 'error';
|
|
4
|
+
data?: ScheduledCallDetails;
|
|
5
|
+
error?: ScheduledCallOpenError;
|
|
6
|
+
}
|
|
7
|
+
export interface ScheduledCallState {
|
|
8
|
+
/** A slug somebody asked to open (host prop or openScheduledCall). */
|
|
9
|
+
openRequest: {
|
|
10
|
+
slug: string;
|
|
11
|
+
requestedAt: number;
|
|
12
|
+
} | null;
|
|
13
|
+
/** The call whose pre-join panel is on screen. */
|
|
14
|
+
preJoin: ScheduledCallDetails | null;
|
|
15
|
+
/** The schedule form; `editing` set means edit mode. */
|
|
16
|
+
scheduleModal: {
|
|
17
|
+
roomJid: string;
|
|
18
|
+
editing: ScheduledCallDetails | null;
|
|
19
|
+
} | null;
|
|
20
|
+
/** The "cancel this call?" confirmation (mounted by the layer, outside the message list). */
|
|
21
|
+
cancelModal: {
|
|
22
|
+
slug: string;
|
|
23
|
+
title: string;
|
|
24
|
+
} | null;
|
|
25
|
+
/** Server copy of the calls the cards show, by slug. */
|
|
26
|
+
details: Record<string, ScheduledCallDetailsEntry>;
|
|
27
|
+
/** The last open request that failed, for the in-chat error notice. */
|
|
28
|
+
openError: {
|
|
29
|
+
slug: string;
|
|
30
|
+
reason: ScheduledCallOpenError;
|
|
31
|
+
} | null;
|
|
32
|
+
}
|
|
33
|
+
export declare const requestOpenScheduledCall: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<string, "scheduledCall/requestOpenScheduledCall">, clearOpenRequest: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"scheduledCall/clearOpenRequest">, setOpenError: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
34
|
+
slug: string;
|
|
35
|
+
reason: ScheduledCallOpenError;
|
|
36
|
+
}, "scheduledCall/setOpenError">, openPreJoin: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<ScheduledCallDetails, "scheduledCall/openPreJoin">, closePreJoin: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"scheduledCall/closePreJoin">, openScheduleModal: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
37
|
+
roomJid: string;
|
|
38
|
+
editing?: ScheduledCallDetails | null;
|
|
39
|
+
}, "scheduledCall/openScheduleModal">, closeScheduleModal: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"scheduledCall/closeScheduleModal">, openCancelModal: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
40
|
+
slug: string;
|
|
41
|
+
title: string;
|
|
42
|
+
}, "scheduledCall/openCancelModal">, closeCancelModal: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"scheduledCall/closeCancelModal">, detailsLoading: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<string, "scheduledCall/detailsLoading">, detailsLoaded: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<ScheduledCallDetails, "scheduledCall/detailsLoaded">, detailsFailed: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
43
|
+
slug: string;
|
|
44
|
+
reason: ScheduledCallOpenError;
|
|
45
|
+
}, "scheduledCall/detailsFailed">, forgetDetails: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<string, "scheduledCall/forgetDetails">;
|
|
46
|
+
declare const _default: import('redux').Reducer<import('immer').WritableDraft<ScheduledCallState>>;
|
|
47
|
+
export default _default;
|
|
@@ -3,6 +3,7 @@ import { xmppSettingsInterface } from './xmpp.model';
|
|
|
3
3
|
import { ConfigRoom } from './room.model';
|
|
4
4
|
import { MessageProps, IMessage } from './message.model';
|
|
5
5
|
import { Iso639_1Codes } from './language.model';
|
|
6
|
+
import { ScheduledCallsConfig } from './scheduledCall.model';
|
|
6
7
|
import { QuickReply } from '../../helpers/quickReplies';
|
|
7
8
|
import { default as React } from 'react';
|
|
8
9
|
import { MessageNotificationToastProps } from '../../components/MessageNotification/MessageNotificationToast';
|
|
@@ -27,7 +28,15 @@ export interface VideoCallIcons {
|
|
|
27
28
|
export interface VideoCallsConfig {
|
|
28
29
|
enabled: boolean;
|
|
29
30
|
livekitUrl: string;
|
|
30
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Room types that can start and receive calls. Defaults to
|
|
33
|
+
* `['private', 'group']`: 1:1 chats plus members-only group chats (group
|
|
34
|
+
* calls always run over LiveKit and need a backend that accepts them; on an
|
|
35
|
+
* older backend the call fails with an error). Pass `['private']` to keep
|
|
36
|
+
* calls 1:1 only. The 1:1 transport (own WebRTC peer to peer, or LiveKit) is
|
|
37
|
+
* chosen by the server per call, not by this config.
|
|
38
|
+
*/
|
|
39
|
+
allowedRoomTypes?: Array<'private' | 'group'>;
|
|
31
40
|
/**
|
|
32
41
|
* Show the audio-only call button next to the video-call button. Off by
|
|
33
42
|
* default: it's a separate opt-in feature. An audio call uses the same call
|
|
@@ -152,6 +161,15 @@ export interface ChatErrorInfo {
|
|
|
152
161
|
componentStack?: string;
|
|
153
162
|
scope: ChatErrorScope;
|
|
154
163
|
}
|
|
164
|
+
/** An incoming XMPP `<message/>` stanza received by the SDK. */
|
|
165
|
+
export interface XmppMessageEvent {
|
|
166
|
+
/** The complete stanza as XML, including its message payload. */
|
|
167
|
+
stanza: string;
|
|
168
|
+
from?: string;
|
|
169
|
+
to?: string;
|
|
170
|
+
id?: string;
|
|
171
|
+
type?: string;
|
|
172
|
+
}
|
|
155
173
|
/**
|
|
156
174
|
* Render-prop form of `fallbackScreens.error`. `reset()` clears the boundary
|
|
157
175
|
* and re-mounts the chat subtree, so a host can build its own "try again".
|
|
@@ -646,6 +664,13 @@ export interface IConfig {
|
|
|
646
664
|
filterFunction: (text: string) => string;
|
|
647
665
|
};
|
|
648
666
|
eventHandlers?: {
|
|
667
|
+
/**
|
|
668
|
+
* Called once for every incoming XMPP `<message/>` stanza, before the
|
|
669
|
+
* SDK routes it to chat, archive, call, or protocol handlers. `stanza`
|
|
670
|
+
* contains the raw XML; on end-to-end encrypted messages it may still be
|
|
671
|
+
* encrypted. A thrown error or rejected promise is caught and logged.
|
|
672
|
+
*/
|
|
673
|
+
onXmppEvent?: (event: XmppMessageEvent) => void | Promise<void>;
|
|
649
674
|
onMessageSent?: (event: {
|
|
650
675
|
message: string;
|
|
651
676
|
roomJID: string;
|
|
@@ -690,6 +715,23 @@ export interface IConfig {
|
|
|
690
715
|
* inside this handler is caught and logged, never rethrown.
|
|
691
716
|
*/
|
|
692
717
|
onError?: (event: ChatErrorInfo) => void;
|
|
718
|
+
/**
|
|
719
|
+
* Called when the server announces that the App's chat component config
|
|
720
|
+
* (the admin's Chat component tab) changed: an `ethora-event` headline of
|
|
721
|
+
* type `chat-component-config-updated` from the server. The event carries
|
|
722
|
+
* no values, only the App id and an opaque `version`; read the config
|
|
723
|
+
* again (`GET /v2/chat-component/config?appId=<appId>&v=<version>`, the
|
|
724
|
+
* `v` steps around the endpoint's 30 s cache) and pass the result in
|
|
725
|
+
* `config`, or set `config.remoteAppearance` and let the chat do both.
|
|
726
|
+
*
|
|
727
|
+
* Fires once per version, for the signed-in session's own App only
|
|
728
|
+
* (`config.appId`, or `remoteAppearance.appId`), a few hundred ms after
|
|
729
|
+
* the last of a burst. A throw inside it is caught and logged.
|
|
730
|
+
*/
|
|
731
|
+
onChatComponentConfigUpdated?: (event: {
|
|
732
|
+
appId: string;
|
|
733
|
+
version: string;
|
|
734
|
+
}) => void;
|
|
693
735
|
};
|
|
694
736
|
disableTypingIndicator?: boolean;
|
|
695
737
|
blockMessageSendingWhenProcessing?: boolean | {
|
|
@@ -743,6 +785,28 @@ export interface IConfig {
|
|
|
743
785
|
* (`admin`).
|
|
744
786
|
*/
|
|
745
787
|
trustedEventSenders?: string[];
|
|
788
|
+
/**
|
|
789
|
+
* Let the chat read the App's look from the server and keep it current:
|
|
790
|
+
* the colours, fonts, layout switches and AI display options the admin
|
|
791
|
+
* saved in the Chat component tab. Opt in by naming the App.
|
|
792
|
+
*
|
|
793
|
+
* The chat reads `GET /v2/chat-component/config?appId=` once at start and
|
|
794
|
+
* holds its first paint for it (at most `initialWaitMs`), lays the saved
|
|
795
|
+
* values over `config` (the server wins for the keys it holds), and reads
|
|
796
|
+
* again whenever the server announces a new version, applying the result to
|
|
797
|
+
* the open chat without reconnecting or resetting anything. Only the keys
|
|
798
|
+
* the chat can change live are accepted from the server (see the README
|
|
799
|
+
* table), each validated; nothing else in `config` is ever touched. A
|
|
800
|
+
* failed read keeps the look you already have.
|
|
801
|
+
*/
|
|
802
|
+
remoteAppearance?: {
|
|
803
|
+
/** The App whose config to read. Usually the same as `config.appId`. */
|
|
804
|
+
appId: string;
|
|
805
|
+
/** API origin. Default: `config.baseUrl`, then the SDK's own default. */
|
|
806
|
+
baseUrl?: string;
|
|
807
|
+
/** Longest the first paint waits for the first read, in ms. Default 2500. */
|
|
808
|
+
initialWaitMs?: number;
|
|
809
|
+
};
|
|
746
810
|
/**
|
|
747
811
|
* Background history preload after connect. Default `{ mode: 'staged',
|
|
748
812
|
* topRooms: 8, concurrency: 3 }`.
|
|
@@ -886,4 +950,10 @@ export interface IConfig {
|
|
|
886
950
|
}) => void | Promise<void>;
|
|
887
951
|
};
|
|
888
952
|
videoCalls?: VideoCallsConfig;
|
|
953
|
+
/**
|
|
954
|
+
* Scheduled calls (booking): a "Schedule call" action next to the call
|
|
955
|
+
* buttons, and invite cards with Add to calendar and Join in the room. On by
|
|
956
|
+
* default whenever `videoCalls.enabled` is on. See ScheduledCallsConfig.
|
|
957
|
+
*/
|
|
958
|
+
scheduledCalls?: ScheduledCallsConfig;
|
|
889
959
|
}
|
|
@@ -2,6 +2,7 @@ import { IUser } from './user.model';
|
|
|
2
2
|
import { TranslationObject } from '../types';
|
|
3
3
|
import { Iso639_1Codes } from './language.model';
|
|
4
4
|
import { IAttachment } from './attachment.model';
|
|
5
|
+
import { ScheduledCallMeta } from './scheduledCall.model';
|
|
5
6
|
export interface IMessage {
|
|
6
7
|
id: string;
|
|
7
8
|
user: IUser;
|
|
@@ -81,6 +82,7 @@ export interface IMessage {
|
|
|
81
82
|
missed: boolean;
|
|
82
83
|
kind: 'audio' | 'video';
|
|
83
84
|
};
|
|
85
|
+
scheduledCall?: ScheduledCallMeta;
|
|
84
86
|
}
|
|
85
87
|
export interface ReactionMessage {
|
|
86
88
|
emoji: string[];
|
|
@@ -178,6 +178,8 @@ export interface IRoomCompressed extends Pick<IRoom, 'jid'> {
|
|
|
178
178
|
export interface ConfigRoom {
|
|
179
179
|
jid: string;
|
|
180
180
|
pinned: boolean;
|
|
181
|
+
/** Whether users can leave this app-level room. Defaults to false for configured rooms. */
|
|
182
|
+
removable?: boolean;
|
|
181
183
|
_id?: string;
|
|
182
184
|
}
|
|
183
185
|
export type ChatAccessOption = {
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export type ScheduledCallKind = 'video' | 'audio';
|
|
2
|
+
/** Lifecycle stored on the server row. */
|
|
3
|
+
export type ScheduledCallStatus = 'scheduled' | 'cancelled';
|
|
4
|
+
/**
|
|
5
|
+
* Status carried by the room message. `updated` means the call was edited
|
|
6
|
+
* after the first invite; the card treats it like `scheduled`.
|
|
7
|
+
*/
|
|
8
|
+
export type ScheduledCallMessageStatus = 'scheduled' | 'updated' | 'cancelled';
|
|
9
|
+
export interface ScheduledCall {
|
|
10
|
+
id?: string;
|
|
11
|
+
appId?: string;
|
|
12
|
+
chatName: string;
|
|
13
|
+
chatType?: 'private' | 'group' | 'public';
|
|
14
|
+
createdBy?: string;
|
|
15
|
+
title: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
/** ISO 8601, UTC. */
|
|
18
|
+
startAt: string;
|
|
19
|
+
durationMinutes: number;
|
|
20
|
+
timezone?: string;
|
|
21
|
+
kind: ScheduledCallKind;
|
|
22
|
+
slug: string;
|
|
23
|
+
status: ScheduledCallStatus;
|
|
24
|
+
sequence?: number;
|
|
25
|
+
reminderSentAt?: string | null;
|
|
26
|
+
createdAt?: string;
|
|
27
|
+
updatedAt?: string;
|
|
28
|
+
}
|
|
29
|
+
/** Links are built by the backend only; clients never compose calendar URLs. */
|
|
30
|
+
export interface ScheduledCallLinks {
|
|
31
|
+
join: string;
|
|
32
|
+
ics: string;
|
|
33
|
+
google: string;
|
|
34
|
+
outlook: string;
|
|
35
|
+
office365?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface ScheduledCallWithLinks {
|
|
38
|
+
scheduledCall: ScheduledCall;
|
|
39
|
+
links: ScheduledCallLinks;
|
|
40
|
+
}
|
|
41
|
+
export interface ScheduledCallDetails extends ScheduledCallWithLinks {
|
|
42
|
+
chat: {
|
|
43
|
+
name: string;
|
|
44
|
+
title?: string;
|
|
45
|
+
type?: string;
|
|
46
|
+
jid: string;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export interface CreateScheduledCallInput {
|
|
50
|
+
chatName: string;
|
|
51
|
+
title?: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
startAt: string;
|
|
54
|
+
durationMinutes?: number;
|
|
55
|
+
timezone?: string;
|
|
56
|
+
kind?: ScheduledCallKind;
|
|
57
|
+
}
|
|
58
|
+
export interface UpdateScheduledCallInput {
|
|
59
|
+
title?: string;
|
|
60
|
+
description?: string;
|
|
61
|
+
startAt?: string;
|
|
62
|
+
durationMinutes?: number;
|
|
63
|
+
kind?: ScheduledCallKind;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* What a `<data type="scheduledCall">` message boils down to. Persisted on the
|
|
67
|
+
* message (like `callLog`) so a reloaded transcript repaints the card before
|
|
68
|
+
* the archive re-delivers the stanza.
|
|
69
|
+
*/
|
|
70
|
+
export interface ScheduledCallMeta {
|
|
71
|
+
slug: string;
|
|
72
|
+
title: string;
|
|
73
|
+
/** ISO 8601, UTC. */
|
|
74
|
+
startAt: string;
|
|
75
|
+
durationMinutes: number;
|
|
76
|
+
kind: ScheduledCallKind;
|
|
77
|
+
status: ScheduledCallMessageStatus;
|
|
78
|
+
/** Creator's user id (`scheduledCallCreatedBy`), decides who sees Edit and Cancel. */
|
|
79
|
+
createdBy?: string;
|
|
80
|
+
joinUrl?: string;
|
|
81
|
+
icsUrl?: string;
|
|
82
|
+
googleUrl?: string;
|
|
83
|
+
outlookUrl?: string;
|
|
84
|
+
}
|
|
85
|
+
/** Why a scheduled call could not be opened. */
|
|
86
|
+
export type ScheduledCallOpenError = 'not-found' | 'not-a-member' | 'cancelled' | 'network';
|
|
87
|
+
export interface ScheduledCallsConfig {
|
|
88
|
+
/**
|
|
89
|
+
* Scheduling and invite cards. Defaults to on whenever video calls are on
|
|
90
|
+
* (`config.videoCalls.enabled`). `false` hides the "Schedule call" action;
|
|
91
|
+
* invite cards still render so a room that already holds one stays readable,
|
|
92
|
+
* but without the Join button.
|
|
93
|
+
*/
|
|
94
|
+
enabled?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Called when `scheduledCallSlug` (or `openScheduledCall(slug)`) could not be
|
|
97
|
+
* opened. A host that wants its own error screen resolves the slug itself
|
|
98
|
+
* first; this is for the in-chat fallback.
|
|
99
|
+
*/
|
|
100
|
+
onOpenError?: (error: {
|
|
101
|
+
slug: string;
|
|
102
|
+
reason: ScheduledCallOpenError;
|
|
103
|
+
}) => void;
|
|
104
|
+
/**
|
|
105
|
+
* Hosts whose `https://<host>/call/<slug>` links `parseScheduledCallLink`
|
|
106
|
+
* accepts on top of `app.chat.ethora.com` and the page's own host. Same option
|
|
107
|
+
* name and defaults as the React Native SDK.
|
|
108
|
+
*/
|
|
109
|
+
hosts?: string[];
|
|
110
|
+
/**
|
|
111
|
+
* Custom URL schemes (without `://`) that `parseScheduledCallLink` accepts
|
|
112
|
+
* for `<scheme>://call/<slug>`. Unset accepts any scheme. Same option name
|
|
113
|
+
* as the React Native SDK.
|
|
114
|
+
*/
|
|
115
|
+
schemes?: string[];
|
|
116
|
+
}
|