@factorialco/f0-react 7.12.0 → 7.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ChatPdfThumbnail-DLaIYO-I.js → ChatPdfThumbnail-C1UcYl1H.js} +1 -1
- package/dist/{ChatPostComposerDialog-4FOpj4qy.js → ChatPostComposerDialog-BtRvJU6I.js} +3 -3
- package/dist/{DocumentToolbar-l7PxkK4o.js → DocumentToolbar-CV9lcCCY.js} +2 -2
- package/dist/{DocxViewer-CBiKF5rZ.js → DocxViewer-rl6xFuWg.js} +2 -2
- package/dist/{F0AiProcessingOverlay-BYUYtCeT.js → F0AiProcessingOverlay-DJxrxlhM.js} +1385 -1577
- package/dist/{F0CanvasPanel-B52A84Yd.js → F0CanvasPanel-Cd27SePP.js} +14105 -13839
- package/dist/{F0VideoPlayer-CYkJgfvF.js → F0VideoPlayer-sGOAl4BZ.js} +34 -34
- package/dist/{LocationMap-P9l5SS9_.js → LocationMap-B-e88fW6.js} +1 -1
- package/dist/{CoachmarkProvider-C-z3xlg6.js → MapProvider-BJSTrUhF.js} +4550 -4542
- package/dist/{SheetViewer-DiM7dzkD.js → SheetViewer-sSCtCF-k.js} +2 -2
- package/dist/{TextViewer-6MkpYRV9.js → TextViewer-J0dGSrMy.js} +2 -2
- package/dist/{VolumeMuted-DKLKhxyd.js → VolumeMuted-UfTwt2zn.js} +6 -26
- package/dist/ai.d.ts +98 -1
- package/dist/ai.js +2 -2
- package/dist/component-status.js +2 -2
- package/dist/experimental-Bp1BeeE5.js +31861 -0
- package/dist/experimental.css +1 -1
- package/dist/experimental.d.ts +1296 -12
- package/dist/experimental.js +286 -242
- package/dist/f0.d.ts +101 -1
- package/dist/f0.js +3224 -3223
- package/dist/i18n-provider-defaults.d.ts +84 -0
- package/dist/i18n-provider-defaults.js +92 -0
- package/dist/{index-iNjzeXPY.js → index--lL16aZU.js} +5 -5
- package/dist/index-D37fIjbv.js +4 -0
- package/dist/index-Dq-WsNBD.js +255 -0
- package/dist/index.css +1 -1
- package/dist/index2.css +1 -0
- package/dist/maplibre-gl-BFrhpbuU.js +24631 -0
- package/dist/{pdfWorker-5KFe_TGk.js → pdfWorker-D4wyA0qi.js} +3 -3
- package/dist/styles.css +1 -1
- package/dist/{tooltip-CMBdJvJA.js → tooltip-BElsa4MF.js} +415 -407
- package/icons/app/Floating.d.ts +4 -0
- package/icons/app/Floating.d.ts.map +1 -0
- package/icons/app/Floating.js +5 -0
- package/icons/app/index.d.ts +4 -3
- package/icons/app/index.d.ts.map +1 -1
- package/icons/app/index.js +4 -3
- package/package.json +14 -4
- package/dist/experimental-DtqXX6Z2.js +0 -53537
- package/dist/index-YxKgC6R7.js +0 -4
- /package/dist/{CoachmarkProvider.css → MapProvider.css} +0 -0
package/dist/experimental.d.ts
CHANGED
|
@@ -1072,7 +1072,7 @@ declare const ANCHOR_ATTRIBUTE = "data-f0-coachmark";
|
|
|
1072
1072
|
*/
|
|
1073
1073
|
export declare const ApplicationFrame: typeof _ApplicationFrame;
|
|
1074
1074
|
|
|
1075
|
-
declare function _ApplicationFrame({ children, sidebar, banner, ai, aiPromotion, sidePanel, }: ApplicationFrameProps): JSX_2.Element;
|
|
1075
|
+
declare function _ApplicationFrame({ children, sidebar, banner, ai, aiPromotion, sidePanel, meeting, }: ApplicationFrameProps): JSX_2.Element;
|
|
1076
1076
|
|
|
1077
1077
|
export declare interface ApplicationFrameProps {
|
|
1078
1078
|
ai?: Omit<AiChatProviderProps, "children">;
|
|
@@ -1082,6 +1082,16 @@ export declare interface ApplicationFrameProps {
|
|
|
1082
1082
|
* behaves exactly as before: present when `ai.enabled`, absent otherwise.
|
|
1083
1083
|
*/
|
|
1084
1084
|
sidePanel?: ApplicationFrameSidePanelProps;
|
|
1085
|
+
/**
|
|
1086
|
+
* Live meeting. The frame owns the one place a call can render; the host owns
|
|
1087
|
+
* the runtime. `runtime: null` (or omitting the prop) means no meeting.
|
|
1088
|
+
*
|
|
1089
|
+
* In `panel` mode the call IS the side panel's content, like a conversation.
|
|
1090
|
+
* In every other mode its window portals to `document.body`, because a
|
|
1091
|
+
* floating window cannot work under a transformed, overflow-hidden ancestor.
|
|
1092
|
+
* See `F0MeetingSurface`.
|
|
1093
|
+
*/
|
|
1094
|
+
meeting?: Omit<F0MeetingProviderProps, "children">;
|
|
1085
1095
|
banner?: React.ReactNode;
|
|
1086
1096
|
sidebar: React.ReactNode;
|
|
1087
1097
|
children: React.ReactNode;
|
|
@@ -1160,6 +1170,22 @@ export declare const AUTO_PER_PAGE_MAX = 30;
|
|
|
1160
1170
|
*/
|
|
1161
1171
|
export declare const AUTO_PER_PAGE_MIN_RESERVED_ROWS = 10;
|
|
1162
1172
|
|
|
1173
|
+
declare type AutoFocusInput = {
|
|
1174
|
+
tiles: F0MeetingTile[];
|
|
1175
|
+
/** What the user asked for, if anything. */
|
|
1176
|
+
intent: F0MeetingFocusIntent;
|
|
1177
|
+
/** Screen shares already auto-focused once, so they are not re-focused. */
|
|
1178
|
+
seenShareKeys: ReadonlySet<string>;
|
|
1179
|
+
};
|
|
1180
|
+
|
|
1181
|
+
declare type AutoFocusResult = {
|
|
1182
|
+
focusKey: string | null;
|
|
1183
|
+
/** Share keys to remember as already auto-focused. */
|
|
1184
|
+
seenShareKeys: ReadonlySet<string>;
|
|
1185
|
+
/** True when the stored intent no longer matches a live tile. */
|
|
1186
|
+
clearIntent: boolean;
|
|
1187
|
+
};
|
|
1188
|
+
|
|
1163
1189
|
export declare const AutoGrid: ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
|
|
1164
1190
|
tileSize?: "lg" | "md" | "sm" | undefined;
|
|
1165
1191
|
gap?: "0" | "1" | "2" | "3" | "4" | "lg" | "md" | "sm" | "5" | "6" | "7" | "8" | "9" | "10" | "11" | "12" | "14" | "16" | "px" | "xl" | "1.5" | "0.5" | "2.5" | undefined;
|
|
@@ -1655,6 +1681,13 @@ declare interface BreakType {
|
|
|
1655
1681
|
isPaid: boolean;
|
|
1656
1682
|
}
|
|
1657
1683
|
|
|
1684
|
+
/**
|
|
1685
|
+
* Flattens the roster into tiles, preserving the host's participant order.
|
|
1686
|
+
* Screen shares come first so they are never pushed off the visible page by a
|
|
1687
|
+
* long roster.
|
|
1688
|
+
*/
|
|
1689
|
+
export declare const buildTiles: (participants: F0MeetingParticipant[]) => F0MeetingTile[];
|
|
1690
|
+
|
|
1658
1691
|
/**
|
|
1659
1692
|
* Represents a bulk action that can be performed on a collection.
|
|
1660
1693
|
*/
|
|
@@ -4240,6 +4273,17 @@ declare const counterVariants: (props?: ({
|
|
|
4240
4273
|
|
|
4241
4274
|
declare type CountryCode = keyof TranslationsType["countries"];
|
|
4242
4275
|
|
|
4276
|
+
/**
|
|
4277
|
+
* External store for the volatile per-participant signals. These never go
|
|
4278
|
+
* through React context: with a dozen participants that would re-render the
|
|
4279
|
+
* whole room a hundred times a second. Only the leaf that draws the waveform
|
|
4280
|
+
* subscribes, so a burst of audio events repaints five `<div>`s.
|
|
4281
|
+
*
|
|
4282
|
+
* F0 ships the factory so hosts only have to call the setters from their
|
|
4283
|
+
* transport listeners — nobody should hand-roll subscribe/getSnapshot.
|
|
4284
|
+
*/
|
|
4285
|
+
export declare const createMeetingSignalStore: () => MeetingSignalStore;
|
|
4286
|
+
|
|
4243
4287
|
/**
|
|
4244
4288
|
* Credits usage data returned by the host app
|
|
4245
4289
|
*/
|
|
@@ -5251,8 +5295,10 @@ declare const defaultTranslations: {
|
|
|
5251
5295
|
readonly tomorrow: "Tomorrow";
|
|
5252
5296
|
readonly inProgress: "In progress";
|
|
5253
5297
|
readonly inProgressTitle: "Call in progress";
|
|
5298
|
+
readonly ringing: "Ringing…";
|
|
5254
5299
|
readonly summarizing: "Summarizing";
|
|
5255
5300
|
readonly finished: "Finished";
|
|
5301
|
+
readonly missed: "Missed";
|
|
5256
5302
|
readonly cancelled: "Cancelled";
|
|
5257
5303
|
readonly startingNow: "Starting now";
|
|
5258
5304
|
readonly startsIn: {
|
|
@@ -5850,6 +5896,12 @@ declare const defaultTranslations: {
|
|
|
5850
5896
|
readonly membersWithLast: "{{names}} and {{last}}";
|
|
5851
5897
|
readonly membersWithMore: "{{names}} and {{count}} more";
|
|
5852
5898
|
};
|
|
5899
|
+
readonly call: {
|
|
5900
|
+
readonly startedBy: "{{name}} started a huddle";
|
|
5901
|
+
readonly ended: "Huddle ended";
|
|
5902
|
+
readonly missed: "Missed huddle";
|
|
5903
|
+
readonly start: "Start huddle";
|
|
5904
|
+
};
|
|
5853
5905
|
readonly unreadCount: {
|
|
5854
5906
|
readonly one: "{{count}} unread";
|
|
5855
5907
|
readonly other: "{{count}} unread";
|
|
@@ -5940,6 +5992,82 @@ declare const defaultTranslations: {
|
|
|
5940
5992
|
readonly noData: "No data";
|
|
5941
5993
|
readonly canceled: "Canceled";
|
|
5942
5994
|
};
|
|
5995
|
+
readonly meeting: {
|
|
5996
|
+
readonly you: "You";
|
|
5997
|
+
readonly muted: "Muted";
|
|
5998
|
+
readonly waitingToJoin: "Waiting…";
|
|
5999
|
+
readonly sharingScreen: "Sharing screen";
|
|
6000
|
+
readonly chatPanel: "Chat";
|
|
6001
|
+
readonly transcriptPanel: "Transcript";
|
|
6002
|
+
readonly notesPanel: "Notes";
|
|
6003
|
+
readonly openChat: "Open chat";
|
|
6004
|
+
readonly closeChat: "Close chat";
|
|
6005
|
+
readonly closePanel: "Close panel";
|
|
6006
|
+
readonly notesPlaceholder: "Take notes for everyone in the call…";
|
|
6007
|
+
readonly roomChatPlaceholder: "Message this call…";
|
|
6008
|
+
readonly roomChatEmpty: "Messages here are only for this call and disappear when it ends.";
|
|
6009
|
+
readonly sendMessage: "Send";
|
|
6010
|
+
readonly notesReadOnly: "Only the host can edit these notes.";
|
|
6011
|
+
readonly transcriptEmpty: "The transcript will appear here as people speak.";
|
|
6012
|
+
readonly copyLink: "Copy link";
|
|
6013
|
+
readonly linkCopied: "Link copied";
|
|
6014
|
+
readonly handRaised: "Hand raised";
|
|
6015
|
+
readonly morePeople: "{{count}} more";
|
|
6016
|
+
readonly connecting: "Connecting…";
|
|
6017
|
+
readonly reconnecting: "Reconnecting…";
|
|
6018
|
+
readonly connectionLost: "Connection lost";
|
|
6019
|
+
readonly ended: "The meeting has ended";
|
|
6020
|
+
readonly rejoin: "Rejoin";
|
|
6021
|
+
readonly weakConnection: "Weak connection";
|
|
6022
|
+
readonly recording: "Recording";
|
|
6023
|
+
readonly cameraBlocked: "Camera access is blocked. Allow it in your browser settings to turn it on.";
|
|
6024
|
+
readonly microphoneBlocked: "Microphone access is blocked. Allow it in your browser settings to speak.";
|
|
6025
|
+
readonly cameraUnavailable: "No camera found";
|
|
6026
|
+
readonly microphoneUnavailable: "No microphone found";
|
|
6027
|
+
readonly cameraInUse: "Your camera is being used by another app";
|
|
6028
|
+
readonly microphoneInUse: "Your microphone is being used by another app";
|
|
6029
|
+
readonly audioBlocked: "Click to enable sound";
|
|
6030
|
+
readonly turnOnMicrophone: "Turn on microphone";
|
|
6031
|
+
readonly turnOffMicrophone: "Turn off microphone";
|
|
6032
|
+
readonly turnOnCamera: "Turn on camera";
|
|
6033
|
+
readonly turnOffCamera: "Turn off camera";
|
|
6034
|
+
readonly shareScreen: "Share screen";
|
|
6035
|
+
readonly stopSharing: "Stop sharing";
|
|
6036
|
+
readonly raiseHand: "Raise hand";
|
|
6037
|
+
readonly lowerHand: "Lower hand";
|
|
6038
|
+
readonly leave: "Leave";
|
|
6039
|
+
readonly moreActions: "More actions";
|
|
6040
|
+
readonly controls: "Meeting controls";
|
|
6041
|
+
readonly unreadCount: "{{count}} unread";
|
|
6042
|
+
readonly selectMicrophone: "Select microphone";
|
|
6043
|
+
readonly systemDefault: "System default";
|
|
6044
|
+
readonly selectCamera: "Select camera";
|
|
6045
|
+
readonly enterFullscreen: "Expand to fullscreen";
|
|
6046
|
+
readonly exitFullscreen: "Exit fullscreen";
|
|
6047
|
+
readonly meetingWindow: "Meeting window";
|
|
6048
|
+
readonly moveWindow: "Move meeting window";
|
|
6049
|
+
readonly pinParticipant: "Pin";
|
|
6050
|
+
readonly unpinParticipant: "Unpin";
|
|
6051
|
+
readonly modeSwitch: "Meeting position";
|
|
6052
|
+
readonly modeSidePanel: "Show in the side panel";
|
|
6053
|
+
readonly modeFloating: "Show in a floating window";
|
|
6054
|
+
readonly modeFullscreen: "Fill the screen";
|
|
6055
|
+
readonly exitPictureInPicture: "Back to the tab";
|
|
6056
|
+
readonly resizePanel: "Resize the meeting panel";
|
|
6057
|
+
readonly movedToCorner: "Meeting window moved to the {{corner}}";
|
|
6058
|
+
readonly cornerTopLeft: "top left";
|
|
6059
|
+
readonly cornerTopRight: "top right";
|
|
6060
|
+
readonly cornerBottomLeft: "bottom left";
|
|
6061
|
+
readonly cornerBottomRight: "bottom right";
|
|
6062
|
+
readonly participantJoined: "{{name}} joined";
|
|
6063
|
+
readonly participantLeft: "{{name}} left";
|
|
6064
|
+
readonly movedToFullscreen: "Meeting fills the screen";
|
|
6065
|
+
readonly movedToFloating: "Meeting in a floating window";
|
|
6066
|
+
readonly movedToSidePanel: "Meeting in the side panel";
|
|
6067
|
+
readonly movedToMinimized: "Meeting minimized";
|
|
6068
|
+
readonly movedInline: "Meeting on the page";
|
|
6069
|
+
readonly movedToPictureInPicture: "Meeting in a picture-in-picture window";
|
|
6070
|
+
};
|
|
5943
6071
|
readonly select: {
|
|
5944
6072
|
readonly noResults: "No results found";
|
|
5945
6073
|
readonly loadingMore: "Loading...";
|
|
@@ -7705,6 +7833,73 @@ export declare type F0ChatAttachment = F0ChatImageAttachment | F0ChatFileAttachm
|
|
|
7705
7833
|
* {@link F0ChatRuntime.uploadFiles} cannot tell these apart. */
|
|
7706
7834
|
export declare type F0ChatAttachSource = "button" | "drop" | "paste";
|
|
7707
7835
|
|
|
7836
|
+
declare type F0ChatCall = {
|
|
7837
|
+
id: string;
|
|
7838
|
+
state: F0ChatCallState;
|
|
7839
|
+
/** Who started it. */
|
|
7840
|
+
startedBy: F0ChatUser;
|
|
7841
|
+
/** ISO timestamp the call was started. */
|
|
7842
|
+
startedAt: string;
|
|
7843
|
+
/** ISO timestamp it ended. Drives the duration on `ended`. */
|
|
7844
|
+
endedAt?: string;
|
|
7845
|
+
/**
|
|
7846
|
+
* Who is in the room right now while `ringing` or `live`, and who was in it
|
|
7847
|
+
* once it has `ended`.
|
|
7848
|
+
*/
|
|
7849
|
+
participants?: F0ChatUser[];
|
|
7850
|
+
/**
|
|
7851
|
+
* Present only while the call can be joined. Its absence is what removes the
|
|
7852
|
+
* button — the same convention as the rest of the contract: no callback, no
|
|
7853
|
+
* action. A host that omits it on an `ended` call needs no other flag.
|
|
7854
|
+
*
|
|
7855
|
+
* Return the promise and the button spins until it settles. Joining is never
|
|
7856
|
+
* instant — a room has to be asked for first — so a host that drops the
|
|
7857
|
+
* promise leaves the card looking as if the press did nothing.
|
|
7858
|
+
*/
|
|
7859
|
+
join?: () => void | Promise<unknown>;
|
|
7860
|
+
/**
|
|
7861
|
+
* What the call was about, shown once it has `ended`. Plain text: the card
|
|
7862
|
+
* renders it whole, and a transcript-sized block does not belong in a row of
|
|
7863
|
+
* a conversation.
|
|
7864
|
+
*/
|
|
7865
|
+
summary?: string;
|
|
7866
|
+
/**
|
|
7867
|
+
* Footer buttons on the ended card. The transcript is the reason this exists
|
|
7868
|
+
* — it is long, and where it opens (a drawer, a modal, a page) is the host's
|
|
7869
|
+
* decision, not the card's.
|
|
7870
|
+
*/
|
|
7871
|
+
actions?: {
|
|
7872
|
+
label: string;
|
|
7873
|
+
icon?: IconType;
|
|
7874
|
+
onClick: () => void;
|
|
7875
|
+
}[];
|
|
7876
|
+
};
|
|
7877
|
+
|
|
7878
|
+
/**
|
|
7879
|
+
* A call in the transcript, rendered as a card with a Join button. Like a system
|
|
7880
|
+
* message it has no author, no reactions and no replies — but unlike one it is
|
|
7881
|
+
* INTERACTIVE and it MUTATES: the same id carries the call from ringing to
|
|
7882
|
+
* ended, so the history keeps one line per call.
|
|
7883
|
+
*
|
|
7884
|
+
* factorial → a Stream message whose custom fields carry the call state, patched
|
|
7885
|
+
* in place from LiveKit's webhooks (see `F0Meeting/SPEC.md`).
|
|
7886
|
+
*/
|
|
7887
|
+
declare type F0ChatCallMessage = {
|
|
7888
|
+
type: "call";
|
|
7889
|
+
id: string;
|
|
7890
|
+
/** ISO timestamp — participates in day separators and ordering. */
|
|
7891
|
+
createdAt: string;
|
|
7892
|
+
call: F0ChatCall;
|
|
7893
|
+
};
|
|
7894
|
+
|
|
7895
|
+
/**
|
|
7896
|
+
* Where a call is in its life. One call is ONE transcript item that moves
|
|
7897
|
+
* through these — not a live card plus a log line afterwards.
|
|
7898
|
+
*/
|
|
7899
|
+
declare type F0ChatCallState = (typeof f0ChatCallStates)[number];
|
|
7900
|
+
|
|
7901
|
+
declare const f0ChatCallStates: readonly ["ringing", "live", "ended", "missed"];
|
|
7902
|
+
|
|
7708
7903
|
/**
|
|
7709
7904
|
* Per-channel permissions, one per verb. Everything is optional and defaults to
|
|
7710
7905
|
* today's behavior, so hosts only express what their transport restricts
|
|
@@ -8111,8 +8306,14 @@ export declare type F0ChatHeaderAction = {
|
|
|
8111
8306
|
label: string;
|
|
8112
8307
|
icon?: IconType;
|
|
8113
8308
|
/** The host decides what happens: call a runtime method (togglePin,
|
|
8114
|
-
* toggleMute), open its own modal, navigate…
|
|
8115
|
-
|
|
8309
|
+
* toggleMute), open its own modal, navigate…
|
|
8310
|
+
*
|
|
8311
|
+
* An `inline` action that returns a promise spins until it settles, and
|
|
8312
|
+
* refuses further presses while it does. Actions that only toggle something
|
|
8313
|
+
* local return nothing and never spin; the ones worth returning are those
|
|
8314
|
+
* that go to a server before anything visibly happens — starting a huddle
|
|
8315
|
+
* being the case this was built for. */
|
|
8316
|
+
onClick: (channel: F0ChatChannel) => void | Promise<unknown>;
|
|
8116
8317
|
/** Where the action renders: inside the ellipsis overflow menu (default) or
|
|
8117
8318
|
* as its own icon button next to it. Inline requires `icon` — an inline
|
|
8118
8319
|
* action without one falls back to the menu. */
|
|
@@ -8146,7 +8347,7 @@ export declare type F0ChatImageAttachment = {
|
|
|
8146
8347
|
};
|
|
8147
8348
|
|
|
8148
8349
|
/** Anything that can appear in the transcript, oldest → newest. */
|
|
8149
|
-
export declare type F0ChatItem = F0ChatMessage | F0ChatSystemMessage | F0ChatPost;
|
|
8350
|
+
export declare type F0ChatItem = F0ChatMessage | F0ChatSystemMessage | F0ChatPost | F0ChatCallMessage;
|
|
8150
8351
|
|
|
8151
8352
|
/**
|
|
8152
8353
|
* Open Graph preview of a URL in the body (WhatsApp-style card above the text).
|
|
@@ -8508,6 +8709,14 @@ export declare type F0ChatProps = {
|
|
|
8508
8709
|
* the array per render with the current label/icon.
|
|
8509
8710
|
*/
|
|
8510
8711
|
headerActions?: F0ChatHeaderAction[] | ((channel: F0ChatChannel) => F0ChatHeaderAction[]);
|
|
8712
|
+
/**
|
|
8713
|
+
* Replaces the built-in header. `null` removes it entirely, for hosts that
|
|
8714
|
+
* already frame the chat with their own chrome — the in-call panel puts its
|
|
8715
|
+
* Chat / Transcript / Notes tabs where this header would be.
|
|
8716
|
+
*
|
|
8717
|
+
* Undefined keeps the default header, so no existing usage changes.
|
|
8718
|
+
*/
|
|
8719
|
+
header?: ReactNode | null;
|
|
8511
8720
|
};
|
|
8512
8721
|
|
|
8513
8722
|
/**
|
|
@@ -9960,6 +10169,8 @@ export declare interface F0MapProps extends WithDataTestIdProps {
|
|
|
9960
10169
|
* zoom in - best for a world-scale view. Changing it re-projects live.
|
|
9961
10170
|
*/
|
|
9962
10171
|
projection?: F0MapProjection;
|
|
10172
|
+
/** Rendering engine to draw the map with. */
|
|
10173
|
+
provider?: F0MapProvider;
|
|
9963
10174
|
/** Show the skeleton instead of the map. */
|
|
9964
10175
|
loading?: boolean;
|
|
9965
10176
|
/** Accessible label for the map region. */
|
|
@@ -9968,11 +10179,6 @@ export declare interface F0MapProps extends WithDataTestIdProps {
|
|
|
9968
10179
|
className?: string;
|
|
9969
10180
|
}
|
|
9970
10181
|
|
|
9971
|
-
/**
|
|
9972
|
-
* Which rendering engine a style is written for. The tag exists so a style
|
|
9973
|
-
* built for one engine can never be handed to another: the shapes are not
|
|
9974
|
-
* interchangeable, and without it the mismatch would only surface at runtime.
|
|
9975
|
-
*/
|
|
9976
10182
|
export declare type F0MapProvider = "maplibre";
|
|
9977
10183
|
|
|
9978
10184
|
/**
|
|
@@ -10029,6 +10235,109 @@ export declare interface F0MapViewport {
|
|
|
10029
10235
|
zoom?: number;
|
|
10030
10236
|
}
|
|
10031
10237
|
|
|
10238
|
+
/**
|
|
10239
|
+
* Makes a meeting available to the app and renders its surface.
|
|
10240
|
+
*
|
|
10241
|
+
* `runtime: null` means there is no call: no window exists and the meeting hooks
|
|
10242
|
+
* throw, exactly as they do outside a provider. This mirrors `F0AiChatProvider`
|
|
10243
|
+
* — the host owns the transport, F0 owns the UI.
|
|
10244
|
+
*
|
|
10245
|
+
* The providers render whether or not there is a call, and ONLY the surface is
|
|
10246
|
+
* conditional. That is load-bearing: `children` here is the host's entire
|
|
10247
|
+
* application, and if it moved between the root and three providers deep as a
|
|
10248
|
+
* call starts, React would reconcile the two shapes as different elements and
|
|
10249
|
+
* remount the whole app — losing all component state and, for a host that
|
|
10250
|
+
* fetches on mount, re-issuing every request on screen.
|
|
10251
|
+
*
|
|
10252
|
+
* `children` cannot simply sit outside the providers instead: in `panel` mode
|
|
10253
|
+
* the room renders as side-panel content, which the host mounts from within its
|
|
10254
|
+
* own tree, so it has to be able to read the meeting from here.
|
|
10255
|
+
*/
|
|
10256
|
+
export declare const F0Meeting: ({ runtime, actions, actionOrder, defaultMode, pictureInPicture, sidePanel, headerContent, overlay, children, }: F0MeetingProviderProps) => ReactNode;
|
|
10257
|
+
|
|
10258
|
+
export declare type F0MeetingAction = {
|
|
10259
|
+
/**
|
|
10260
|
+
* Reusing a core id (see {@link f0MeetingCoreActionIds}) PATCHES the
|
|
10261
|
+
* synthesized action instead of adding a new one, so a host can restyle the
|
|
10262
|
+
* mic button without reimplementing it.
|
|
10263
|
+
*/
|
|
10264
|
+
id: string;
|
|
10265
|
+
/** Already localized. For toggles the host rebuilds it per render. */
|
|
10266
|
+
label: string;
|
|
10267
|
+
icon: IconType;
|
|
10268
|
+
/** Shown while `pressed` — mic → MicrophoneNegative. */
|
|
10269
|
+
activeIcon?: IconType;
|
|
10270
|
+
/** Toggle semantics: renders `aria-pressed` and the active treatment. */
|
|
10271
|
+
pressed?: boolean;
|
|
10272
|
+
onClick?: () => void;
|
|
10273
|
+
disabled?: boolean;
|
|
10274
|
+
/** Why it is disabled. Without this, a disabled button is a dead end. */
|
|
10275
|
+
disabledReason?: string;
|
|
10276
|
+
/** An operation is in flight: spinner, no double-fire. */
|
|
10277
|
+
pending?: boolean;
|
|
10278
|
+
variant?: "default" | "critical";
|
|
10279
|
+
/** Collapse priority; higher survives longer. */
|
|
10280
|
+
priority?: number;
|
|
10281
|
+
/** Never collapses into the overflow menu. */
|
|
10282
|
+
pinned?: boolean;
|
|
10283
|
+
/** Actions sharing a group render adjacent, separated by a hairline. */
|
|
10284
|
+
group?: string;
|
|
10285
|
+
badge?: number | "dot";
|
|
10286
|
+
/** Restrict to some surface modes. Omit for all. */
|
|
10287
|
+
modes?: F0MeetingSurfaceMode[];
|
|
10288
|
+
/**
|
|
10289
|
+
* Shortcut hint for the tooltip. F0 renders it but does NOT bind it — global
|
|
10290
|
+
* key binding belongs to the host, which owns the rest of the app.
|
|
10291
|
+
*/
|
|
10292
|
+
shortcut?: string;
|
|
10293
|
+
/** Removes a synthesized core action entirely. */
|
|
10294
|
+
hidden?: boolean;
|
|
10295
|
+
};
|
|
10296
|
+
|
|
10297
|
+
export declare type F0MeetingActionInput = F0MeetingAction | F0MeetingActionPatch;
|
|
10298
|
+
|
|
10299
|
+
/**
|
|
10300
|
+
* A partial override of a synthesized core action. Patching only needs the id,
|
|
10301
|
+
* so relabelling the mic button does not mean restating its icon, priority and
|
|
10302
|
+
* pinning — which would be both noise and a chance to get them wrong.
|
|
10303
|
+
*/
|
|
10304
|
+
export declare type F0MeetingActionPatch = Partial<Omit<F0MeetingAction, "id">> & {
|
|
10305
|
+
id: F0MeetingCoreActionId;
|
|
10306
|
+
};
|
|
10307
|
+
|
|
10308
|
+
export declare type F0MeetingActionsProp = F0MeetingActionInput[] | ((runtime: F0MeetingRuntime) => F0MeetingActionInput[]);
|
|
10309
|
+
|
|
10310
|
+
/**
|
|
10311
|
+
* Binds a media track to a DOM element that F0 owns. F0 calls `attach` in a
|
|
10312
|
+
* layout effect and the returned cleanup on unmount / track change.
|
|
10313
|
+
*
|
|
10314
|
+
* factorial → LiveKit: `(el) => { track.attach(el); return () => track.detach(el) }`.
|
|
10315
|
+
* Going through the transport's own attach (instead of assigning `srcObject`)
|
|
10316
|
+
* is what keeps adaptive stream and dynacast working: LiveKit observes the
|
|
10317
|
+
* attached element's size and visibility to pick the simulcast layer and to
|
|
10318
|
+
* pause off-screen tracks.
|
|
10319
|
+
*/
|
|
10320
|
+
export declare type F0MeetingBinding = (element: HTMLMediaElement) => () => void;
|
|
10321
|
+
|
|
10322
|
+
/**
|
|
10323
|
+
* Per-room permissions, defaulting to allowed so hosts only express what their
|
|
10324
|
+
* token or role restricts.
|
|
10325
|
+
*
|
|
10326
|
+
* Capabilities are PERMISSIONS; the optional actions on the runtime are FEATURE
|
|
10327
|
+
* SUPPORT. Omitting `startRecording` means "this deployment has no recording";
|
|
10328
|
+
* `canRecord: false` means "recording exists but not for you".
|
|
10329
|
+
*/
|
|
10330
|
+
export declare type F0MeetingCapabilities = {
|
|
10331
|
+
canPublishAudio?: boolean;
|
|
10332
|
+
canPublishVideo?: boolean;
|
|
10333
|
+
canShareScreen?: boolean;
|
|
10334
|
+
canRecord?: boolean;
|
|
10335
|
+
canMuteOthers?: boolean;
|
|
10336
|
+
canRemoveParticipants?: boolean;
|
|
10337
|
+
/** Per-participant moderation gate (e.g. you cannot remove another host). */
|
|
10338
|
+
canModerate?: (participant: F0MeetingParticipant) => boolean;
|
|
10339
|
+
};
|
|
10340
|
+
|
|
10032
10341
|
/**
|
|
10033
10342
|
* @experimental This is an experimental component, use it at your own risk.
|
|
10034
10343
|
*/
|
|
@@ -10100,6 +10409,506 @@ export declare interface F0MeetingCardProps extends WithDataTestIdProps, DataAtt
|
|
|
10100
10409
|
secondaryActions?: CardSecondaryAction[];
|
|
10101
10410
|
}
|
|
10102
10411
|
|
|
10412
|
+
export declare const f0MeetingConnectionQualities: readonly ["excellent", "good", "poor", "lost"];
|
|
10413
|
+
|
|
10414
|
+
export declare type F0MeetingConnectionQuality = (typeof f0MeetingConnectionQualities)[number];
|
|
10415
|
+
|
|
10416
|
+
export declare type F0MeetingCoreActionId = (typeof f0MeetingCoreActionIds)[number];
|
|
10417
|
+
|
|
10418
|
+
export declare const f0MeetingCoreActionIds: readonly ["core:microphone", "core:microphoneSettings", "core:camera", "core:cameraSettings", "core:screenShare", "core:raiseHand", "core:chat", "core:leave"];
|
|
10419
|
+
|
|
10420
|
+
export declare type F0MeetingDevice = {
|
|
10421
|
+
/** MediaDeviceInfo.deviceId. */
|
|
10422
|
+
id: string;
|
|
10423
|
+
label: string;
|
|
10424
|
+
/** Marks the OS default entry so the UI can render "System default". */
|
|
10425
|
+
isDefault?: boolean;
|
|
10426
|
+
};
|
|
10427
|
+
|
|
10428
|
+
/** Why the room ended — drives the copy of the end state. */
|
|
10429
|
+
export declare type F0MeetingDisconnectReason = (typeof f0MeetingDisconnectReasons)[number];
|
|
10430
|
+
|
|
10431
|
+
export declare const f0MeetingDisconnectReasons: readonly ["user-left", "removed", "room-closed", "duplicate-identity", "server-shutdown", "connection-lost", "unknown"];
|
|
10432
|
+
|
|
10433
|
+
/**
|
|
10434
|
+
* Which tile is in the spotlight, as an INTENT rather than a key.
|
|
10435
|
+
*
|
|
10436
|
+
* A plain `string | null` cannot tell "nobody has pinned anything" apart from
|
|
10437
|
+
* "the user dismissed the spotlight", so in a one-to-one the auto rule kept
|
|
10438
|
+
* re-applying itself and the pin button did nothing. The three states make
|
|
10439
|
+
* dismissal expressible.
|
|
10440
|
+
*/
|
|
10441
|
+
export declare type F0MeetingFocusIntent = {
|
|
10442
|
+
type: "auto";
|
|
10443
|
+
} | {
|
|
10444
|
+
type: "pinned";
|
|
10445
|
+
key: string;
|
|
10446
|
+
} | {
|
|
10447
|
+
type: "none";
|
|
10448
|
+
};
|
|
10449
|
+
|
|
10450
|
+
/**
|
|
10451
|
+
* The local participant's media, split from the roster because it changes on a
|
|
10452
|
+
* different cadence and drives the control bar directly.
|
|
10453
|
+
*/
|
|
10454
|
+
export declare type F0MeetingLocalMedia = {
|
|
10455
|
+
microphone: F0MeetingLocalSource;
|
|
10456
|
+
camera: F0MeetingLocalSource;
|
|
10457
|
+
/** Omit when the host cannot share (mobile web, restricted tenants). */
|
|
10458
|
+
screenShare?: F0MeetingLocalSource;
|
|
10459
|
+
/**
|
|
10460
|
+
* Browsers block autoplay of remote audio until a user gesture. When true,
|
|
10461
|
+
* F0 renders an affordance wired to `unlockAudio`.
|
|
10462
|
+
* factorial → LiveKit `room.canPlaybackAudio === false`, resolved by
|
|
10463
|
+
* `room.startAudio()`.
|
|
10464
|
+
*/
|
|
10465
|
+
audioBlocked?: boolean;
|
|
10466
|
+
unlockAudio?: () => void | Promise<void>;
|
|
10467
|
+
};
|
|
10468
|
+
|
|
10469
|
+
/** State of one local media source. */
|
|
10470
|
+
export declare type F0MeetingLocalSource = {
|
|
10471
|
+
enabled: boolean;
|
|
10472
|
+
/** A toggle is in flight. Renders the pending state and blocks double-clicks. */
|
|
10473
|
+
pending?: boolean;
|
|
10474
|
+
permission?: F0MeetingPermission;
|
|
10475
|
+
/** Devices for the inline picker. Omit to hide the chevron entirely. */
|
|
10476
|
+
devices?: F0MeetingDevice[];
|
|
10477
|
+
selectedDeviceId?: string;
|
|
10478
|
+
selectDevice?: (deviceId: string) => void | Promise<void>;
|
|
10479
|
+
};
|
|
10480
|
+
|
|
10481
|
+
export declare type F0MeetingParticipant = {
|
|
10482
|
+
id: string;
|
|
10483
|
+
/** Display name, already resolved by the host. LiveKit `Participant.name`. */
|
|
10484
|
+
name: string;
|
|
10485
|
+
avatar?: AvatarVariant;
|
|
10486
|
+
isLocal: boolean;
|
|
10487
|
+
/**
|
|
10488
|
+
* Moderator flag — drives moderation affordances. Not a transport concept:
|
|
10489
|
+
* the host derives it from token grants or `participant.metadata`.
|
|
10490
|
+
*/
|
|
10491
|
+
isHost?: boolean;
|
|
10492
|
+
/**
|
|
10493
|
+
* A bot rather than a person (AI notetaker, transcription bot). Renders with
|
|
10494
|
+
* a distinct treatment and never counts toward "N people in the call".
|
|
10495
|
+
*/
|
|
10496
|
+
isAgent?: boolean;
|
|
10497
|
+
/** Joined but has not published anything yet. */
|
|
10498
|
+
isConnecting?: boolean;
|
|
10499
|
+
/**
|
|
10500
|
+
* Whether this person is actually in the room. Absent means `joined`, so a
|
|
10501
|
+
* host that only ever reports real participants needs no change.
|
|
10502
|
+
*
|
|
10503
|
+
* `invited` is someone the call is waiting for: they hold a tile that reads
|
|
10504
|
+
* "Waiting…", publish nothing, and do NOT count toward "N people in the
|
|
10505
|
+
* call". LiveKit does not know them — they come from the host's own list of
|
|
10506
|
+
* attendees, which is why this cannot be derived from the transport.
|
|
10507
|
+
*/
|
|
10508
|
+
presence?: F0MeetingPresence;
|
|
10509
|
+
tracks: F0MeetingTrack[];
|
|
10510
|
+
/**
|
|
10511
|
+
* ISO timestamp the hand was raised, so "who raised first" has an order.
|
|
10512
|
+
* factorial → LiveKit participant attributes or a data-channel message.
|
|
10513
|
+
*/
|
|
10514
|
+
raisedHandAt?: string;
|
|
10515
|
+
/** Free-form host label shown in the tile chip. F0 never parses it. */
|
|
10516
|
+
subtitle?: string;
|
|
10517
|
+
/**
|
|
10518
|
+
* Never crop this person's video: it is letterboxed inside its tile instead
|
|
10519
|
+
* of filling it.
|
|
10520
|
+
*
|
|
10521
|
+
* Tiles take the shape of their cell and crop the sides to fill it, which is
|
|
10522
|
+
* safe for a centred face and NOT safe for someone signing — it takes their
|
|
10523
|
+
* hands with it. Meet exposes the same escape hatch as "Show my full video to
|
|
10524
|
+
* others". The person owns the preference; F0 only honours it.
|
|
10525
|
+
*/
|
|
10526
|
+
preventCrop?: boolean;
|
|
10527
|
+
};
|
|
10528
|
+
|
|
10529
|
+
/**
|
|
10530
|
+
* Media permission as the browser reports it. Modelling it explicitly is what
|
|
10531
|
+
* lets the UI explain a black tile instead of just showing one.
|
|
10532
|
+
*
|
|
10533
|
+
* factorial → the DOMException name from `getUserMedia`: `NotAllowedError` →
|
|
10534
|
+
* "denied", `NotFoundError` → "unavailable", `NotReadableError` → "in-use".
|
|
10535
|
+
*/
|
|
10536
|
+
export declare type F0MeetingPermission = (typeof f0MeetingPermissions)[number];
|
|
10537
|
+
|
|
10538
|
+
export declare const f0MeetingPermissions: readonly ["granted", "prompt", "denied", "unavailable", "in-use"];
|
|
10539
|
+
|
|
10540
|
+
export declare type F0MeetingPresence = (typeof f0MeetingPresences)[number];
|
|
10541
|
+
|
|
10542
|
+
/**
|
|
10543
|
+
* A person in the room. `id` is the transport identity — the SAME string the
|
|
10544
|
+
* transport uses, so F0 never cross-references two id spaces internally. The
|
|
10545
|
+
* domain lookup (identity → employee name/avatar) belongs to the adapter.
|
|
10546
|
+
*
|
|
10547
|
+
* factorial → LiveKit `Participant.identity` (the employee id).
|
|
10548
|
+
*/
|
|
10549
|
+
export declare const f0MeetingPresences: readonly ["invited", "joined"];
|
|
10550
|
+
|
|
10551
|
+
/**
|
|
10552
|
+
* Makes a {@link F0MeetingRuntime} available to the meeting UI. The host owns
|
|
10553
|
+
* the runtime (a mock in stories, a LiveKit adapter in factorial); F0 only
|
|
10554
|
+
* reads it and never imports the transport.
|
|
10555
|
+
*/
|
|
10556
|
+
export declare const F0MeetingProvider: ({ runtime, children, }: {
|
|
10557
|
+
/**
|
|
10558
|
+
* `null` while there is no call. The provider still renders, so `children`
|
|
10559
|
+
* keep their position in the tree — see {@link F0Meeting}. Every hook below
|
|
10560
|
+
* throws on a null context, which keeps the contract intact: you may only read
|
|
10561
|
+
* a meeting from inside one.
|
|
10562
|
+
*/
|
|
10563
|
+
runtime: F0MeetingRuntime | null;
|
|
10564
|
+
children: ReactNode;
|
|
10565
|
+
}) => ReactNode;
|
|
10566
|
+
|
|
10567
|
+
export declare type F0MeetingProviderProps = {
|
|
10568
|
+
/** `null` when there is no active meeting: nothing mounts. */
|
|
10569
|
+
runtime: F0MeetingRuntime | null;
|
|
10570
|
+
/** Host actions, merged by id with the synthesized core ones. */
|
|
10571
|
+
actions?: F0MeetingActionsProp;
|
|
10572
|
+
/** Explicit left-to-right order by action id. Unlisted ids keep their slot. */
|
|
10573
|
+
actionOrder?: string[];
|
|
10574
|
+
/** Surface mode when a meeting first appears. */
|
|
10575
|
+
defaultMode?: F0MeetingSurfaceDestination;
|
|
10576
|
+
/**
|
|
10577
|
+
* Whether the browser may move the call into its picture-in-picture window
|
|
10578
|
+
* when the user leaves the tab. On by default. There is no button for it,
|
|
10579
|
+
* and nothing happens on a browser without either PiP API.
|
|
10580
|
+
*/
|
|
10581
|
+
pictureInPicture?: boolean;
|
|
10582
|
+
/**
|
|
10583
|
+
* The tabs of the in-call side panel (chat, transcript, notes). F0 renders
|
|
10584
|
+
* the bar and owns whether the panel is open, because the button that opens
|
|
10585
|
+
* it lives in F0's own control bar — a bare `ReactNode` could not supply the
|
|
10586
|
+
* tab labels or the unread badge that button needs.
|
|
10587
|
+
*/
|
|
10588
|
+
sidePanel?: F0MeetingSidePanel;
|
|
10589
|
+
/** Host content rendered in the window header, before the mode controls. */
|
|
10590
|
+
headerContent?: React.ReactNode;
|
|
10591
|
+
/** Host content rendered above the whole room (banners, upsells). */
|
|
10592
|
+
overlay?: React.ReactNode;
|
|
10593
|
+
children?: React.ReactNode;
|
|
10594
|
+
};
|
|
10595
|
+
|
|
10596
|
+
export declare type F0MeetingReaction = {
|
|
10597
|
+
id: string;
|
|
10598
|
+
participantId: string;
|
|
10599
|
+
emoji: string;
|
|
10600
|
+
at: string;
|
|
10601
|
+
};
|
|
10602
|
+
|
|
10603
|
+
export declare type F0MeetingRecording = {
|
|
10604
|
+
active: boolean;
|
|
10605
|
+
startedBy?: F0MeetingParticipant;
|
|
10606
|
+
startedAt?: string;
|
|
10607
|
+
/** Legal copy is host-provided and already localized. */
|
|
10608
|
+
consentNotice?: string;
|
|
10609
|
+
};
|
|
10610
|
+
|
|
10611
|
+
/**
|
|
10612
|
+
* The room itself: grid, controls and state chrome. It knows nothing about the
|
|
10613
|
+
* window that hosts it — the surface owns position, size and mode, exactly as
|
|
10614
|
+
* `F0Chat` takes its window controls as callbacks.
|
|
10615
|
+
*/
|
|
10616
|
+
export declare const F0MeetingRoom: ({ actions, actionOrder, sidePanel, overlay, }: F0MeetingRoomProps) => JSX_2.Element;
|
|
10617
|
+
|
|
10618
|
+
export declare type F0MeetingRoomInfo = {
|
|
10619
|
+
id: string;
|
|
10620
|
+
/** Shown in the header and in the minimized pill. */
|
|
10621
|
+
title: string;
|
|
10622
|
+
avatar?: AvatarVariant;
|
|
10623
|
+
/**
|
|
10624
|
+
* ISO timestamp the call started — drives the elapsed timer. LiveKit exposes
|
|
10625
|
+
* no room start time, so the adapter uses its own backend value and falls
|
|
10626
|
+
* back to local join time.
|
|
10627
|
+
*/
|
|
10628
|
+
startedAt?: string;
|
|
10629
|
+
/** Where this meeting came from, so the header can link back to it. */
|
|
10630
|
+
origin?: {
|
|
10631
|
+
label: string;
|
|
10632
|
+
onNavigate: () => void;
|
|
10633
|
+
};
|
|
10634
|
+
};
|
|
10635
|
+
|
|
10636
|
+
export declare type F0MeetingRoomProps = {
|
|
10637
|
+
actions?: F0MeetingActionsProp;
|
|
10638
|
+
actionOrder?: string[];
|
|
10639
|
+
sidePanel?: F0MeetingSidePanel;
|
|
10640
|
+
overlay?: React.ReactNode;
|
|
10641
|
+
};
|
|
10642
|
+
|
|
10643
|
+
/** The roster slice: changes on join/leave/publish, not on every packet. */
|
|
10644
|
+
export declare type F0MeetingRoster = {
|
|
10645
|
+
room: F0MeetingRoomInfo;
|
|
10646
|
+
status: F0MeetingStatus;
|
|
10647
|
+
participants: F0MeetingParticipant[];
|
|
10648
|
+
localMedia: F0MeetingLocalMedia;
|
|
10649
|
+
recording?: F0MeetingRecording;
|
|
10650
|
+
signals?: F0MeetingSignalStore;
|
|
10651
|
+
};
|
|
10652
|
+
|
|
10653
|
+
/**
|
|
10654
|
+
* The data and actions a host provides to drive the meeting UI. F0 is headless:
|
|
10655
|
+
* it never touches the transport. A mock runtime powers Storybook; factorial
|
|
10656
|
+
* implements this against LiveKit.
|
|
10657
|
+
*
|
|
10658
|
+
* As in {@link F0ChatRuntime}, optional callbacks are CAPABILITY DETECTION:
|
|
10659
|
+
* omitting `setScreenShareEnabled` removes the screen-share button entirely.
|
|
10660
|
+
*/
|
|
10661
|
+
export declare type F0MeetingRuntime = {
|
|
10662
|
+
room: F0MeetingRoomInfo;
|
|
10663
|
+
status: F0MeetingStatus;
|
|
10664
|
+
/** Only meaningful with `status: "disconnected"`. */
|
|
10665
|
+
disconnectReason?: F0MeetingDisconnectReason;
|
|
10666
|
+
/** Human-readable failure, already localized. `status: "error"` only. */
|
|
10667
|
+
errorMessage?: string;
|
|
10668
|
+
localParticipantId: string;
|
|
10669
|
+
/**
|
|
10670
|
+
* Everyone in the room INCLUDING the local participant, in a stable order the
|
|
10671
|
+
* host controls (join order). F0 owns speaker promotion and pagination on top
|
|
10672
|
+
* of this — a host that reorders on every speaker change makes the grid churn.
|
|
10673
|
+
*/
|
|
10674
|
+
participants: F0MeetingParticipant[];
|
|
10675
|
+
localMedia: F0MeetingLocalMedia;
|
|
10676
|
+
/**
|
|
10677
|
+
* Volatile per-participant signals. Omit and F0 degrades gracefully to muted
|
|
10678
|
+
* flags with no waveform and no quality bars, which is what tests and simple
|
|
10679
|
+
* hosts want.
|
|
10680
|
+
*/
|
|
10681
|
+
signals?: F0MeetingSignalStore;
|
|
10682
|
+
/**
|
|
10683
|
+
* Leave the room. F0 never calls this implicitly — not on unmount, not on
|
|
10684
|
+
* Escape, not on navigation. Hanging up must be an explicit user act.
|
|
10685
|
+
*/
|
|
10686
|
+
leave: () => void | Promise<void>;
|
|
10687
|
+
setMicrophoneEnabled: (enabled: boolean) => void | Promise<void>;
|
|
10688
|
+
setCameraEnabled: (enabled: boolean) => void | Promise<void>;
|
|
10689
|
+
setScreenShareEnabled?: (enabled: boolean) => void | Promise<void>;
|
|
10690
|
+
startRecording?: () => void | Promise<void>;
|
|
10691
|
+
stopRecording?: () => void | Promise<void>;
|
|
10692
|
+
recording?: F0MeetingRecording;
|
|
10693
|
+
setHandRaised?: (raised: boolean) => void | Promise<void>;
|
|
10694
|
+
sendReaction?: (emoji: string) => void | Promise<void>;
|
|
10695
|
+
/** Transient reactions to animate; the host prunes them after a few seconds. */
|
|
10696
|
+
reactions?: F0MeetingReaction[];
|
|
10697
|
+
muteParticipant?: (participantId: string) => void | Promise<void>;
|
|
10698
|
+
removeParticipant?: (participantId: string) => void | Promise<void>;
|
|
10699
|
+
/**
|
|
10700
|
+
* Live transcription. Omit and the panel has no Transcript tab at all —
|
|
10701
|
+
* the usual capability-by-presence rule.
|
|
10702
|
+
*/
|
|
10703
|
+
transcript?: F0MeetingTranscriptSegment[];
|
|
10704
|
+
/** Shared notes for the room. Present without `setNotes` means read-only. */
|
|
10705
|
+
notes?: string;
|
|
10706
|
+
setNotes?: (value: string) => void;
|
|
10707
|
+
/** Retry after a failed connect — wires the Rejoin action. */
|
|
10708
|
+
reconnect?: () => void | Promise<void>;
|
|
10709
|
+
capabilities?: F0MeetingCapabilities;
|
|
10710
|
+
};
|
|
10711
|
+
|
|
10712
|
+
export declare type F0MeetingSidePanel = {
|
|
10713
|
+
tabs: F0MeetingSidePanelTab[];
|
|
10714
|
+
defaultTabId?: string;
|
|
10715
|
+
};
|
|
10716
|
+
|
|
10717
|
+
/**
|
|
10718
|
+
* A tab in the room's side panel. F0 owns the bar, the selection and the close
|
|
10719
|
+
* button; the host owns what is inside each tab.
|
|
10720
|
+
*/
|
|
10721
|
+
export declare type F0MeetingSidePanelTab = {
|
|
10722
|
+
id: string;
|
|
10723
|
+
label: string;
|
|
10724
|
+
content: React.ReactNode;
|
|
10725
|
+
/** Unread count on the tab and on the control-bar button that opens it. */
|
|
10726
|
+
badge?: number;
|
|
10727
|
+
};
|
|
10728
|
+
|
|
10729
|
+
/**
|
|
10730
|
+
* Per-participant volatile state. Read through `useSyncExternalStore`, never
|
|
10731
|
+
* through context: with a dozen participants LiveKit emits these at 10–20 Hz,
|
|
10732
|
+
* which would re-render the whole tree a hundred times a second.
|
|
10733
|
+
*/
|
|
10734
|
+
export declare type F0MeetingSignal = {
|
|
10735
|
+
/** 0..1, smoothed by the host. LiveKit `Participant.audioLevel`. */
|
|
10736
|
+
audioLevel: number;
|
|
10737
|
+
isSpeaking: boolean;
|
|
10738
|
+
quality: F0MeetingConnectionQuality;
|
|
10739
|
+
};
|
|
10740
|
+
|
|
10741
|
+
/**
|
|
10742
|
+
* Minimal external-store protocol. F0 exports `createMeetingSignalStore` so
|
|
10743
|
+
* hosts never implement subscribe/getSnapshot themselves — the adapter just
|
|
10744
|
+
* calls the setters from its transport listeners.
|
|
10745
|
+
*/
|
|
10746
|
+
export declare type F0MeetingSignalStore = {
|
|
10747
|
+
subscribe: (participantId: string, listener: () => void) => () => void;
|
|
10748
|
+
/**
|
|
10749
|
+
* MUST return the same object identity while nothing changed, or
|
|
10750
|
+
* `useSyncExternalStore` loops forever.
|
|
10751
|
+
*/
|
|
10752
|
+
getSnapshot: (participantId: string) => F0MeetingSignal;
|
|
10753
|
+
subscribeSpeakers: (listener: () => void) => () => void;
|
|
10754
|
+
/** Identity changes only when the SET changes, so the grid doesn't churn. */
|
|
10755
|
+
getSpeakers: () => readonly string[];
|
|
10756
|
+
};
|
|
10757
|
+
|
|
10758
|
+
/**
|
|
10759
|
+
* Reserves space for the meeting on a dedicated page.
|
|
10760
|
+
*
|
|
10761
|
+
* It renders nothing: it is an empty box that publishes its viewport rect, and
|
|
10762
|
+
* the window — which stays in its portal — animates to that rect. Teleporting
|
|
10763
|
+
* by measurement instead of reparenting is what keeps the `<video>` elements
|
|
10764
|
+
* mounted across navigation, and it makes the fullscreen ↔ inline ↔ floating
|
|
10765
|
+
* transition a single animation of x/y/width/height.
|
|
10766
|
+
*/
|
|
10767
|
+
export declare const F0MeetingSlot: () => JSX_2.Element;
|
|
10768
|
+
|
|
10769
|
+
/**
|
|
10770
|
+
* The slow-moving slice, behind a SEPARATE context with a stable value. LiveKit
|
|
10771
|
+
* emits audio levels, speaking changes and quality updates at 10–20 Hz per
|
|
10772
|
+
* participant; anything mounted per-tile that read the full runtime would
|
|
10773
|
+
* re-render on every one of them, defeating the tile memoization.
|
|
10774
|
+
*
|
|
10775
|
+
* The action callbacks are identity-stable delegates into the latest runtime.
|
|
10776
|
+
*/
|
|
10777
|
+
export declare type F0MeetingStable = {
|
|
10778
|
+
roomId: string;
|
|
10779
|
+
localParticipantId: string;
|
|
10780
|
+
capabilities?: F0MeetingCapabilities;
|
|
10781
|
+
/**
|
|
10782
|
+
* Presence flags, not the callbacks themselves: optional runtime actions gate
|
|
10783
|
+
* UI affordances by PRESENCE, so the memo tracks presence, not identity.
|
|
10784
|
+
*/
|
|
10785
|
+
hasScreenShare: boolean;
|
|
10786
|
+
hasRecording: boolean;
|
|
10787
|
+
hasReactions: boolean;
|
|
10788
|
+
hasRaiseHand: boolean;
|
|
10789
|
+
hasModeration: boolean;
|
|
10790
|
+
hasReconnect: boolean;
|
|
10791
|
+
setMicrophoneEnabled: (enabled: boolean) => void;
|
|
10792
|
+
setCameraEnabled: (enabled: boolean) => void;
|
|
10793
|
+
setScreenShareEnabled: (enabled: boolean) => void;
|
|
10794
|
+
setHandRaised: (raised: boolean) => void;
|
|
10795
|
+
sendReaction: (emoji: string) => void;
|
|
10796
|
+
muteParticipant: (participantId: string) => void;
|
|
10797
|
+
removeParticipant: (participantId: string) => void;
|
|
10798
|
+
reconnect: () => void;
|
|
10799
|
+
leave: () => void;
|
|
10800
|
+
};
|
|
10801
|
+
|
|
10802
|
+
/**
|
|
10803
|
+
* Room lifecycle. `reconnecting` shows a non-blocking banner and FREEZES the
|
|
10804
|
+
* last video frame instead of clearing tiles — clearing on a two-second ICE
|
|
10805
|
+
* restart is the worst thing a call UI can do.
|
|
10806
|
+
*
|
|
10807
|
+
* factorial → LiveKit `Room.state` plus the `Disconnected` event's reason.
|
|
10808
|
+
*/
|
|
10809
|
+
export declare type F0MeetingStatus = (typeof f0MeetingStatuses)[number];
|
|
10810
|
+
|
|
10811
|
+
export declare const f0MeetingStatuses: readonly ["idle", "connecting", "connected", "reconnecting", "disconnected", "error"];
|
|
10812
|
+
|
|
10813
|
+
/**
|
|
10814
|
+
* Mounts the room into a portal on `document.body`, once, for the whole life of
|
|
10815
|
+
* the meeting — for every mode EXCEPT `panel` and `pip`.
|
|
10816
|
+
*
|
|
10817
|
+
* It lives outside the application frame on purpose. The frame's root is
|
|
10818
|
+
* `overflow-hidden` and contains transformed elements, and a transformed
|
|
10819
|
+
* ancestor breaks `position: fixed` for everything inside it — which is exactly
|
|
10820
|
+
* what a free-floating window needs. Portalling also keeps the frame's own
|
|
10821
|
+
* z-index map untouched: the surface only claims the 40–49 band at body level,
|
|
10822
|
+
* deliberately below Radix dialogs so a modal can still cover the call.
|
|
10823
|
+
*
|
|
10824
|
+
* `panel` is the one mode with no window at all: there the room is the side
|
|
10825
|
+
* panel's content (see `MeetingPanelContent`), so it needs no chrome of its own
|
|
10826
|
+
* and no rect — the panel supplies both. `pip` has a window, but it is the
|
|
10827
|
+
* browser's: the room portals into that window's document (see `PipFrame`).
|
|
10828
|
+
*
|
|
10829
|
+
* The body-level portal element stays mounted regardless, because two things
|
|
10830
|
+
* must never leave the main document: the live region announcing the call, and
|
|
10831
|
+
* the `<audio>` elements — a media element moved to another document stops
|
|
10832
|
+
* playing, and remounting one in the middle of a sentence is a dropped word.
|
|
10833
|
+
*/
|
|
10834
|
+
export declare const F0MeetingSurface: () => JSX_2.Element | null;
|
|
10835
|
+
|
|
10836
|
+
export declare type F0MeetingSurfaceDestination = (typeof f0MeetingSurfaceDestinations)[number];
|
|
10837
|
+
|
|
10838
|
+
/** The places a call can be sent to — by the user, or by `defaultMode`. */
|
|
10839
|
+
export declare const f0MeetingSurfaceDestinations: readonly ["fullscreen", "panel", "floating", "minimized", "inline"];
|
|
10840
|
+
|
|
10841
|
+
export declare type F0MeetingSurfaceMode = (typeof f0MeetingSurfaceModes)[number];
|
|
10842
|
+
|
|
10843
|
+
/**
|
|
10844
|
+
* Everything the surface can render as. `pip` is the one mode nobody chooses:
|
|
10845
|
+
* the browser moves the call into its picture-in-picture window when the tab
|
|
10846
|
+
* is left, whatever mode it was in, and closing that window returns to it.
|
|
10847
|
+
* Never persisted, never a `defaultMode`, never a button.
|
|
10848
|
+
*/
|
|
10849
|
+
export declare const f0MeetingSurfaceModes: readonly ["fullscreen", "panel", "floating", "minimized", "inline", "pip"];
|
|
10850
|
+
|
|
10851
|
+
/**
|
|
10852
|
+
* A rendered cell. One per published camera (with a placeholder when the camera
|
|
10853
|
+
* is off) plus one per screen share, so a participant who is sharing occupies
|
|
10854
|
+
* two tiles — the same behaviour as every other call product.
|
|
10855
|
+
*/
|
|
10856
|
+
export declare type F0MeetingTile = {
|
|
10857
|
+
/** `${participantId}:${kind}` — stable across re-solves. */
|
|
10858
|
+
key: string;
|
|
10859
|
+
participant: F0MeetingParticipant;
|
|
10860
|
+
kind: Extract<F0MeetingTrackKind, "camera" | "screenShare">;
|
|
10861
|
+
/** Undefined when nothing is published: the tile renders the avatar. */
|
|
10862
|
+
track?: F0MeetingTrack;
|
|
10863
|
+
};
|
|
10864
|
+
|
|
10865
|
+
export declare type F0MeetingTrack = {
|
|
10866
|
+
/** Stable publication id. factorial → LiveKit `TrackPublication.trackSid`. */
|
|
10867
|
+
id: string;
|
|
10868
|
+
kind: F0MeetingTrackKind;
|
|
10869
|
+
/**
|
|
10870
|
+
* Identity key for the binding. F0 re-runs attach ONLY when this changes —
|
|
10871
|
+
* never on `binding`'s identity, which hosts rebuild on every transport
|
|
10872
|
+
* event. Republishing the same source (camera restart, device switch) MUST
|
|
10873
|
+
* change it. factorial → `${trackSid}:${track.mediaStreamID}`.
|
|
10874
|
+
*/
|
|
10875
|
+
bindingKey: string;
|
|
10876
|
+
binding?: F0MeetingBinding;
|
|
10877
|
+
/** Muted at the source. factorial → LiveKit `TrackPublication.isMuted`. */
|
|
10878
|
+
muted: boolean;
|
|
10879
|
+
/** Subscribed and flowing. factorial → `isSubscribed && !isMuted`. */
|
|
10880
|
+
live: boolean;
|
|
10881
|
+
/**
|
|
10882
|
+
* Intrinsic dimensions, when known — lets the tile letterbox before the
|
|
10883
|
+
* first frame lands. Screen shares are rarely 16:9, so forcing them into it
|
|
10884
|
+
* is visible. factorial → LiveKit `TrackPublication.dimensions`.
|
|
10885
|
+
*/
|
|
10886
|
+
width?: number;
|
|
10887
|
+
height?: number;
|
|
10888
|
+
};
|
|
10889
|
+
|
|
10890
|
+
export declare type F0MeetingTrackKind = (typeof f0MeetingTrackKinds)[number];
|
|
10891
|
+
|
|
10892
|
+
export declare const f0MeetingTrackKinds: readonly ["camera", "microphone", "screenShare", "screenShareAudio"];
|
|
10893
|
+
|
|
10894
|
+
/**
|
|
10895
|
+
* One line of live transcription.
|
|
10896
|
+
*
|
|
10897
|
+
* Modelled on LiveKit's own shape so the adapter is a rename: segments arrive
|
|
10898
|
+
* on the `lk.transcription` text-stream topic, and a non-final segment is
|
|
10899
|
+
* REPLACED by its final version under the same id rather than appended.
|
|
10900
|
+
* (`RoomEvent.TranscriptionReceived` is deprecated; do not wire it.)
|
|
10901
|
+
*/
|
|
10902
|
+
export declare type F0MeetingTranscriptSegment = {
|
|
10903
|
+
/** LiveKit `lk.segment_id` — shared between the interim and final versions. */
|
|
10904
|
+
id: string;
|
|
10905
|
+
participantId: string;
|
|
10906
|
+
text: string;
|
|
10907
|
+
at: string;
|
|
10908
|
+
/** LiveKit `lk.transcription_final`. Interim lines render as provisional. */
|
|
10909
|
+
isFinal: boolean;
|
|
10910
|
+
};
|
|
10911
|
+
|
|
10103
10912
|
declare type F0Message = {
|
|
10104
10913
|
id: string;
|
|
10105
10914
|
role: "user" | "assistant" | "system" | "tool";
|
|
@@ -10323,6 +11132,13 @@ export declare type F0ProgressSeriesSize = (typeof f0ProgressSeriesSizes)[number
|
|
|
10323
11132
|
|
|
10324
11133
|
export declare const f0ProgressSeriesSizes: readonly ["sm", "md", "lg"];
|
|
10325
11134
|
|
|
11135
|
+
export declare type F0Rect = {
|
|
11136
|
+
x: number;
|
|
11137
|
+
y: number;
|
|
11138
|
+
width: number;
|
|
11139
|
+
height: number;
|
|
11140
|
+
};
|
|
11141
|
+
|
|
10326
11142
|
/**
|
|
10327
11143
|
* Header for a resource detail page: avatar, title, description, status,
|
|
10328
11144
|
* metadata and its primary, secondary and overflow actions.
|
|
@@ -10916,6 +11732,29 @@ export declare interface F0VersionHistoryProps {
|
|
|
10916
11732
|
activeVersionId?: "current" | (string & {});
|
|
10917
11733
|
}
|
|
10918
11734
|
|
|
11735
|
+
export declare type F0WindowCorner = (typeof f0WindowCorners)[number];
|
|
11736
|
+
|
|
11737
|
+
export declare const f0WindowCorners: readonly ["tl", "tr", "bl", "br"];
|
|
11738
|
+
|
|
11739
|
+
/**
|
|
11740
|
+
* Anchored placement. Storing absolute coordinates is the classic mistake:
|
|
11741
|
+
* shrinking the browser leaves the window off-screen. Anchoring to a corner
|
|
11742
|
+
* keeps it where the user expects across viewport changes.
|
|
11743
|
+
*
|
|
11744
|
+
* It describes the FLOATING window only. `panel` mode stores nothing here: the
|
|
11745
|
+
* room is the side panel's content there, so its width is the panel's and is
|
|
11746
|
+
* persisted by the panel — which is also why docking and undocking returns the
|
|
11747
|
+
* exact floating size the user had chosen.
|
|
11748
|
+
*/
|
|
11749
|
+
export declare type F0WindowPlacement = {
|
|
11750
|
+
corner: F0WindowCorner;
|
|
11751
|
+
/** Distance from the anchored corner, in px, always positive. */
|
|
11752
|
+
dx: number;
|
|
11753
|
+
dy: number;
|
|
11754
|
+
width: number;
|
|
11755
|
+
height: number;
|
|
11756
|
+
};
|
|
11757
|
+
|
|
10919
11758
|
/**
|
|
10920
11759
|
* @deprecated Renamed to `F0SearchInput` to match the F0 input vocabulary
|
|
10921
11760
|
* (any component where the user types in a box has the `Input` suffix and
|
|
@@ -11569,6 +12408,55 @@ declare type GraphVisualizationSettings = {
|
|
|
11569
12408
|
hidden?: string[];
|
|
11570
12409
|
};
|
|
11571
12410
|
|
|
12411
|
+
/** One row of the grid. Rows may hold different counts, so also different widths. */
|
|
12412
|
+
declare type GridRow = {
|
|
12413
|
+
count: number;
|
|
12414
|
+
tileWidth: number;
|
|
12415
|
+
tileHeight: number;
|
|
12416
|
+
};
|
|
12417
|
+
|
|
12418
|
+
export declare type GridSolution = {
|
|
12419
|
+
rows: number;
|
|
12420
|
+
/** Widest row's tile count. */
|
|
12421
|
+
cols: number;
|
|
12422
|
+
/** The NARROWEST row's tile — the worst case, which is what limits are about. */
|
|
12423
|
+
tileWidth: number;
|
|
12424
|
+
tileHeight: number;
|
|
12425
|
+
/** Tiles that fit. `count - visibleCount` go to the overflow chip. */
|
|
12426
|
+
visibleCount: number;
|
|
12427
|
+
rowSpecs: GridRow[];
|
|
12428
|
+
/** Σ tile areas: how much of the container the layout actually covers. */
|
|
12429
|
+
totalArea: number;
|
|
12430
|
+
};
|
|
12431
|
+
|
|
12432
|
+
export declare type GridSolverInput = {
|
|
12433
|
+
count: number;
|
|
12434
|
+
width: number;
|
|
12435
|
+
height: number;
|
|
12436
|
+
gap: number;
|
|
12437
|
+
/**
|
|
12438
|
+
* How far a tile may stray from `preferredAspect` to fill its cell. Inside
|
|
12439
|
+
* this range the tile simply IS the cell, so the grid leaves no dead space.
|
|
12440
|
+
*/
|
|
12441
|
+
minAspect: number;
|
|
12442
|
+
maxAspect: number;
|
|
12443
|
+
/** Only breaks ties between layouts of equal quality. */
|
|
12444
|
+
preferredAspect: number;
|
|
12445
|
+
/** Below this a tile stops being useful; the solver overflows instead. */
|
|
12446
|
+
minTileWidth: number;
|
|
12447
|
+
/**
|
|
12448
|
+
* The same floor for height. Optional, and 0 means "no floor" — a caller with
|
|
12449
|
+
* only a width in mind gets exactly the old behaviour.
|
|
12450
|
+
*/
|
|
12451
|
+
minTileHeight?: number;
|
|
12452
|
+
/**
|
|
12453
|
+
* How much smaller than the best possible worst tile a layout may make its
|
|
12454
|
+
* smallest tile to compete on total coverage. `1` (the default) is pure
|
|
12455
|
+
* maximin; `COVERAGE_TOLERANCE` is what the room uses.
|
|
12456
|
+
*/
|
|
12457
|
+
coverageTolerance?: number;
|
|
12458
|
+
};
|
|
12459
|
+
|
|
11572
12460
|
/**
|
|
11573
12461
|
* Symbol used to identify the groupId in the data
|
|
11574
12462
|
*/
|
|
@@ -12669,6 +13557,19 @@ export declare type lastIntentType = {
|
|
|
12669
13557
|
/** Sentinel for {@link F0ChatRuntime.loadMessageContext} meaning "the live tail". */
|
|
12670
13558
|
export declare const LATEST: "latest";
|
|
12671
13559
|
|
|
13560
|
+
/**
|
|
13561
|
+
* Places the solved tiles. Rows sit in equal-height slots that span the
|
|
13562
|
+
* container, and each row centres its own tiles inside its slot — so a row
|
|
13563
|
+
* that the aspect clamp shrank is centred rather than pinned to a corner.
|
|
13564
|
+
*
|
|
13565
|
+
* Returns absolute rects so the caller can animate x/y/width/height directly —
|
|
13566
|
+
* no `scale`, which is what would warp the video mid-flight.
|
|
13567
|
+
*/
|
|
13568
|
+
export declare const layoutGrid: (solution: GridSolution, box: {
|
|
13569
|
+
width: number;
|
|
13570
|
+
height: number;
|
|
13571
|
+
}, gap: number) => F0Rect[];
|
|
13572
|
+
|
|
12672
13573
|
declare type Level = (typeof levels)[number];
|
|
12673
13574
|
|
|
12674
13575
|
declare const levels: readonly ["info", "warning", "critical", "positive"];
|
|
@@ -12991,8 +13892,15 @@ export declare type MeetingAttendee = {
|
|
|
12991
13892
|
};
|
|
12992
13893
|
|
|
12993
13894
|
export declare interface MeetingJoin {
|
|
12994
|
-
/**
|
|
12995
|
-
|
|
13895
|
+
/**
|
|
13896
|
+
* Called when the Join button is pressed.
|
|
13897
|
+
*
|
|
13898
|
+
* Return the promise and the button shows a spinner until it settles, which
|
|
13899
|
+
* is what joining actually needs: a room has to be asked for before there is
|
|
13900
|
+
* anything to walk into, and without this the card sits there looking as if
|
|
13901
|
+
* the press did nothing.
|
|
13902
|
+
*/
|
|
13903
|
+
onJoin?: () => void | Promise<unknown>;
|
|
12996
13904
|
/** Navigates to the meeting room instead of handling the click. */
|
|
12997
13905
|
href?: string;
|
|
12998
13906
|
/**
|
|
@@ -13009,6 +13917,93 @@ export declare interface MeetingJoin {
|
|
|
13009
13917
|
label?: string;
|
|
13010
13918
|
}
|
|
13011
13919
|
|
|
13920
|
+
/**
|
|
13921
|
+
* Shared notes for the room.
|
|
13922
|
+
*
|
|
13923
|
+
* Uncontrolled-looking but fully controlled: the value comes from the host, so
|
|
13924
|
+
* whatever it syncs the notes through — a data channel, a document, a poll —
|
|
13925
|
+
* arrives here as a re-render rather than as a second source of truth.
|
|
13926
|
+
*/
|
|
13927
|
+
export declare const MeetingNotes: ({ value, onChange }: MeetingNotesProps) => JSX_2.Element;
|
|
13928
|
+
|
|
13929
|
+
declare type MeetingNotesProps = {
|
|
13930
|
+
value: string;
|
|
13931
|
+
/** Absent means read-only: the notes exist but this person cannot edit them. */
|
|
13932
|
+
onChange?: (value: string) => void;
|
|
13933
|
+
};
|
|
13934
|
+
|
|
13935
|
+
/**
|
|
13936
|
+
* The room AS THE SIDE PANEL'S CONTENT — not a window that covers it.
|
|
13937
|
+
*
|
|
13938
|
+
* Everything `FloatingWindow` would draw is deliberately absent: the card, the
|
|
13939
|
+
* border, the shadow, the rect, the drag handles and the resize seam all belong
|
|
13940
|
+
* to the panel, which already has one of each. What is left is the header row
|
|
13941
|
+
* and the room, filling whatever space the panel gives them.
|
|
13942
|
+
*
|
|
13943
|
+
* It takes no props ON PURPOSE. The element is handed to `present()` and stored
|
|
13944
|
+
* in the panel's state, so it must be referentially stable — a fresh element on
|
|
13945
|
+
* every render would re-present in a loop. Everything the chrome needs comes
|
|
13946
|
+
* from {@link useMeetingChrome} instead.
|
|
13947
|
+
*
|
|
13948
|
+
* ## Why it renders nothing when there is no call
|
|
13949
|
+
*
|
|
13950
|
+
* That same `present()` is what makes this OUTLIVE the call. The element lives
|
|
13951
|
+
* in the side panel's state, in the host's tree, so it is not removed with the
|
|
13952
|
+
* meeting surface — it is taken out by `MeetingPanelPresenter`'s effect cleanup,
|
|
13953
|
+
* a whole commit after the runtime became null. There is therefore exactly one
|
|
13954
|
+
* render where this is on screen with no call behind it, and reading the meeting
|
|
13955
|
+
* there used to throw and take the page down on hanging up.
|
|
13956
|
+
*/
|
|
13957
|
+
export declare const MeetingPanelContent: () => ReactNode;
|
|
13958
|
+
|
|
13959
|
+
/**
|
|
13960
|
+
* The call's own chat, for the room's side panel.
|
|
13961
|
+
*
|
|
13962
|
+
* Deliberately plainer than `F0Chat`: this transport has no reactions, no
|
|
13963
|
+
* threads, no read receipts and no history — in production it is LiveKit's data
|
|
13964
|
+
* channel, which delivers a string and forgets it. Rendering it with the full
|
|
13965
|
+
* conversation surface would promise all of those.
|
|
13966
|
+
*/
|
|
13967
|
+
export declare const MeetingRoomChat: ({ messages, onSend }: MeetingRoomChatProps) => JSX_2.Element;
|
|
13968
|
+
|
|
13969
|
+
declare type MeetingRoomChatMessage = {
|
|
13970
|
+
id: string;
|
|
13971
|
+
participantId: string;
|
|
13972
|
+
text: string;
|
|
13973
|
+
at: string;
|
|
13974
|
+
};
|
|
13975
|
+
|
|
13976
|
+
declare type MeetingRoomChatProps = {
|
|
13977
|
+
messages: MeetingRoomChatMessage[];
|
|
13978
|
+
onSend: (text: string) => void;
|
|
13979
|
+
};
|
|
13980
|
+
|
|
13981
|
+
/**
|
|
13982
|
+
* The in-call panel: chat, transcript and notes beside the grid.
|
|
13983
|
+
*
|
|
13984
|
+
* F0 owns the bar, the selection and the close button because the control that
|
|
13985
|
+
* opens the panel lives in F0's own action bar and needs the tab labels and
|
|
13986
|
+
* unread counts. What goes inside each tab is entirely the host's.
|
|
13987
|
+
*
|
|
13988
|
+
* Only one tab is mounted at a time. That is deliberate for the chat tab in
|
|
13989
|
+
* particular: its transcript is virtualized, and measuring rows inside a
|
|
13990
|
+
* display:none subtree yields zero heights that the list then has to correct
|
|
13991
|
+
* on reveal.
|
|
13992
|
+
*/
|
|
13993
|
+
export declare const MeetingSidePanel: ({ panel }: MeetingSidePanelProps) => JSX_2.Element | null;
|
|
13994
|
+
|
|
13995
|
+
declare type MeetingSidePanelProps = {
|
|
13996
|
+
panel: F0MeetingSidePanel;
|
|
13997
|
+
};
|
|
13998
|
+
|
|
13999
|
+
export declare type MeetingSignalStore = F0MeetingSignalStore & {
|
|
14000
|
+
setAudioLevel: (participantId: string, level: number) => void;
|
|
14001
|
+
setSpeaking: (participantIds: readonly string[]) => void;
|
|
14002
|
+
setQuality: (participantId: string, quality: F0MeetingConnectionQuality) => void;
|
|
14003
|
+
remove: (participantId: string) => void;
|
|
14004
|
+
reset: () => void;
|
|
14005
|
+
};
|
|
14006
|
+
|
|
13012
14007
|
export declare type MeetingState = (typeof meetingStates)[number];
|
|
13013
14008
|
|
|
13014
14009
|
/**
|
|
@@ -13018,7 +14013,102 @@ export declare type MeetingState = (typeof meetingStates)[number];
|
|
|
13018
14013
|
* the elapsed label, whether Join is actionable) is computed from `startsAt` and
|
|
13019
14014
|
* `now`.
|
|
13020
14015
|
*/
|
|
13021
|
-
export declare const meetingStates: readonly ["scheduled", "inProgress", "summarizing", "finished", "cancelled"];
|
|
14016
|
+
export declare const meetingStates: readonly ["ringing", "scheduled", "inProgress", "summarizing", "finished", "missed", "cancelled"];
|
|
14017
|
+
|
|
14018
|
+
declare type MeetingSurfaceContextValue = {
|
|
14019
|
+
/** What the user chose. Never mutated by the environment. */
|
|
14020
|
+
mode: F0MeetingSurfaceDestination;
|
|
14021
|
+
/**
|
|
14022
|
+
* What actually renders. A small viewport or an unmounted inline slot derives
|
|
14023
|
+
* a different mode without destroying the user's preference; so does an open
|
|
14024
|
+
* picture-in-picture window, which is `pip` for as long as it is open.
|
|
14025
|
+
*/
|
|
14026
|
+
effectiveMode: F0MeetingSurfaceMode;
|
|
14027
|
+
setMode: (mode: F0MeetingSurfaceDestination) => void;
|
|
14028
|
+
/** Absolute rect the window animates to, in viewport coordinates. */
|
|
14029
|
+
rect: F0Rect;
|
|
14030
|
+
isDragging: boolean;
|
|
14031
|
+
setIsDragging: (dragging: boolean) => void;
|
|
14032
|
+
/** Commit an absolute rect after a drag (re-anchors and snaps). */
|
|
14033
|
+
settleRect: (rect: F0Rect) => void;
|
|
14034
|
+
/** Commit a resize, keeping the current anchor. */
|
|
14035
|
+
resizeRect: (rect: F0Rect) => void;
|
|
14036
|
+
/** True below the md breakpoint: no dragging, pill instead of window. */
|
|
14037
|
+
isCompactViewport: boolean;
|
|
14038
|
+
/**
|
|
14039
|
+
* The frame's content area. `panel` mode does NOT use it — there the room is
|
|
14040
|
+
* the side panel's content and the panel places itself. It is what a window
|
|
14041
|
+
* sizes itself against when it has to sit BESIDE the panel (see
|
|
14042
|
+
* `fitToContent`), and the viewport when no frame published one.
|
|
14043
|
+
*/
|
|
14044
|
+
panelArea: F0Rect;
|
|
14045
|
+
/**
|
|
14046
|
+
* Whether there is a side panel for the call to be the content of.
|
|
14047
|
+
*
|
|
14048
|
+
* Registered by the application frame, the same way `F0MeetingSlot`
|
|
14049
|
+
* registers a rect for `inline`. A call rendered on its own — a story, a
|
|
14050
|
+
* test, a host with no frame — has nowhere to dock, so `panel` derives to
|
|
14051
|
+
* `floating` and the switch stops offering it.
|
|
14052
|
+
*/
|
|
14053
|
+
hasPanelSlot: boolean;
|
|
14054
|
+
setPanelSlot: (available: boolean) => void;
|
|
14055
|
+
/** Registered by `F0MeetingSlot` so `inline` knows where to fly to. */
|
|
14056
|
+
setInlineRect: (rect: F0Rect | null) => void;
|
|
14057
|
+
/**
|
|
14058
|
+
* The application frame's content region, published by the frame itself. The
|
|
14059
|
+
* side panel lives inside it — between the navigation and the content —
|
|
14060
|
+
* rather than on top of the whole viewport.
|
|
14061
|
+
*/
|
|
14062
|
+
setFrameRect: (rect: F0Rect | null) => void;
|
|
14063
|
+
/** What the user asked the spotlight to do, if anything. */
|
|
14064
|
+
focusIntent: F0MeetingFocusIntent;
|
|
14065
|
+
setFocusIntent: (intent: F0MeetingFocusIntent) => void;
|
|
14066
|
+
/** Whether the in-call side panel is open, and on which tab. */
|
|
14067
|
+
isSidePanelOpen: boolean;
|
|
14068
|
+
setSidePanelOpen: (open: boolean) => void;
|
|
14069
|
+
activeTabId: string | null;
|
|
14070
|
+
setActiveTabId: (id: string) => void;
|
|
14071
|
+
announce: (message: string) => void;
|
|
14072
|
+
liveMessage: string;
|
|
14073
|
+
/** What the browser offers for picture-in-picture, after the host's opt-out. */
|
|
14074
|
+
pipSupport: PipSupport;
|
|
14075
|
+
/** The Document PiP window, while the room renders inside it. */
|
|
14076
|
+
pipWindow: Window | null;
|
|
14077
|
+
/**
|
|
14078
|
+
* Move the call into the browser's picture-in-picture. Deliberately not a
|
|
14079
|
+
* destination of `setMode`: the only caller is the browser itself, from the
|
|
14080
|
+
* Media Session `enterpictureinpicture` action when the tab is left — so the
|
|
14081
|
+
* call follows you out of the tab the way Meet's does, and never by a button.
|
|
14082
|
+
*/
|
|
14083
|
+
enterPictureInPicture: () => void;
|
|
14084
|
+
exitPictureInPicture: () => void;
|
|
14085
|
+
/**
|
|
14086
|
+
* Every live `<video>` by tile key, kept by `TileVideo`, so video PiP has an
|
|
14087
|
+
* element to hand to the browser.
|
|
14088
|
+
*/
|
|
14089
|
+
registerVideo: (key: string, element: HTMLVideoElement | null) => void;
|
|
14090
|
+
};
|
|
14091
|
+
|
|
14092
|
+
export declare const MeetingSurfaceProvider: ({ defaultMode, roomId, pictureInPicture, children, }: {
|
|
14093
|
+
defaultMode?: F0MeetingSurfaceDestination;
|
|
14094
|
+
/** Scopes the remembered mode. A different meeting starts at `defaultMode`. */
|
|
14095
|
+
roomId?: string;
|
|
14096
|
+
pictureInPicture?: boolean;
|
|
14097
|
+
children: ReactNode;
|
|
14098
|
+
}) => ReactNode;
|
|
14099
|
+
|
|
14100
|
+
/**
|
|
14101
|
+
* Live transcription, newest at the bottom.
|
|
14102
|
+
*
|
|
14103
|
+
* Interim segments render at reduced emphasis and are REPLACED by their final
|
|
14104
|
+
* version under the same id — appending both is what turns a transcript into
|
|
14105
|
+
* the same sentence three times, each a word longer.
|
|
14106
|
+
*/
|
|
14107
|
+
export declare const MeetingTranscript: ({ segments }: MeetingTranscriptProps) => JSX_2.Element;
|
|
14108
|
+
|
|
14109
|
+
declare type MeetingTranscriptProps = {
|
|
14110
|
+
segments: F0MeetingTranscriptSegment[];
|
|
14111
|
+
};
|
|
13022
14112
|
|
|
13023
14113
|
export declare type MentionedUser = {
|
|
13024
14114
|
id: string | number;
|
|
@@ -13348,6 +14438,9 @@ export declare type NavigationTarget = {
|
|
|
13348
14438
|
|
|
13349
14439
|
declare type NavTarget = HTMLAttributeAnchorTarget;
|
|
13350
14440
|
|
|
14441
|
+
/** The quadrant the rect's centre falls into. */
|
|
14442
|
+
export declare const nearestCorner: (rect: F0Rect, viewport: Viewport) => F0WindowCorner;
|
|
14443
|
+
|
|
13351
14444
|
/**
|
|
13352
14445
|
* Utility type to extract all possible paths from nested object.
|
|
13353
14446
|
* Generates hyphenated paths from nested object structure
|
|
@@ -14432,7 +15525,13 @@ declare interface PieComputation {
|
|
|
14432
15525
|
limit?: number;
|
|
14433
15526
|
}
|
|
14434
15527
|
|
|
15528
|
+
declare type PipSupport = "document" | "video" | "none";
|
|
15529
|
+
|
|
15530
|
+
/** Re-expresses an absolute rect against a given corner. */
|
|
15531
|
+
export declare const placementFromRect: (rect: F0Rect, corner: F0WindowCorner, viewport: Viewport) => F0WindowPlacement;
|
|
15532
|
+
|
|
14435
15533
|
declare type PopoverContentProps = React_2.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> & {
|
|
15534
|
+
/** Portal target. Defaults to the nearest `PortalContainerProvider`. */
|
|
14436
15535
|
container?: HTMLElement | null;
|
|
14437
15536
|
};
|
|
14438
15537
|
|
|
@@ -14859,6 +15958,16 @@ declare type RelaxedNumericWithFormatter = Omit<NumericWithFormatter, "numericVa
|
|
|
14859
15958
|
|
|
14860
15959
|
declare type RendererDefinition = ValueDisplayRendererDefinition;
|
|
14861
15960
|
|
|
15961
|
+
/**
|
|
15962
|
+
* Promotes off-page speakers into the visible page, replacing the tile that has
|
|
15963
|
+
* been quiet the longest rather than the first one — swapping into slot 0 makes
|
|
15964
|
+
* the grid jump on every turn.
|
|
15965
|
+
*
|
|
15966
|
+
* The hold window stops two people alternating from shuffling tiles on every
|
|
15967
|
+
* exchange, which is the single most distracting thing a video grid can do.
|
|
15968
|
+
*/
|
|
15969
|
+
export declare const reorderForSpeakers: ({ tiles, speakerIds, pageSize, lastSpokenAt, now, holdMs, }: SpeakerOrderInput) => F0MeetingTile[];
|
|
15970
|
+
|
|
14862
15971
|
export declare interface ReplaceBlockNotesTextEditorPageDocumentPatch {
|
|
14863
15972
|
type: "replace_block";
|
|
14864
15973
|
targetId: string;
|
|
@@ -14885,6 +15994,19 @@ declare type RequisitionProfile = {
|
|
|
14885
15994
|
};
|
|
14886
15995
|
};
|
|
14887
15996
|
|
|
15997
|
+
/**
|
|
15998
|
+
* Decides which tile is spotlighted. Pure, so every branch is a unit test.
|
|
15999
|
+
*
|
|
16000
|
+
* Priority: the user's pin, then a screen share we have not focused yet, then
|
|
16001
|
+
* the remote participant in a one-to-one.
|
|
16002
|
+
*
|
|
16003
|
+
* The `none` intent is what makes the pin button work in a one-to-one. With a
|
|
16004
|
+
* plain nullable key, dismissing the spotlight fell straight back into the
|
|
16005
|
+
* two-camera rule below and re-focused the same person in the same render, so
|
|
16006
|
+
* the control did nothing at all.
|
|
16007
|
+
*/
|
|
16008
|
+
export declare const resolveAutoFocus: ({ tiles, intent, seenShareKeys, }: AutoFocusInput) => AutoFocusResult;
|
|
16009
|
+
|
|
14888
16010
|
export declare type ResolvedRecordType<R> = R extends RecordType ? R : RecordType;
|
|
14889
16011
|
|
|
14890
16012
|
/**
|
|
@@ -14894,6 +16016,14 @@ export declare type ResolvedRecordType<R> = R extends RecordType ? R : RecordTyp
|
|
|
14894
16016
|
*/
|
|
14895
16017
|
export declare const resolveGranularityDefinition: (key: NavigationGranularityKey) => GranularityDefinition;
|
|
14896
16018
|
|
|
16019
|
+
/**
|
|
16020
|
+
* Resolves an anchored placement into an absolute rect, clamped into the
|
|
16021
|
+
* current viewport. Anchoring to a corner (rather than storing x/y) is what
|
|
16022
|
+
* keeps the window sensible when the browser is resized: it stays glued to
|
|
16023
|
+
* "its" corner instead of drifting off-screen.
|
|
16024
|
+
*/
|
|
16025
|
+
export declare const resolvePlacement: (placement: F0WindowPlacement, viewport: Viewport, minWidth?: number, minHeight?: number) => F0Rect;
|
|
16026
|
+
|
|
14897
16027
|
/** A renderer entry in its full form — a bare function is just its `render`. */
|
|
14898
16028
|
export declare const resolveSlotRenderer: (entry: SlotRendererEntry | undefined) => {
|
|
14899
16029
|
render: SlotRenderer;
|
|
@@ -15187,6 +16317,12 @@ export declare const selectSizes: readonly ["sm", "md"];
|
|
|
15187
16317
|
|
|
15188
16318
|
export declare const selectVariants: readonly ["field", "inline"];
|
|
15189
16319
|
|
|
16320
|
+
/**
|
|
16321
|
+
* Placement after a drag: always re-anchored to the nearest corner, and pulled
|
|
16322
|
+
* flush to it when the window was dropped close enough.
|
|
16323
|
+
*/
|
|
16324
|
+
export declare const settlePlacement: (rect: F0Rect, viewport: Viewport) => F0WindowPlacement;
|
|
16325
|
+
|
|
15190
16326
|
/**
|
|
15191
16327
|
* @experimental This is an experimental component use it at your own risk
|
|
15192
16328
|
*/
|
|
@@ -15961,6 +17097,30 @@ export declare type SlotWidgetProps = HomeWidgetChrome & {
|
|
|
15961
17097
|
ctx?: HomeRenderCtx;
|
|
15962
17098
|
};
|
|
15963
17099
|
|
|
17100
|
+
/**
|
|
17101
|
+
* Picks the row split for the most people the floors admit, each row filling
|
|
17102
|
+
* the container's width on its own.
|
|
17103
|
+
*
|
|
17104
|
+
* Two ideas do the work. A tile takes the shape of its own cell within
|
|
17105
|
+
* `[minAspect, maxAspect]`, so inside that range the tile IS the cell and the
|
|
17106
|
+
* block covers the container instead of letterboxing a fixed 16:9 box in every
|
|
17107
|
+
* cell. And rows are sized independently, so an incomplete last row spreads its
|
|
17108
|
+
* tiles over the full width rather than leaving the missing cells as a hole —
|
|
17109
|
+
* three people fill the room, they do not sit next to an empty square.
|
|
17110
|
+
*
|
|
17111
|
+
* Selection is coverage within a tolerance of maximin — see `pick`.
|
|
17112
|
+
*
|
|
17113
|
+
* Pure, so it is tested without rendering.
|
|
17114
|
+
*/
|
|
17115
|
+
export declare const solveGrid: (input: GridSolverInput) => GridSolution;
|
|
17116
|
+
|
|
17117
|
+
/**
|
|
17118
|
+
* Spotlight plus a thumbnail strip. The strip is a PROPORTION of the container
|
|
17119
|
+
* rather than a fixed height: the previous implementation hard-coded 125px,
|
|
17120
|
+
* which is most of a small floating window.
|
|
17121
|
+
*/
|
|
17122
|
+
export declare const solveSpotlight: ({ stripCount, width, height, gap, stripRange, spotlightRange, }: SpotlightSolverInput) => SpotlightSolution;
|
|
17123
|
+
|
|
15964
17124
|
/**
|
|
15965
17125
|
* Type helper to extract keys from a SortingsDefinition
|
|
15966
17126
|
*/
|
|
@@ -15985,6 +17145,20 @@ export declare type SortingsStateMultiple = {
|
|
|
15985
17145
|
|
|
15986
17146
|
export declare type SortOrder = "asc" | "desc";
|
|
15987
17147
|
|
|
17148
|
+
declare type SpeakerOrderInput = {
|
|
17149
|
+
tiles: F0MeetingTile[];
|
|
17150
|
+
/** Participants currently speaking. */
|
|
17151
|
+
speakerIds: readonly string[];
|
|
17152
|
+
/** How many tiles the grid can show at once. */
|
|
17153
|
+
pageSize: number;
|
|
17154
|
+
/** participantId → epoch ms of their last turn. */
|
|
17155
|
+
lastSpokenAt: Readonly<Record<string, number>>;
|
|
17156
|
+
/** Now, injected so the function stays pure and testable. */
|
|
17157
|
+
now: number;
|
|
17158
|
+
/** A visible tile is only displaced after being quiet this long. */
|
|
17159
|
+
holdMs: number;
|
|
17160
|
+
};
|
|
17161
|
+
|
|
15988
17162
|
/**
|
|
15989
17163
|
* @experimental This is an experimental component use it at your own risk
|
|
15990
17164
|
*/
|
|
@@ -16036,6 +17210,43 @@ class?: never;
|
|
|
16036
17210
|
className?: ClassValue;
|
|
16037
17211
|
})) | undefined) => string> & RefAttributes<HTMLDivElement>, "ref"> & RefAttributes<HTMLElement | SVGElement>>;
|
|
16038
17212
|
|
|
17213
|
+
export declare type SpotlightSolution = {
|
|
17214
|
+
spotlight: F0Rect;
|
|
17215
|
+
strip: F0Rect[];
|
|
17216
|
+
/** Thumbnails that did not fit, for the "+N" chip. */
|
|
17217
|
+
stripOverflow: number;
|
|
17218
|
+
stripSide: "bottom" | "right" | "none";
|
|
17219
|
+
};
|
|
17220
|
+
|
|
17221
|
+
export declare type SpotlightSolverInput = {
|
|
17222
|
+
/** Participants that are NOT the spotlight. */
|
|
17223
|
+
stripCount: number;
|
|
17224
|
+
width: number;
|
|
17225
|
+
height: number;
|
|
17226
|
+
gap: number;
|
|
17227
|
+
/**
|
|
17228
|
+
* How far a thumbnail may stray to take the shape of its own slot. Uniform
|
|
17229
|
+
* across the strip, but derived from the container rather than fixed: a wide
|
|
17230
|
+
* room gets nearly square thumbnails, a side panel portrait ones.
|
|
17231
|
+
*/
|
|
17232
|
+
stripRange: {
|
|
17233
|
+
min: number;
|
|
17234
|
+
max: number;
|
|
17235
|
+
};
|
|
17236
|
+
/**
|
|
17237
|
+
* Cameras pass a range: the spotlight takes the shape of its box, clamped, so
|
|
17238
|
+
* it crops the sides rather than leaving most of a tall panel empty.
|
|
17239
|
+
*
|
|
17240
|
+
* Screen shares omit it and the spotlight takes the WHOLE box, letterboxing
|
|
17241
|
+
* the presentation inside its own tile. That is what puts the black exactly
|
|
17242
|
+
* where the picture is missing instead of darkening the whole room.
|
|
17243
|
+
*/
|
|
17244
|
+
spotlightRange?: {
|
|
17245
|
+
min: number;
|
|
17246
|
+
max: number;
|
|
17247
|
+
};
|
|
17248
|
+
};
|
|
17249
|
+
|
|
16039
17250
|
export declare const Stack: ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
|
|
16040
17251
|
overflow?: "hidden" | "auto" | undefined;
|
|
16041
17252
|
paddingX?: "none" | "p-4" | "p-2" | "p-8" | "p-12" | "p-16" | undefined;
|
|
@@ -16601,6 +17812,11 @@ declare type TextCellConfig = {
|
|
|
16601
17812
|
/** The HTML-ish input type of a text cell. Drives a default leading icon. */
|
|
16602
17813
|
declare type TextCellInputType = "text" | "email" | "url" | "tel";
|
|
16603
17814
|
|
|
17815
|
+
/** Ratio to lay a tile out with: screen shares keep their intrinsic one. */
|
|
17816
|
+
export declare const tileAspectRatio: (tile: F0MeetingTile, fallback: number) => number;
|
|
17817
|
+
|
|
17818
|
+
export declare const tileKey: (participantId: string, kind: string) => string;
|
|
17819
|
+
|
|
16604
17820
|
/** A button rendered in the footer at the bottom of the table of contents */
|
|
16605
17821
|
export declare type TOCAction = {
|
|
16606
17822
|
label: string;
|
|
@@ -17125,6 +18341,26 @@ declare interface UseExportActionProps<R extends RecordType, Filters extends Fil
|
|
|
17125
18341
|
/** Read the chat runtime. Throws when used outside an {@link F0ChatProvider}. */
|
|
17126
18342
|
export declare function useF0Chat(): F0ChatRuntime;
|
|
17127
18343
|
|
|
18344
|
+
export declare const useF0Meeting: () => F0MeetingRuntime;
|
|
18345
|
+
|
|
18346
|
+
export declare const useF0MeetingRoster: () => F0MeetingRoster;
|
|
18347
|
+
|
|
18348
|
+
export declare const useF0MeetingStable: () => F0MeetingStable;
|
|
18349
|
+
|
|
18350
|
+
/**
|
|
18351
|
+
* Whether there is a call at all.
|
|
18352
|
+
*
|
|
18353
|
+
* The providers render with or without one (see {@link F0Meeting}), so being
|
|
18354
|
+
* inside them does NOT imply a live runtime and the three hooks below still
|
|
18355
|
+
* throw. Ask this first from anywhere that can outlive the call.
|
|
18356
|
+
*
|
|
18357
|
+
* Which is not a rare corner: anything the HOST mounts — panel content, a slot,
|
|
18358
|
+
* its own chrome — is removed by an effect, a commit after the runtime went
|
|
18359
|
+
* null. That one render is enough to take the page down, and it is exactly what
|
|
18360
|
+
* hanging up out of `panel` mode used to do.
|
|
18361
|
+
*/
|
|
18362
|
+
export declare const useHasF0Meeting: () => boolean;
|
|
18363
|
+
|
|
17128
18364
|
export declare const useInfiniteScrollPagination: (paginationInfo: PaginationInfo | null, isLoading: boolean, isLoadingMore: boolean, loadMore: () => void) => {
|
|
17129
18365
|
loadingIndicatorRef: RefObject<HTMLTableCellElement>;
|
|
17130
18366
|
};
|
|
@@ -17136,6 +18372,34 @@ export declare const useInfiniteScrollPagination: (paginationInfo: PaginationInf
|
|
|
17136
18372
|
*/
|
|
17137
18373
|
export declare const useIsBulkChange: (count: number, threshold?: number) => boolean;
|
|
17138
18374
|
|
|
18375
|
+
/**
|
|
18376
|
+
* Subscribes to one participant's volatile signals. Call it as deep in the tree
|
|
18377
|
+
* as possible — ideally in the leaf that draws the waveform — so an audio burst
|
|
18378
|
+
* repaints a handful of bars instead of the whole tile.
|
|
18379
|
+
*
|
|
18380
|
+
* With a `selector` the component re-renders only when the SELECTED value
|
|
18381
|
+
* changes: the quality bars can watch `quality` and sit out every audio level.
|
|
18382
|
+
* `isEqual` defaults to `Object.is`, which is all a primitive needs.
|
|
18383
|
+
*
|
|
18384
|
+
* When the host provides no signal store the hook returns a frozen default, so
|
|
18385
|
+
* the room degrades to muted flags with no waveform instead of breaking.
|
|
18386
|
+
*/
|
|
18387
|
+
export declare function useMeetingSignal(participantId: string): F0MeetingSignal;
|
|
18388
|
+
|
|
18389
|
+
export declare function useMeetingSignal<T>(participantId: string, selector: (signal: F0MeetingSignal) => T, isEqual?: (previous: T, next: T) => boolean): T;
|
|
18390
|
+
|
|
18391
|
+
/** The set of currently speaking participants, for the layout's ordering. */
|
|
18392
|
+
export declare const useMeetingSpeakers: () => readonly string[];
|
|
18393
|
+
|
|
18394
|
+
export declare const useMeetingSurface: () => MeetingSurfaceContextValue;
|
|
18395
|
+
|
|
18396
|
+
/**
|
|
18397
|
+
* The same state, for consumers that render whether or not a call exists — the
|
|
18398
|
+
* application frame reads this to decide how much width to reserve, and there
|
|
18399
|
+
* is no provider at all when `runtime` is null.
|
|
18400
|
+
*/
|
|
18401
|
+
export declare const useMeetingSurfaceOptional: () => MeetingSurfaceContextValue | null;
|
|
18402
|
+
|
|
17139
18403
|
/**
|
|
17140
18404
|
* Converts an item-navigation result into the `NavigationProps` shape that
|
|
17141
18405
|
* `PageHeader` and `F0Dialog` accept (directly or via
|
|
@@ -17207,6 +18471,18 @@ export declare const useSidebarChats: () => SidebarChatStore;
|
|
|
17207
18471
|
*/
|
|
17208
18472
|
export declare function useSidePanel(): SidePanelContextValue;
|
|
17209
18473
|
|
|
18474
|
+
/**
|
|
18475
|
+
* Attaches a track to a media element F0 owns.
|
|
18476
|
+
*
|
|
18477
|
+
* The effect depends on `bindingKey` and on WHETHER there is a binding — never
|
|
18478
|
+
* on the function's identity. Hosts rebuild the runtime, and with it every
|
|
18479
|
+
* `binding` closure, on each transport event, so depending on identity would
|
|
18480
|
+
* detach and re-attach the element around twenty times a second, black-flashing
|
|
18481
|
+
* the video continuously. The presence flag is what lets a binding that arrives
|
|
18482
|
+
* a commit after its key (a stream that opened late) still get attached.
|
|
18483
|
+
*/
|
|
18484
|
+
export declare const useTrackBinding: <T extends HTMLMediaElement>(track: F0MeetingTrack | undefined) => React.RefObject<T>;
|
|
18485
|
+
|
|
17210
18486
|
export declare const useWidgetIsWide: () => boolean;
|
|
17211
18487
|
|
|
17212
18488
|
/**
|
|
@@ -17354,6 +18630,11 @@ declare interface VideoPlayerContent {
|
|
|
17354
18630
|
descriptions?: Localized<string>;
|
|
17355
18631
|
}
|
|
17356
18632
|
|
|
18633
|
+
declare type Viewport = {
|
|
18634
|
+
width: number;
|
|
18635
|
+
height: number;
|
|
18636
|
+
};
|
|
18637
|
+
|
|
17357
18638
|
/**
|
|
17358
18639
|
* Region of the canvas (in screen px) covered by external chrome — typically a
|
|
17359
18640
|
* side panel / drawer opened over the graph. All fly-to paths shift their target
|
|
@@ -17372,6 +18653,9 @@ export declare interface ViewportInset {
|
|
|
17372
18653
|
left?: number;
|
|
17373
18654
|
}
|
|
17374
18655
|
|
|
18656
|
+
/** The whole viewport as a rect, for hosts that publish no content area. */
|
|
18657
|
+
export declare const viewportRect: (viewport: Viewport) => F0Rect;
|
|
18658
|
+
|
|
17375
18659
|
/**
|
|
17376
18660
|
* @experimental This is an experimental component use it at your own risk
|
|
17377
18661
|
*/
|