@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
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { ScheduledCall, ScheduledCallKind } from '../types/models/scheduledCall.model';
|
|
2
|
+
/** Join opens this many minutes before the start (contract: 15). */
|
|
3
|
+
export declare const JOIN_LEAD_MINUTES = 15;
|
|
4
|
+
/** Server bounds (contract: duration 5..480, title 1..200, description 0..2000). */
|
|
5
|
+
export declare const MIN_DURATION_MINUTES = 5;
|
|
6
|
+
export declare const MAX_DURATION_MINUTES = 480;
|
|
7
|
+
export declare const DEFAULT_DURATION_MINUTES = 30;
|
|
8
|
+
export declare const MAX_TITLE_LENGTH = 200;
|
|
9
|
+
export declare const MAX_DESCRIPTION_LENGTH = 2000;
|
|
10
|
+
/** The server accepts a start up to 2 minutes in the past (clock skew). */
|
|
11
|
+
export declare const START_SKEW_MS: number;
|
|
12
|
+
/** Durations offered by the schedule form. */
|
|
13
|
+
export declare const DURATION_PRESETS: readonly [15, 30, 45, 60, 90, 120];
|
|
14
|
+
export type ScheduledCallPhase = 'upcoming' | 'joinable' | 'ended' | 'cancelled';
|
|
15
|
+
type PhaseInput = Pick<ScheduledCall, 'startAt' | 'durationMinutes'> & {
|
|
16
|
+
status: 'scheduled' | 'updated' | 'cancelled';
|
|
17
|
+
};
|
|
18
|
+
/** Epoch ms of an ISO string; NaN when it does not parse. */
|
|
19
|
+
export declare const toEpochMs: (iso: string | undefined | null) => number;
|
|
20
|
+
export declare const getScheduledCallEndMs: (call: Pick<ScheduledCall, "startAt" | "durationMinutes">) => number;
|
|
21
|
+
/** When the Join button becomes available (epoch ms). */
|
|
22
|
+
export declare const getJoinOpensAtMs: (call: Pick<ScheduledCall, "startAt">) => number;
|
|
23
|
+
/**
|
|
24
|
+
* Where a call is in its life. A call whose start does not parse is treated as
|
|
25
|
+
* ended, never joinable: the Join button must not guess.
|
|
26
|
+
*/
|
|
27
|
+
export declare const getScheduledCallPhase: (call: PhaseInput, now?: number) => ScheduledCallPhase;
|
|
28
|
+
/** Minutes until the join window opens, rounded up; 0 once it is open. */
|
|
29
|
+
export declare const minutesUntilJoinOpens: (call: Pick<ScheduledCall, "startAt">, now?: number) => number;
|
|
30
|
+
/** `YYYY-MM-DD` in the local time zone, the value of an <input type="date">. */
|
|
31
|
+
export declare const toLocalDateInput: (date: Date) => string;
|
|
32
|
+
/** `HH:mm` in the local time zone, the value of an <input type="time">. */
|
|
33
|
+
export declare const toLocalTimeInput: (date: Date) => string;
|
|
34
|
+
/**
|
|
35
|
+
* Local `YYYY-MM-DD` + `HH:mm` -> Date. Null when either part is malformed or
|
|
36
|
+
* names a date that does not exist (Feb 30 would otherwise roll into March).
|
|
37
|
+
*/
|
|
38
|
+
export declare const combineLocalDateTime: (dateValue: string, timeValue: string) => Date | null;
|
|
39
|
+
/** The default start of a new call: the next quarter hour, at least 15 min ahead. */
|
|
40
|
+
export declare const defaultScheduleStart: (now?: Date) => Date;
|
|
41
|
+
export interface ScheduleFormValues {
|
|
42
|
+
title: string;
|
|
43
|
+
description: string;
|
|
44
|
+
/** `YYYY-MM-DD`, local. */
|
|
45
|
+
date: string;
|
|
46
|
+
/** `HH:mm`, local. */
|
|
47
|
+
time: string;
|
|
48
|
+
durationMinutes: number;
|
|
49
|
+
kind: ScheduledCallKind;
|
|
50
|
+
}
|
|
51
|
+
export type ScheduleFormErrorKey = 'title' | 'description' | 'start' | 'startPast' | 'duration';
|
|
52
|
+
export type ScheduleFormErrors = Partial<Record<ScheduleFormErrorKey, true>>;
|
|
53
|
+
/**
|
|
54
|
+
* Client-side mirror of the server rules, so the form can say what is wrong
|
|
55
|
+
* before a round trip. `skipPastCheck` is for editing a call that already
|
|
56
|
+
* started or whose time is left unchanged.
|
|
57
|
+
*/
|
|
58
|
+
export declare const validateScheduleForm: (values: ScheduleFormValues, now?: number, options?: {
|
|
59
|
+
skipPastCheck?: boolean;
|
|
60
|
+
}) => ScheduleFormErrors;
|
|
61
|
+
/** Presets plus the call's own duration when it is not one of them (edit). */
|
|
62
|
+
export declare const durationOptions: (current?: number) => number[];
|
|
63
|
+
export declare const localTimeZone: () => string | undefined;
|
|
64
|
+
export interface ScheduledCallLinkOptions {
|
|
65
|
+
/** Hosts accepted for `https://<host>/call/<slug>`. Empty or unset: any host. */
|
|
66
|
+
hosts?: string[];
|
|
67
|
+
/** Schemes accepted for `<scheme>://call/<slug>`. Empty or unset: any scheme. */
|
|
68
|
+
schemes?: string[];
|
|
69
|
+
}
|
|
70
|
+
export declare const isValidScheduledCallSlug: (value: unknown) => value is string;
|
|
71
|
+
/**
|
|
72
|
+
* The slug of a scheduled-call join link, or null when `url` is not one.
|
|
73
|
+
* Accepts the canonical `https://<host>/call/<slug>` and the app-scheme form
|
|
74
|
+
* `<scheme>://call/<slug>`. `options.hosts` / `options.schemes` narrow what is
|
|
75
|
+
* accepted (plain http and script-like schemes never are). Same name and
|
|
76
|
+
* contract as the React Native SDK.
|
|
77
|
+
*/
|
|
78
|
+
export declare const parseScheduledCallLink: (url: unknown, options?: ScheduledCallLinkOptions) => string | null;
|
|
79
|
+
/**
|
|
80
|
+
* Link attributes ride on a room message any member could forge, so a button
|
|
81
|
+
* only gets a link that is plausible for what it says it is: http(s) only
|
|
82
|
+
* (never `javascript:`), the calendar buttons only on the calendar providers'
|
|
83
|
+
* own hosts, and the .ics link only on the API host the chat already talks to
|
|
84
|
+
* (when that is known) and for this call's slug.
|
|
85
|
+
*/
|
|
86
|
+
export declare const safeCalendarLink: (kind: "google" | "outlook" | "ics", value: unknown, context: {
|
|
87
|
+
slug: string;
|
|
88
|
+
apiBaseUrl?: string | null;
|
|
89
|
+
}) => string | null;
|
|
90
|
+
/**
|
|
91
|
+
* A link from the authenticated API (the pre-join panel). Trusted as far as
|
|
92
|
+
* the origin goes, but still http(s) only.
|
|
93
|
+
*/
|
|
94
|
+
export declare const httpLinkOrNull: (value: unknown) => string | null;
|
|
95
|
+
/**
|
|
96
|
+
* The title to show. The backend defaults an omitted title to the English
|
|
97
|
+
* word `Call`, so that exact value (and an empty one) is shown in the viewer's
|
|
98
|
+
* language instead.
|
|
99
|
+
*/
|
|
100
|
+
export declare const displayCallTitle: (title: string | undefined | null, defaultTitle: string) => string;
|
|
101
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Dispatch } from '@reduxjs/toolkit';
|
|
2
|
+
import { RootState } from '../roomStore';
|
|
3
|
+
import { ScheduledCallDetails } from '../types/models/scheduledCall.model';
|
|
4
|
+
/**
|
|
5
|
+
* Fetches one scheduled call into the slice's details cache. Cards call this
|
|
6
|
+
* when they appear, so it is deduped: a call already loading or loaded (and
|
|
7
|
+
* not `force`d) is left alone. Never throws; a failure is recorded on the
|
|
8
|
+
* entry and the card falls back to what the room message carried.
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadScheduledCallDetails(dispatch: Dispatch, getState: () => RootState, slug: string, options?: {
|
|
11
|
+
force?: boolean;
|
|
12
|
+
}): Promise<ScheduledCallDetails | null>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type Translate = (key: string, vars?: Record<string, string | number>) => string;
|
|
2
|
+
/** "Wed, Oct 22" in the viewer's local time zone and the UI locale. */
|
|
3
|
+
export declare const formatScheduledDay: (startAt: string, locale?: string) => string;
|
|
4
|
+
/** "3:00 PM - 3:30 PM" (end time only when it can be computed). */
|
|
5
|
+
export declare const formatScheduledTimeRange: (call: {
|
|
6
|
+
startAt: string;
|
|
7
|
+
durationMinutes: number;
|
|
8
|
+
}, locale?: string) => string;
|
|
9
|
+
/** Clock time of an instant, e.g. when the join window opens. */
|
|
10
|
+
export declare const formatClockTime: (ms: number, locale?: string) => string;
|
|
11
|
+
/** "30 min", "2 h", "1 h 30 min". */
|
|
12
|
+
export declare const formatScheduledDuration: (minutes: number, t: Translate) => string;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { IConfig } from '../types/types';
|
|
2
|
+
/**
|
|
3
|
+
* Scheduled calls are on whenever video calls are on, unless the host sets
|
|
4
|
+
* `config.scheduledCalls.enabled: false`. Never on without calls: a booked
|
|
5
|
+
* call has to be joinable through the same call path.
|
|
6
|
+
*/
|
|
7
|
+
export declare const isScheduledCallsEnabled: (config: Pick<IConfig, "videoCalls" | "scheduledCalls"> | null | undefined) => boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Whether a call can be placed in a room of this type under this config: the
|
|
10
|
+
* same gate the chat header uses for its call buttons (master switch, room
|
|
11
|
+
* type, LiveKit URL). Join on a scheduled call is offered only when true.
|
|
12
|
+
*/
|
|
13
|
+
export declare const canPlaceCallsInRoom: (config: Pick<IConfig, "videoCalls"> | null | undefined, roomType: string | undefined | null) => boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Edit and Cancel are for the person who scheduled the call and for the room
|
|
16
|
+
* owner. The server enforces the same rule (403); this only decides whether
|
|
17
|
+
* to offer the buttons. `callCreatedBy` is unknown until the call has been
|
|
18
|
+
* fetched, and an unknown creator never grants anything.
|
|
19
|
+
*/
|
|
20
|
+
export declare const canManageScheduledCall: (params: {
|
|
21
|
+
userId?: string | null;
|
|
22
|
+
callCreatedBy?: string | null;
|
|
23
|
+
room?: {
|
|
24
|
+
createdBy?: string;
|
|
25
|
+
role?: string;
|
|
26
|
+
} | null;
|
|
27
|
+
}) => boolean;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True when `fromJid` is the app's system account. The resource is ignored.
|
|
3
|
+
* When `expectedDomain` is given the sender must also be on that XMPP domain,
|
|
4
|
+
* so a same-looking account on a federated server is not accepted. A missing
|
|
5
|
+
* or malformed JID is never trusted.
|
|
6
|
+
*/
|
|
7
|
+
export declare const isSystemAccountSender: (fromJid: unknown, expectedDomain?: string | null) => boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CallKindName } from './callMode';
|
|
2
|
+
/**
|
|
3
|
+
* Second half of placing a call, shared by every dial entry point (chat
|
|
4
|
+
* header, profile modal): POST /v1/chats/call/create and record how the server
|
|
5
|
+
* decided to carry the call in the call slice. The caller has already
|
|
6
|
+
* dispatched startOutgoingCall.
|
|
7
|
+
*
|
|
8
|
+
* Throws when the request fails (the entry point shows the message). A p2p
|
|
9
|
+
* answer that lands after the user already cancelled is cleaned up here: the
|
|
10
|
+
* server has already rung the callee, and nothing else knows its callId.
|
|
11
|
+
*/
|
|
12
|
+
export declare function requestOutgoingCall(params: {
|
|
13
|
+
chatName: string;
|
|
14
|
+
kind: CallKindName;
|
|
15
|
+
peerXmppUsername?: string | null;
|
|
16
|
+
}): Promise<void>;
|
|
@@ -9,6 +9,7 @@ interface LoginWrapperProps extends Partial<Pick<CustomComponentsContextValue, '
|
|
|
9
9
|
MainComponentStyles?: React.CSSProperties;
|
|
10
10
|
config?: IConfig;
|
|
11
11
|
roomJID?: string;
|
|
12
|
+
scheduledCallSlug?: string;
|
|
12
13
|
}
|
|
13
14
|
declare const LoginWrapper: React.FC<LoginWrapperProps>;
|
|
14
15
|
export default LoginWrapper;
|
|
@@ -4,6 +4,12 @@ import { CustomComponentsContextValue } from '../../types/models/customComponent
|
|
|
4
4
|
export interface ChatWrapperProps extends Pick<CustomComponentsContextValue, 'CustomMessageComponent' | 'CustomInputComponent' | 'CustomScrollableArea' | 'CustomDaySeparator' | 'CustomNewMessageLabel'> {
|
|
5
5
|
token?: string;
|
|
6
6
|
roomJID?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Open a scheduled call: once signed in, select its room and show the
|
|
9
|
+
* pre-join panel. The slug is the last part of a `/call/<slug>` join link
|
|
10
|
+
* (see `parseScheduledCallLink`). Nothing starts until the user taps Join.
|
|
11
|
+
*/
|
|
12
|
+
scheduledCallSlug?: string;
|
|
7
13
|
user?: ConfigUser;
|
|
8
14
|
loginData?: {
|
|
9
15
|
email: string;
|
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
export declare const AvatarPicker: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
|
|
2
|
+
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
3
|
+
}> & string;
|
|
4
|
+
export declare const AvatarPickerActions: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
|
|
5
|
+
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
6
|
+
}> & string;
|
|
7
|
+
export declare const TextAction: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "style"> & {
|
|
8
|
+
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
9
|
+
}> & string;
|
|
10
|
+
export declare const MemberPickerHeader: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
|
|
11
|
+
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
12
|
+
}> & string;
|
|
13
|
+
export declare const MemberPickerAction: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<any, "style"> & {
|
|
14
|
+
style?: any;
|
|
15
|
+
}> & string;
|
|
16
|
+
export declare const MemberCount: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "style"> & {
|
|
17
|
+
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
18
|
+
}> & string;
|
|
19
|
+
export declare const MemberPickerSection: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
|
|
20
|
+
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
21
|
+
}> & string;
|
|
22
|
+
export declare const ModalHint: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "style"> & {
|
|
23
|
+
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
24
|
+
}> & string;
|
|
25
|
+
export declare const HiddenFileInput: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "style"> & {
|
|
26
|
+
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
27
|
+
}> & string;
|
|
1
28
|
export declare const ChatTypeGroup: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
|
|
2
29
|
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
3
30
|
}> & string;
|
|
@@ -15,6 +15,27 @@ export declare const ModalContainer: import('styled-components/dist/types').ISty
|
|
|
15
15
|
export declare const ModalTitle: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, "style"> & {
|
|
16
16
|
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
17
17
|
}> & string;
|
|
18
|
+
/** New-chat dialog keeps its chrome and actions visible while a long member
|
|
19
|
+
* picker scrolls independently in the middle. */
|
|
20
|
+
export declare const NewChatDialog: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Merged<Omit<any, "style"> & {
|
|
21
|
+
style?: any;
|
|
22
|
+
}, {
|
|
23
|
+
$closing?: boolean;
|
|
24
|
+
}>> & string;
|
|
25
|
+
export declare const NewChatBackdrop: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Merged<Omit<any, "style"> & {
|
|
26
|
+
style?: any;
|
|
27
|
+
}, {
|
|
28
|
+
$closing?: boolean;
|
|
29
|
+
}>> & string;
|
|
30
|
+
export declare const NewChatDialogHeader: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLElement>, HTMLElement>, "style"> & {
|
|
31
|
+
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
32
|
+
}> & string;
|
|
33
|
+
export declare const NewChatDialogBody: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
|
|
34
|
+
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
35
|
+
}> & string;
|
|
36
|
+
export declare const NewChatDialogFooter: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLElement>, HTMLElement>, "style"> & {
|
|
37
|
+
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
38
|
+
}> & string;
|
|
18
39
|
/** Small uppercase-weight label above a field/list inside a modal - e.g. "Select Users (max 20)". */
|
|
19
40
|
export declare const ModalSectionLabel: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
|
|
20
41
|
style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* "Cancel this call?" confirmation. Mounted by ScheduledCallLayer, not by the
|
|
4
|
+
* card: a fixed overlay rendered inside the message list is bounded by the
|
|
5
|
+
* list's ancestors and came out clipped on the left.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ScheduledCallCancelConfirm: React.FC;
|
|
8
|
+
export default ScheduledCallCancelConfirm;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** `<Chat scheduledCallSlug>`: open this call's room and pre-join panel. */
|
|
4
|
+
scheduledCallSlug?: string;
|
|
5
|
+
/** Narrow screens show the room list first; this brings the room forward. */
|
|
6
|
+
onRevealRoom?: () => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Everything scheduled calls need inside a mounted chat: the schedule form,
|
|
10
|
+
* the pre-join panel, and the opener that turns a slug (host prop or
|
|
11
|
+
* `openScheduledCall(slug)`) into "room selected, pre-join panel up". Mounted
|
|
12
|
+
* once the chat shell is up, so the room list is already there to select from.
|
|
13
|
+
*/
|
|
14
|
+
export declare const ScheduledCallLayer: React.FC<Props>;
|
|
15
|
+
export default ScheduledCallLayer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const P2PCallRunner: React.FC;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { VideoCallIcons } from '../../types/models/config.model';
|
|
3
|
+
import { P2PCallController } from '../../calls/p2p/P2PCallController';
|
|
4
|
+
/** The controller of the call on screen, re-rendering when it is swapped. */
|
|
5
|
+
export declare const useActiveP2PController: () => P2PCallController | null;
|
|
6
|
+
export interface P2PCallSessionProps {
|
|
7
|
+
kind?: 'audio' | 'video';
|
|
8
|
+
primaryColor?: string;
|
|
9
|
+
icons?: VideoCallIcons;
|
|
10
|
+
minimized?: boolean;
|
|
11
|
+
onToggleMinimize?: () => void;
|
|
12
|
+
onHangup: () => void;
|
|
13
|
+
}
|
|
14
|
+
export declare const P2PCallSession: React.FC<P2PCallSessionProps>;
|
|
@@ -33,8 +33,45 @@ interface VideoCallSessionProps {
|
|
|
33
33
|
* receives it. See VideoCallOverlay.
|
|
34
34
|
*/
|
|
35
35
|
onParticipantJoined?: () => void;
|
|
36
|
+
/**
|
|
37
|
+
* Group room call: render every participant in a grid and keep the call
|
|
38
|
+
* alive while other people remain. A 1:1 call (default) ends locally as
|
|
39
|
+
* soon as the single remote peer leaves.
|
|
40
|
+
*/
|
|
41
|
+
isGroup?: boolean;
|
|
36
42
|
onNoAnswer?: () => void;
|
|
37
43
|
noAnswerTimeoutMs?: number;
|
|
38
44
|
}
|
|
45
|
+
export declare const TEXT_PRIMARY = "var(--ethora-color-text, #141414)";
|
|
46
|
+
export declare const TEXT_MUTED = "var(--ethora-call-text-muted, #8c8c8c)";
|
|
47
|
+
export declare const SURFACE = "var(--ethora-color-bg, #fff)";
|
|
48
|
+
export declare const SURFACE_MUTED = "var(--ethora-color-chat-bg, #f3f6fc)";
|
|
49
|
+
export declare const DIVIDER = "var(--ethora-color-bg-hover, #f0f0f0)";
|
|
50
|
+
export declare const DANGER = "#E53935";
|
|
51
|
+
export declare const MicOnIcon: React.FC<{
|
|
52
|
+
color?: string;
|
|
53
|
+
}>;
|
|
54
|
+
export declare const MicOffIcon: React.FC<{
|
|
55
|
+
color?: string;
|
|
56
|
+
cutColor?: string;
|
|
57
|
+
}>;
|
|
58
|
+
export declare const CamOnIcon: React.FC<{
|
|
59
|
+
color?: string;
|
|
60
|
+
}>;
|
|
61
|
+
export declare const CamOffIcon: React.FC<{
|
|
62
|
+
color?: string;
|
|
63
|
+
cutColor?: string;
|
|
64
|
+
}>;
|
|
65
|
+
export declare const MinimizeIcon: React.FC<{
|
|
66
|
+
color?: string;
|
|
67
|
+
}>;
|
|
68
|
+
export declare const ExpandIcon: React.FC<{
|
|
69
|
+
color?: string;
|
|
70
|
+
}>;
|
|
71
|
+
export declare const hexToRgba: (hex: string, alpha: number) => string;
|
|
72
|
+
export declare const formatDuration: (totalSeconds: number) => string;
|
|
73
|
+
type ToneVariant = 'neutral' | 'active' | 'danger';
|
|
74
|
+
export declare const toneStyle: (tone: ToneVariant, primary: string, background?: string) => React.CSSProperties;
|
|
75
|
+
export declare const controlButtonBase: React.CSSProperties;
|
|
39
76
|
export declare const VideoCallSession: React.FC<VideoCallSessionProps>;
|
|
40
77
|
export {};
|
|
@@ -11,6 +11,8 @@ export interface ParsedCallPush {
|
|
|
11
11
|
callerName: string | null;
|
|
12
12
|
/** Caller's xmpp localpart, when provided. */
|
|
13
13
|
callerXmppUsername: string | null;
|
|
14
|
+
/** The call is for a group room (always LiveKit). */
|
|
15
|
+
isGroup: boolean;
|
|
14
16
|
}
|
|
15
17
|
/**
|
|
16
18
|
* True when a push `data` payload represents an incoming call. Matches on an
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-process bus for the `chat-component-config-updated` server event, so the
|
|
3
|
+
* XMPP stanza handler (networking/ethoraEvents.ts) and whoever acts on it
|
|
4
|
+
* (`config.remoteAppearance`, see hooks/useRemoteAppearance.ts) do not import
|
|
5
|
+
* each other.
|
|
6
|
+
*/
|
|
7
|
+
export interface ChatComponentConfigUpdatedEvent {
|
|
8
|
+
appId: string;
|
|
9
|
+
/** Opaque state id from the server, pass it to the config endpoint as `v`. */
|
|
10
|
+
version: string;
|
|
11
|
+
}
|
|
12
|
+
type Listener = (event: ChatComponentConfigUpdatedEvent) => void;
|
|
13
|
+
export declare const subscribeChatComponentConfigUpdated: (listener: Listener) => (() => void);
|
|
14
|
+
export declare const publishChatComponentConfigUpdated: (event: ChatComponentConfigUpdatedEvent) => void;
|
|
15
|
+
export declare const resetChatComponentConfigListeners: () => void;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which `config` keys the chat applies LIVE, and how an operator-saved record
|
|
3
|
+
* is laid over the host's config.
|
|
4
|
+
*
|
|
5
|
+
* Live means: changing the key on a mounted chat re-renders the affected
|
|
6
|
+
* pieces from the store and the CSS variables, with the XMPP connection, the
|
|
7
|
+
* rooms, the messages and every draft left alone. The list is exactly the
|
|
8
|
+
* visual and layout switches; everything else (identity, endpoints, login,
|
|
9
|
+
* history, e2ee, receipts, ...) is read when the chat starts and a new value
|
|
10
|
+
* is picked up by the next mount.
|
|
11
|
+
*
|
|
12
|
+
* The keys below also form the allowlist for `config.remoteAppearance`: a
|
|
13
|
+
* record fetched from the server can set these keys and no others, each with
|
|
14
|
+
* a strict validator, because the record comes over the network and ends up
|
|
15
|
+
* in CSS variables and a stylesheet.
|
|
16
|
+
*/
|
|
17
|
+
type Parse = (value: unknown) => string | boolean | number | null;
|
|
18
|
+
/** Live keys and their validators. Mirrors ethora-backend modules/apps/chatComponentConfig.js. */
|
|
19
|
+
export declare const LIVE_CONFIG_KEYS: Readonly<Record<string, Parse>>;
|
|
20
|
+
export declare const isLiveConfigPath: (path: string) => boolean;
|
|
21
|
+
/** Flattens to dotted leaf paths. Functions, nodes and class instances are leaves compared by identity. */
|
|
22
|
+
export declare const flattenConfig: (input: unknown, out?: Map<string, unknown>, prefix?: string, depth?: number) => Map<string, unknown>;
|
|
23
|
+
export interface ConfigChange {
|
|
24
|
+
/** Changed paths the chat applies live. */
|
|
25
|
+
live: string[];
|
|
26
|
+
/** Changed paths read when the chat starts: applied by the next mount. */
|
|
27
|
+
restart: string[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Splits what differs between two host configs into live and start-time
|
|
31
|
+
* paths. A function that is a new closure on every render counts as changed
|
|
32
|
+
* (it is compared by identity) and lands in `restart`; that only affects the
|
|
33
|
+
* log line, the chat applies the whole new config either way.
|
|
34
|
+
*/
|
|
35
|
+
export declare function classifyConfigChange(prev: unknown, next: unknown): ConfigChange;
|
|
36
|
+
export type RemoteConfigRecord = Record<string, string | boolean | number>;
|
|
37
|
+
/**
|
|
38
|
+
* Keeps only allowlisted keys with a valid value. Anything else (an unknown
|
|
39
|
+
* key, a wrong type, markup, a URL, an out of range number) is dropped, so a
|
|
40
|
+
* wrong or hostile answer cannot do more than restyle the chat within the
|
|
41
|
+
* validators' limits.
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseRemoteConfigRecord(raw: unknown): RemoteConfigRecord;
|
|
44
|
+
/** The config with the record laid over it, copying only the objects on the way. Siblings stay. */
|
|
45
|
+
export declare function applyRemoteConfigRecord<T extends object | undefined>(base: T, record: RemoteConfigRecord | null | undefined): T;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PostReportRoom } from '../types/models/room.model';
|
|
2
|
+
export interface ReportCategory {
|
|
3
|
+
id: string;
|
|
4
|
+
labelKey: string;
|
|
5
|
+
apiCategory: string;
|
|
6
|
+
/** English name, used in `text` (the report e-mail is not localized). */
|
|
7
|
+
name: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const REPORT_CATEGORIES: ReportCategory[];
|
|
10
|
+
export declare const OTHER_REPORT_CATEGORY: ReportCategory;
|
|
11
|
+
export declare const findReportCategory: (id: string) => ReportCategory | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* The request body for a room report. `roomJid` may be the full room JID or
|
|
14
|
+
* the bare room name: the route takes the bare name (JID localpart), like
|
|
15
|
+
* every other /v1/chats/... route. Returns null for an unknown category or
|
|
16
|
+
* an empty room.
|
|
17
|
+
*/
|
|
18
|
+
export declare const buildReportRoomPayload: (roomJid: string, categoryId: string, details?: string) => PostReportRoom | null;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { IMessage } from '../types/types';
|
|
2
|
+
import { ScheduledCallMeta } from '../types/models/scheduledCall.model';
|
|
3
|
+
export declare const SCHEDULED_CALL_MESSAGE_TYPE = "scheduledCall";
|
|
4
|
+
/**
|
|
5
|
+
* Reads the scheduled-call fields off a message. Null when the message is not
|
|
6
|
+
* one, or when it lacks what a card cannot do without (a valid slug and a
|
|
7
|
+
* parseable start); such a message falls back to its plain body.
|
|
8
|
+
*
|
|
9
|
+
* `apiBaseUrl` is the API the chat talks to, used to vet the .ics link.
|
|
10
|
+
*/
|
|
11
|
+
export declare const parseScheduledCallMeta: (message: unknown, apiBaseUrl?: string | null) => ScheduledCallMeta | null;
|
|
12
|
+
/**
|
|
13
|
+
* createMessageFromXml hook: attaches `scheduledCall` meta to a message that
|
|
14
|
+
* is one. Everything else comes back untouched (same object).
|
|
15
|
+
*/
|
|
16
|
+
export declare const attachScheduledCallMeta: (message: IMessage, apiBaseUrl?: string | null) => IMessage;
|
|
17
|
+
/**
|
|
18
|
+
* One card per slug: of all messages that announce the same scheduled call
|
|
19
|
+
* only the newest stays, so an `updated` or `cancelled` message replaces the
|
|
20
|
+
* card instead of stacking under it. Order of everything else is kept, and the
|
|
21
|
+
* input is returned as is when no call is announced twice.
|
|
22
|
+
*/
|
|
23
|
+
export declare const collapseScheduledCallMessages: (messages: IMessage[]) => IMessage[];
|
|
@@ -3,4 +3,5 @@ export declare const useStoreConsole: () => {
|
|
|
3
3
|
rooms: Record<string, any> & import('redux-persist/es/persistReducer').PersistPartial;
|
|
4
4
|
roomHeapSlice: import('../roomStore/roomHeapSlice').roomHeapSliceState;
|
|
5
5
|
call: import('immer').WritableDraft<import('../roomStore/callSlice').CallState>;
|
|
6
|
+
scheduledCall: import('immer').WritableDraft<import('../roomStore/scheduledCallSlice').ScheduledCallState>;
|
|
6
7
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Date.now()` that re-renders its component every `intervalMs` while
|
|
3
|
+
* `enabled`. For things that change with the clock (a Join button that opens
|
|
4
|
+
* 15 minutes before the start) without each caller owning a timer.
|
|
5
|
+
*/
|
|
6
|
+
export declare const useNow: (intervalMs: number, enabled?: boolean) => number;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IConfig } from '../types/types';
|
|
2
|
+
import { RemoteConfigRecord } from '../helpers/liveConfig';
|
|
3
|
+
export declare const DEFAULT_REMOTE_APPEARANCE_WAIT_MS = 2500;
|
|
4
|
+
export interface RemoteAppearanceState {
|
|
5
|
+
/** The record to lay over the host config; null until the first read settles. */
|
|
6
|
+
record: RemoteConfigRecord | null;
|
|
7
|
+
/** True while the chat should hold its first paint for the first read. */
|
|
8
|
+
waiting: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* `config.remoteAppearance`: reads the App's chat component config from the
|
|
12
|
+
* server and keeps it current. Reads once on mount (the chat waits for it, at
|
|
13
|
+
* most `initialWaitMs`, so it starts once with its final look), then again
|
|
14
|
+
* every time the server announces a new version with a
|
|
15
|
+
* `chat-component-config-updated` event. The newest read wins, a failed read
|
|
16
|
+
* keeps what is shown, and a version that is already shown is not fetched
|
|
17
|
+
* again.
|
|
18
|
+
*
|
|
19
|
+
* Does nothing (and never waits) when the host did not opt in.
|
|
20
|
+
*/
|
|
21
|
+
export declare function useRemoteAppearance(config?: IConfig): RemoteAppearanceState;
|
|
@@ -4,5 +4,9 @@ import { TypographyConfig } from '../types/models/config.model';
|
|
|
4
4
|
* Wired into the chat root (ReduxWrapper) so the font is in place before the
|
|
5
5
|
* UI paints. No-op when `typography` is undefined - the default system font
|
|
6
6
|
* stack is kept, so existing integrations are unaffected.
|
|
7
|
+
*
|
|
8
|
+
* When `typography` goes away on a mounted chat (the operator cleared the
|
|
9
|
+
* font in the admin tab), what this hook applied is removed again and the
|
|
10
|
+
* default stack is back, with no reload.
|
|
7
11
|
*/
|
|
8
12
|
export declare function useTypography(typography?: TypographyConfig): void;
|