@ethora/chat-component 26.10.6 → 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.
Files changed (94) hide show
  1. package/README.md +102 -3
  2. package/dist/ChatProfileModal-83t5BRkI.js +2298 -0
  3. package/dist/{FilePreviewModal-DwNUEHei.js → FilePreviewModal-DxUGjSHe.js} +135 -135
  4. package/dist/{ManageDataModal-CaQ2VBPn.js → ManageDataModal-DFE_Wegj.js} +24 -24
  5. package/dist/{MarkdownBody-BeoG2cpo.js → MarkdownBody-uFITrPjT.js} +1 -1
  6. package/dist/{MessageSearchModal-DMw9o49-.js → MessageSearchModal-CsbTWgNm.js} +46 -46
  7. package/dist/{PublicChatsModal-CWdYILv_.js → PublicChatsModal-bDOp3IL9.js} +18 -18
  8. package/dist/{SideDrawer-Cl-vbuIG.js → SideDrawer-A_1ECqD2.js} +29 -29
  9. package/dist/UserProfileModal-Ca5wHYvr.js +639 -0
  10. package/dist/{UserSettingsModal-DgCAHmNh.js → UserSettingsModal-CAyyQGV6.js} +4 -4
  11. package/dist/{VideoCallOverlay-Cq2cECWj.js → VideoCallOverlay-BMiQh8kI.js} +6605 -4726
  12. package/dist/{VisibilityModal-D7vqGbrA.js → VisibilityModal-BXyIy7_J.js} +12 -12
  13. package/dist/assets/icons.d.ts +4 -0
  14. package/dist/calls/callDisplay.d.ts +22 -0
  15. package/dist/calls/callMode.d.ts +105 -0
  16. package/dist/calls/openScheduledCall.d.ts +20 -0
  17. package/dist/calls/p2p/P2PCallController.d.ts +160 -0
  18. package/dist/calls/p2p/icePolicy.d.ts +36 -0
  19. package/dist/calls/p2p/negotiator.d.ts +56 -0
  20. package/dist/calls/p2p/p2pRuntime.d.ts +35 -0
  21. package/dist/calls/p2p/signalInbox.d.ts +34 -0
  22. package/dist/calls/p2p/signalStanza.d.ts +51 -0
  23. package/dist/calls/placeCall.d.ts +20 -0
  24. package/dist/calls/scheduledCall.d.ts +101 -0
  25. package/dist/calls/scheduledCallActions.d.ts +12 -0
  26. package/dist/calls/scheduledCallFormat.d.ts +13 -0
  27. package/dist/calls/scheduledCallsConfig.d.ts +27 -0
  28. package/dist/calls/senderTrust.d.ts +7 -0
  29. package/dist/calls/startCall.d.ts +16 -0
  30. package/dist/components/MainComponents/ChatWrapper.d.ts +1 -0
  31. package/dist/components/MainComponents/LoginWrapper.d.ts +1 -0
  32. package/dist/components/MainComponents/ProfileImagePlaceholder.d.ts +1 -0
  33. package/dist/components/MainComponents/ReduxWrapper.d.ts +6 -0
  34. package/dist/components/MenuRoom/MenuRoom.d.ts +1 -0
  35. package/dist/components/Modals/NewChatModal/styledNewChatComponents.d.ts +27 -0
  36. package/dist/components/Modals/styledModalComponents.d.ts +25 -4
  37. package/dist/components/ScheduledCalls/ScheduleCallModal.d.ts +3 -0
  38. package/dist/components/ScheduledCalls/ScheduledCallCancelConfirm.d.ts +8 -0
  39. package/dist/components/ScheduledCalls/ScheduledCallCard.d.ts +7 -0
  40. package/dist/components/ScheduledCalls/ScheduledCallLayer.d.ts +15 -0
  41. package/dist/components/ScheduledCalls/ScheduledCallPreJoin.d.ts +3 -0
  42. package/dist/components/VideoCalls/P2PCallRunner.d.ts +1 -0
  43. package/dist/components/VideoCalls/P2PCallSession.d.ts +14 -0
  44. package/dist/components/VideoCalls/VideoCallSession.d.ts +39 -0
  45. package/dist/firebase-messaging-sw.js +918 -96
  46. package/dist/{handleCopyClick-Crn2jEEu.js → handleCopyClick-BX1fcFGN.js} +1 -1
  47. package/dist/helpers/callClaim.d.ts +17 -0
  48. package/dist/helpers/callOutcomeSync.d.ts +23 -0
  49. package/dist/helpers/callPush.d.ts +25 -0
  50. package/dist/helpers/canLeaveRoom.d.ts +3 -0
  51. package/dist/helpers/chatComponentConfigEvents.d.ts +16 -0
  52. package/dist/helpers/incomingCallPush.d.ts +89 -0
  53. package/dist/helpers/liveConfig.d.ts +46 -0
  54. package/dist/helpers/pushRoomHandoff.d.ts +13 -0
  55. package/dist/helpers/reportRoom.d.ts +18 -0
  56. package/dist/helpers/scheduledCallMessage.d.ts +23 -0
  57. package/dist/helpers/storeConsole.d.ts +1 -0
  58. package/dist/hooks/useChatSettingState.d.ts +1 -0
  59. package/dist/hooks/useNow.d.ts +6 -0
  60. package/dist/hooks/usePushNotifications.d.ts +2 -0
  61. package/dist/hooks/useRemoteAppearance.d.ts +21 -0
  62. package/dist/hooks/useTypography.d.ts +4 -0
  63. package/dist/{main-36gqdbJ8.js → main-B25iFKAC.js} +16623 -13399
  64. package/dist/main.d.ts +3 -1
  65. package/dist/main.js +25 -23
  66. package/dist/networking/api-requests/callState.api.d.ts +24 -0
  67. package/dist/networking/api-requests/remoteAppearance.api.d.ts +20 -0
  68. package/dist/networking/api-requests/rooms.api.d.ts +11 -1
  69. package/dist/networking/api-requests/scheduledCalls.api.d.ts +19 -0
  70. package/dist/networking/ethoraEvents.d.ts +14 -1
  71. package/dist/networking/xmpp/notifyXmppEvent.d.ts +6 -0
  72. package/dist/networking/xmpp/sendMessageReaction.xmpp.d.ts +13 -1
  73. package/dist/networking/xmppClient.d.ts +2 -1
  74. package/dist/roomStore/Middleware/blockedHydrationMiddleware.d.ts +2 -0
  75. package/dist/roomStore/callSlice.d.ts +23 -1
  76. package/dist/roomStore/chatSettingsSlice.d.ts +11 -2
  77. package/dist/roomStore/index.d.ts +4 -0
  78. package/dist/roomStore/scheduledCallSlice.d.ts +47 -0
  79. package/dist/types/models/config.model.d.ts +78 -1
  80. package/dist/types/models/message.model.d.ts +2 -0
  81. package/dist/types/models/room.model.d.ts +2 -0
  82. package/dist/types/models/scheduledCall.model.d.ts +116 -0
  83. package/dist/types/models/xmpp.model.d.ts +2 -1
  84. package/dist/utils/callAuthMirror.d.ts +1 -0
  85. package/dist/utils/callBroadcast.d.ts +12 -0
  86. package/dist/utils/callNotifications.d.ts +67 -0
  87. package/dist/utils/firebasePushNotifications.d.ts +14 -0
  88. package/dist/utils/handledCalls.d.ts +5 -0
  89. package/dist/utils/pushServiceWorkerBridge.d.ts +19 -0
  90. package/dist/utils/webLock.d.ts +13 -0
  91. package/package.json +1 -1
  92. package/public/firebase-messaging-sw.js +918 -96
  93. package/dist/ChatProfileModal-OJCKwdNp.js +0 -2168
  94. package/dist/UserProfileModal-B8KtGnwZ.js +0 -594
@@ -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
+ }
@@ -1,4 +1,5 @@
1
1
  import { Client } from '@xmpp/client';
2
+ import { ReactionStanzaData } from '../../networking/xmpp/sendMessageReaction.xmpp';
2
3
  import { Iso639_1Codes } from './language.model';
3
4
  import { default as XmppClient, HistoryWindowPage } from '../../networking/xmppClient';
4
5
  import { IMessage } from './message.model';
@@ -112,7 +113,7 @@ export interface XmppClientInterface {
112
113
  actionSetTimestampToPrivateStoreStanza(chatId: string, timestamp: number, chats?: string[]): Promise<void>;
113
114
  sendMediaMessageStanza(roomJID: string, data: MediaUploadData, id: string): Promise<boolean>;
114
115
  createPrivateRoomStanza(title: string, description: string, to: string): Promise<string>;
115
- sendMessageReactionStanza(messageId: string, roomJid: string, reactionsList: string[], reactionSymbol?: string): void;
116
+ sendMessageReactionStanza(messageId: string, roomJid: string, reactionsList: string[], data?: ReactionStanzaData): void;
116
117
  sendTextMessageWithTranslateTagStanza(roomJID: string, firstName: string, lastName: string, photo: string, walletAddress: string, userMessage: string, notDisplayedValue?: string, isReply?: boolean, showInChannel?: boolean, mainMessage?: string, langSource?: Iso639_1Codes): void;
117
118
  disconnect?(options?: {
118
119
  suppressReconnect?: boolean;
@@ -0,0 +1 @@
1
+ export declare function mirrorCallAuthToWorker(token: string | null | undefined): Promise<void>;
@@ -0,0 +1,12 @@
1
+ export type CallOutcome = 'accepted' | 'declined' | 'ended';
2
+ export interface CallOutcomeMessage {
3
+ /** callNotificationKey of the call: its callId, or room:<room>. */
4
+ key: string;
5
+ outcome: CallOutcome;
6
+ }
7
+ export declare const CALL_OUTCOME_STORAGE_KEY = "@ethora/chat-component:callOutcome";
8
+ export declare const broadcastCallOutcome: (key: string | null | undefined, outcome: CallOutcome) => void;
9
+ /** Calls `callback` for an outcome another tab announced. Returns the unsubscribe. */
10
+ export declare const subscribeCallOutcomes: (callback: (message: CallOutcomeMessage) => void) => (() => void);
11
+ /** Test hook: forget the cached channel so a stubbed BroadcastChannel is picked up. */
12
+ export declare const resetCallBroadcastForTests: () => void;
@@ -0,0 +1,67 @@
1
+ export declare const CALL_NOTIFICATION_ACTIONS: {
2
+ action: string;
3
+ title: string;
4
+ }[];
5
+ export declare const callNotificationTag: (key: string) => string;
6
+ /**
7
+ * The key one call goes by in the page and in the service worker: its callId,
8
+ * or `room:<room bare name>` when the push or token carries none. Both sides
9
+ * must derive it the same way (the worker has its own copy, callKeyOf in
10
+ * firebase-messaging-sw.js), otherwise a call without a callId gets two
11
+ * notifications and the worker later swaps its own for a false "Missed call".
12
+ */
13
+ export declare const callNotificationKey: (callId: string | null | undefined, roomRef: string | null | undefined) => string;
14
+ /**
15
+ * Shows the "incoming call" notification. With a service worker registration
16
+ * (`useServiceWorker`) it goes through registration.showNotification, which is
17
+ * the only way to get Answer / Decline actions and to have the tap handled by
18
+ * the worker. Without one it falls back to `new Notification`, which cannot
19
+ * carry actions (the constructor throws on them), so they are dropped there.
20
+ *
21
+ * A ring shown through the registration is persistent (requireInteraction), so
22
+ * the worker is told (CALL_RING_SHOWN) and ends it at `expiresAt` (swapping it
23
+ * for "Missed call") even when this tab is closed before the ring is over.
24
+ */
25
+ export declare function showCallNotification(title: string, options: NotificationOptions & {
26
+ data?: any;
27
+ tag: string;
28
+ }, opts?: {
29
+ scope?: string;
30
+ useServiceWorker?: boolean;
31
+ onClick?: () => void;
32
+ /** When the call stops ringing (the token's exp), ms since epoch, if known. */
33
+ expiresAt?: number | null;
34
+ }): Promise<void>;
35
+ /**
36
+ * Closes the OS notification of a call, wherever it was shown: the page's own
37
+ * Notification, and anything with the call's tag in the worker registration
38
+ * (including the one the worker showed while no page was listening).
39
+ */
40
+ export declare function closeCallNotifications(key: string, scope?: string): Promise<void>;
41
+ /**
42
+ * Closes every call notification of this origin, rings and "Missed call" alike.
43
+ * For logout: whoever logs in next must not find the previous user's call
44
+ * notifications (their Answer / Decline would act on a call that is not theirs).
45
+ */
46
+ export declare function closeAllCallNotifications(scope?: string): Promise<void>;
47
+ /**
48
+ * The "Missed call" notification, the same one the service worker shows when
49
+ * it is the one that sees a ring end (same tag, same data), so whichever gets
50
+ * there first wins and the other leaves it alone. A hidden tab can reach the
51
+ * ring's end before the worker does, and the worker then finds nothing to swap;
52
+ * showing it from here as well makes the outcome independent of that order.
53
+ * `missedCallId` tells a repeat of the same call (skipped) from the next missed
54
+ * call in the room (replaces, and renotifies).
55
+ */
56
+ export declare function showMissedCallNotification(call: {
57
+ key: string;
58
+ kind: 'audio' | 'video';
59
+ callerName?: string | null;
60
+ roomBareName?: string | null;
61
+ }, opts?: {
62
+ icon?: string;
63
+ badge?: string;
64
+ scope?: string;
65
+ useServiceWorker?: boolean;
66
+ onClick?: () => void;
67
+ }): Promise<void>;
@@ -12,6 +12,8 @@ interface FcmRegistrationOptions {
12
12
  firebaseConfig?: any;
13
13
  iconPath?: string;
14
14
  badgePath?: string;
15
+ /** Same-origin path a cold-start push tap opens (default: the origin root). */
16
+ clickPath?: string;
15
17
  debug?: boolean;
16
18
  }
17
19
  /**
@@ -33,6 +35,18 @@ export declare function initPushNotifications(options?: FcmRegistrationOptions):
33
35
  * Returns an unsubscribe function.
34
36
  */
35
37
  export declare function listenForForegroundMessages(handler: (payload: MessagePayload) => void, firebaseConfig?: any): () => void;
38
+ /**
39
+ * requestPendingPushClick()
40
+ * A push tapped while no window was open is kept by the service worker, because
41
+ * the new page is not listening yet when the tap happens. Once the page's
42
+ * `message` listener is attached it calls this: the worker answers with a
43
+ * `PUSH_NOTIFICATION_CLICK` message (same shape as a warm tap) and forgets it,
44
+ * or stays silent when nothing is pending. With `discard`, the worker only
45
+ * drops the pending click (the page already took it from the `fromPush` url).
46
+ */
47
+ export declare function requestPendingPushClick(readyTimeoutMs?: number, { discard }?: {
48
+ discard?: boolean;
49
+ }): Promise<boolean>;
36
50
  /**
37
51
  * disablePushNotifications()
38
52
  */
@@ -0,0 +1,5 @@
1
+ export declare const HANDLED_CALLS_TTL_MS: number;
2
+ export declare const HANDLED_CALLS_STORAGE_KEY = "@ethora/chat-component:handledCalls";
3
+ export declare const markCallHandled: (key: string | null | undefined, now?: number) => void;
4
+ export declare const isCallHandled: (key: string | null | undefined, now?: number) => boolean;
5
+ export declare const resetHandledCalls: () => void;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Posts a message to the push service worker. Uses the controlling worker when
3
+ * the page has one, otherwise waits (briefly) for the registration to become
4
+ * active, the same way requestPendingPushClick does for a freshly loaded page.
5
+ */
6
+ export declare function postToPushServiceWorker(message: Record<string, unknown>, readyTimeoutMs?: number): Promise<boolean>;
7
+ export declare const CALL_AUTH_CACHE = "ethora-push-auth-v1";
8
+ export declare const callAuthKey: () => string;
9
+ export declare function deleteMirroredCallAuth(): Promise<void>;
10
+ export declare const PENDING_CLICK_CACHE = "ethora-push-pending-v1";
11
+ export declare const pendingClickKey: () => string;
12
+ /** Drops a tap the worker was holding for the next page load (logout). */
13
+ export declare function deletePendingPushClick(): Promise<void>;
14
+ /**
15
+ * Tells the worker whether this page can take an incoming call over (the call
16
+ * push listener is mounted with videoCalls enabled). The worker uses it to pick
17
+ * where an Answer or a tap on the call notification goes.
18
+ */
19
+ export declare function announceCallClient(ready: boolean): void;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Runs `task` while holding the lock `name`, so two contexts doing the same
3
+ * check-then-act (page and service worker showing one "Missed call") cannot
4
+ * interleave.
5
+ */
6
+ export declare function withWebLock<T>(name: string, task: () => Promise<T> | T): Promise<T>;
7
+ /**
8
+ * First caller wins. Resolves true for the context that gets the lock `name`
9
+ * (and keeps it for `holdMs`, long enough for the other tabs that received the
10
+ * same message to try and lose), false for everyone else. Without Web Locks it
11
+ * is `true` right away (a plain boolean, so the caller does not even yield).
12
+ */
13
+ export declare function claimOnce(name: string, holdMs?: number): boolean | Promise<boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ethora/chat-component",
3
- "version": "26.10.6",
3
+ "version": "26.10.8",
4
4
  "type": "module",
5
5
  "main": "dist/main.js",
6
6
  "types": "dist/main.d.ts",