@factorialco/f0-react 7.13.0 → 7.15.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-CasoTzmS.js → ChatPdfThumbnail-C1UcYl1H.js} +1 -1
- package/dist/{ChatPostComposerDialog-CLk4RYiT.js → ChatPostComposerDialog-BaOB3UHy.js} +3 -3
- package/dist/{DocumentToolbar-oQ1B9uYt.js → DocumentToolbar-CV9lcCCY.js} +2 -2
- package/dist/{DocxViewer-VCoDg5wv.js → DocxViewer-rl6xFuWg.js} +2 -2
- package/dist/{F0AiProcessingOverlay-Cv4B3Za1.js → F0AiProcessingOverlay-DJxrxlhM.js} +1385 -1577
- package/dist/{F0CanvasPanel-D3xyeygU.js → F0CanvasPanel-Cd27SePP.js} +14097 -13831
- package/dist/{F0VideoPlayer-fLkttxV3.js → F0VideoPlayer-sGOAl4BZ.js} +19 -19
- package/dist/{MapProvider-CS2D1_u-.js → MapProvider-BJSTrUhF.js} +2 -2
- package/dist/{SheetViewer-CPwlJsIf.js → SheetViewer-sSCtCF-k.js} +2 -2
- package/dist/{TextViewer-DOCvTpB4.js → TextViewer-J0dGSrMy.js} +2 -2
- package/dist/{VolumeMuted-DKLKhxyd.js → VolumeMuted-UfTwt2zn.js} +6 -26
- package/dist/ai.d.ts +99 -1
- package/dist/ai.js +2 -2
- package/dist/component-status.js +2 -2
- package/dist/{experimental-BiVfnjJ8.js → experimental-Bp9WMpVV.js} +14390 -11212
- package/dist/experimental.d.ts +1303 -7
- package/dist/experimental.js +284 -240
- package/dist/f0.d.ts +99 -1
- package/dist/f0.js +11 -11
- package/dist/i18n-provider-defaults.d.ts +85 -0
- package/dist/i18n-provider-defaults.js +93 -0
- package/dist/{index-ngfMeMZd.js → index--lL16aZU.js} +4 -4
- package/dist/index-D37fIjbv.js +4 -0
- package/dist/{index-FtDheNrV.js → index-x715W5gJ.js} +2 -2
- package/dist/{pdfWorker-lezjTonm.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 +2 -2
- package/dist/index-KQQFyh9M.js +0 -4
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: {
|
|
@@ -5806,6 +5852,7 @@ declare const defaultTranslations: {
|
|
|
5806
5852
|
readonly edit: "Edit";
|
|
5807
5853
|
readonly editing: "Editing";
|
|
5808
5854
|
readonly edited: "edited";
|
|
5855
|
+
readonly aiAssisted: "drafted with One";
|
|
5809
5856
|
readonly cancelEdit: "Cancel edit";
|
|
5810
5857
|
readonly saveEdit: "Save";
|
|
5811
5858
|
readonly you: "You";
|
|
@@ -5850,6 +5897,12 @@ declare const defaultTranslations: {
|
|
|
5850
5897
|
readonly membersWithLast: "{{names}} and {{last}}";
|
|
5851
5898
|
readonly membersWithMore: "{{names}} and {{count}} more";
|
|
5852
5899
|
};
|
|
5900
|
+
readonly call: {
|
|
5901
|
+
readonly startedBy: "{{name}} started a huddle";
|
|
5902
|
+
readonly ended: "Huddle ended";
|
|
5903
|
+
readonly missed: "Missed huddle";
|
|
5904
|
+
readonly start: "Start huddle";
|
|
5905
|
+
};
|
|
5853
5906
|
readonly unreadCount: {
|
|
5854
5907
|
readonly one: "{{count}} unread";
|
|
5855
5908
|
readonly other: "{{count}} unread";
|
|
@@ -5940,6 +5993,82 @@ declare const defaultTranslations: {
|
|
|
5940
5993
|
readonly noData: "No data";
|
|
5941
5994
|
readonly canceled: "Canceled";
|
|
5942
5995
|
};
|
|
5996
|
+
readonly meeting: {
|
|
5997
|
+
readonly you: "You";
|
|
5998
|
+
readonly muted: "Muted";
|
|
5999
|
+
readonly waitingToJoin: "Waiting…";
|
|
6000
|
+
readonly sharingScreen: "Sharing screen";
|
|
6001
|
+
readonly chatPanel: "Chat";
|
|
6002
|
+
readonly transcriptPanel: "Transcript";
|
|
6003
|
+
readonly notesPanel: "Notes";
|
|
6004
|
+
readonly openChat: "Open chat";
|
|
6005
|
+
readonly closeChat: "Close chat";
|
|
6006
|
+
readonly closePanel: "Close panel";
|
|
6007
|
+
readonly notesPlaceholder: "Take notes for everyone in the call…";
|
|
6008
|
+
readonly roomChatPlaceholder: "Message this call…";
|
|
6009
|
+
readonly roomChatEmpty: "Messages here are only for this call and disappear when it ends.";
|
|
6010
|
+
readonly sendMessage: "Send";
|
|
6011
|
+
readonly notesReadOnly: "Only the host can edit these notes.";
|
|
6012
|
+
readonly transcriptEmpty: "The transcript will appear here as people speak.";
|
|
6013
|
+
readonly copyLink: "Copy link";
|
|
6014
|
+
readonly linkCopied: "Link copied";
|
|
6015
|
+
readonly handRaised: "Hand raised";
|
|
6016
|
+
readonly morePeople: "{{count}} more";
|
|
6017
|
+
readonly connecting: "Connecting…";
|
|
6018
|
+
readonly reconnecting: "Reconnecting…";
|
|
6019
|
+
readonly connectionLost: "Connection lost";
|
|
6020
|
+
readonly ended: "The meeting has ended";
|
|
6021
|
+
readonly rejoin: "Rejoin";
|
|
6022
|
+
readonly weakConnection: "Weak connection";
|
|
6023
|
+
readonly recording: "Recording";
|
|
6024
|
+
readonly cameraBlocked: "Camera access is blocked. Allow it in your browser settings to turn it on.";
|
|
6025
|
+
readonly microphoneBlocked: "Microphone access is blocked. Allow it in your browser settings to speak.";
|
|
6026
|
+
readonly cameraUnavailable: "No camera found";
|
|
6027
|
+
readonly microphoneUnavailable: "No microphone found";
|
|
6028
|
+
readonly cameraInUse: "Your camera is being used by another app";
|
|
6029
|
+
readonly microphoneInUse: "Your microphone is being used by another app";
|
|
6030
|
+
readonly audioBlocked: "Click to enable sound";
|
|
6031
|
+
readonly turnOnMicrophone: "Turn on microphone";
|
|
6032
|
+
readonly turnOffMicrophone: "Turn off microphone";
|
|
6033
|
+
readonly turnOnCamera: "Turn on camera";
|
|
6034
|
+
readonly turnOffCamera: "Turn off camera";
|
|
6035
|
+
readonly shareScreen: "Share screen";
|
|
6036
|
+
readonly stopSharing: "Stop sharing";
|
|
6037
|
+
readonly raiseHand: "Raise hand";
|
|
6038
|
+
readonly lowerHand: "Lower hand";
|
|
6039
|
+
readonly leave: "Leave";
|
|
6040
|
+
readonly moreActions: "More actions";
|
|
6041
|
+
readonly controls: "Meeting controls";
|
|
6042
|
+
readonly unreadCount: "{{count}} unread";
|
|
6043
|
+
readonly selectMicrophone: "Select microphone";
|
|
6044
|
+
readonly systemDefault: "System default";
|
|
6045
|
+
readonly selectCamera: "Select camera";
|
|
6046
|
+
readonly enterFullscreen: "Expand to fullscreen";
|
|
6047
|
+
readonly exitFullscreen: "Exit fullscreen";
|
|
6048
|
+
readonly meetingWindow: "Meeting window";
|
|
6049
|
+
readonly moveWindow: "Move meeting window";
|
|
6050
|
+
readonly pinParticipant: "Pin";
|
|
6051
|
+
readonly unpinParticipant: "Unpin";
|
|
6052
|
+
readonly modeSwitch: "Meeting position";
|
|
6053
|
+
readonly modeSidePanel: "Show in the side panel";
|
|
6054
|
+
readonly modeFloating: "Show in a floating window";
|
|
6055
|
+
readonly modeFullscreen: "Fill the screen";
|
|
6056
|
+
readonly exitPictureInPicture: "Back to the tab";
|
|
6057
|
+
readonly resizePanel: "Resize the meeting panel";
|
|
6058
|
+
readonly movedToCorner: "Meeting window moved to the {{corner}}";
|
|
6059
|
+
readonly cornerTopLeft: "top left";
|
|
6060
|
+
readonly cornerTopRight: "top right";
|
|
6061
|
+
readonly cornerBottomLeft: "bottom left";
|
|
6062
|
+
readonly cornerBottomRight: "bottom right";
|
|
6063
|
+
readonly participantJoined: "{{name}} joined";
|
|
6064
|
+
readonly participantLeft: "{{name}} left";
|
|
6065
|
+
readonly movedToFullscreen: "Meeting fills the screen";
|
|
6066
|
+
readonly movedToFloating: "Meeting in a floating window";
|
|
6067
|
+
readonly movedToSidePanel: "Meeting in the side panel";
|
|
6068
|
+
readonly movedToMinimized: "Meeting minimized";
|
|
6069
|
+
readonly movedInline: "Meeting on the page";
|
|
6070
|
+
readonly movedToPictureInPicture: "Meeting in a picture-in-picture window";
|
|
6071
|
+
};
|
|
5943
6072
|
readonly select: {
|
|
5944
6073
|
readonly noResults: "No results found";
|
|
5945
6074
|
readonly loadingMore: "Loading...";
|
|
@@ -7705,6 +7834,73 @@ export declare type F0ChatAttachment = F0ChatImageAttachment | F0ChatFileAttachm
|
|
|
7705
7834
|
* {@link F0ChatRuntime.uploadFiles} cannot tell these apart. */
|
|
7706
7835
|
export declare type F0ChatAttachSource = "button" | "drop" | "paste";
|
|
7707
7836
|
|
|
7837
|
+
declare type F0ChatCall = {
|
|
7838
|
+
id: string;
|
|
7839
|
+
state: F0ChatCallState;
|
|
7840
|
+
/** Who started it. */
|
|
7841
|
+
startedBy: F0ChatUser;
|
|
7842
|
+
/** ISO timestamp the call was started. */
|
|
7843
|
+
startedAt: string;
|
|
7844
|
+
/** ISO timestamp it ended. Drives the duration on `ended`. */
|
|
7845
|
+
endedAt?: string;
|
|
7846
|
+
/**
|
|
7847
|
+
* Who is in the room right now while `ringing` or `live`, and who was in it
|
|
7848
|
+
* once it has `ended`.
|
|
7849
|
+
*/
|
|
7850
|
+
participants?: F0ChatUser[];
|
|
7851
|
+
/**
|
|
7852
|
+
* Present only while the call can be joined. Its absence is what removes the
|
|
7853
|
+
* button — the same convention as the rest of the contract: no callback, no
|
|
7854
|
+
* action. A host that omits it on an `ended` call needs no other flag.
|
|
7855
|
+
*
|
|
7856
|
+
* Return the promise and the button spins until it settles. Joining is never
|
|
7857
|
+
* instant — a room has to be asked for first — so a host that drops the
|
|
7858
|
+
* promise leaves the card looking as if the press did nothing.
|
|
7859
|
+
*/
|
|
7860
|
+
join?: () => void | Promise<unknown>;
|
|
7861
|
+
/**
|
|
7862
|
+
* What the call was about, shown once it has `ended`. Plain text: the card
|
|
7863
|
+
* renders it whole, and a transcript-sized block does not belong in a row of
|
|
7864
|
+
* a conversation.
|
|
7865
|
+
*/
|
|
7866
|
+
summary?: string;
|
|
7867
|
+
/**
|
|
7868
|
+
* Footer buttons on the ended card. The transcript is the reason this exists
|
|
7869
|
+
* — it is long, and where it opens (a drawer, a modal, a page) is the host's
|
|
7870
|
+
* decision, not the card's.
|
|
7871
|
+
*/
|
|
7872
|
+
actions?: {
|
|
7873
|
+
label: string;
|
|
7874
|
+
icon?: IconType;
|
|
7875
|
+
onClick: () => void;
|
|
7876
|
+
}[];
|
|
7877
|
+
};
|
|
7878
|
+
|
|
7879
|
+
/**
|
|
7880
|
+
* A call in the transcript, rendered as a card with a Join button. Like a system
|
|
7881
|
+
* message it has no author, no reactions and no replies — but unlike one it is
|
|
7882
|
+
* INTERACTIVE and it MUTATES: the same id carries the call from ringing to
|
|
7883
|
+
* ended, so the history keeps one line per call.
|
|
7884
|
+
*
|
|
7885
|
+
* factorial → a Stream message whose custom fields carry the call state, patched
|
|
7886
|
+
* in place from LiveKit's webhooks (see `F0Meeting/SPEC.md`).
|
|
7887
|
+
*/
|
|
7888
|
+
declare type F0ChatCallMessage = {
|
|
7889
|
+
type: "call";
|
|
7890
|
+
id: string;
|
|
7891
|
+
/** ISO timestamp — participates in day separators and ordering. */
|
|
7892
|
+
createdAt: string;
|
|
7893
|
+
call: F0ChatCall;
|
|
7894
|
+
};
|
|
7895
|
+
|
|
7896
|
+
/**
|
|
7897
|
+
* Where a call is in its life. One call is ONE transcript item that moves
|
|
7898
|
+
* through these — not a live card plus a log line afterwards.
|
|
7899
|
+
*/
|
|
7900
|
+
declare type F0ChatCallState = (typeof f0ChatCallStates)[number];
|
|
7901
|
+
|
|
7902
|
+
declare const f0ChatCallStates: readonly ["ringing", "live", "ended", "missed"];
|
|
7903
|
+
|
|
7708
7904
|
/**
|
|
7709
7905
|
* Per-channel permissions, one per verb. Everything is optional and defaults to
|
|
7710
7906
|
* today's behavior, so hosts only express what their transport restricts
|
|
@@ -8111,8 +8307,14 @@ export declare type F0ChatHeaderAction = {
|
|
|
8111
8307
|
label: string;
|
|
8112
8308
|
icon?: IconType;
|
|
8113
8309
|
/** The host decides what happens: call a runtime method (togglePin,
|
|
8114
|
-
* toggleMute), open its own modal, navigate…
|
|
8115
|
-
|
|
8310
|
+
* toggleMute), open its own modal, navigate…
|
|
8311
|
+
*
|
|
8312
|
+
* An `inline` action that returns a promise spins until it settles, and
|
|
8313
|
+
* refuses further presses while it does. Actions that only toggle something
|
|
8314
|
+
* local return nothing and never spin; the ones worth returning are those
|
|
8315
|
+
* that go to a server before anything visibly happens — starting a huddle
|
|
8316
|
+
* being the case this was built for. */
|
|
8317
|
+
onClick: (channel: F0ChatChannel) => void | Promise<unknown>;
|
|
8116
8318
|
/** Where the action renders: inside the ellipsis overflow menu (default) or
|
|
8117
8319
|
* as its own icon button next to it. Inline requires `icon` — an inline
|
|
8118
8320
|
* action without one falls back to the menu. */
|
|
@@ -8146,7 +8348,7 @@ export declare type F0ChatImageAttachment = {
|
|
|
8146
8348
|
};
|
|
8147
8349
|
|
|
8148
8350
|
/** Anything that can appear in the transcript, oldest → newest. */
|
|
8149
|
-
export declare type F0ChatItem = F0ChatMessage | F0ChatSystemMessage | F0ChatPost;
|
|
8351
|
+
export declare type F0ChatItem = F0ChatMessage | F0ChatSystemMessage | F0ChatPost | F0ChatCallMessage;
|
|
8150
8352
|
|
|
8151
8353
|
/**
|
|
8152
8354
|
* Open Graph preview of a URL in the body (WhatsApp-style card above the text).
|
|
@@ -8262,6 +8464,14 @@ export declare type F0ChatMessage = {
|
|
|
8262
8464
|
* reactions/read updates), so it never false-positives the label.
|
|
8263
8465
|
*/
|
|
8264
8466
|
editedAt?: string;
|
|
8467
|
+
/**
|
|
8468
|
+
* The message was drafted with One (Factorial's AI) and approved by its
|
|
8469
|
+
* author, who remains the sender. Drives the muted "drafted with One" label
|
|
8470
|
+
* after the body, next to the edited marker, so the reader and assistive
|
|
8471
|
+
* technology learn it on every surface that shows the content. The host maps
|
|
8472
|
+
* it from server-set message metadata, never from body text.
|
|
8473
|
+
*/
|
|
8474
|
+
aiAssisted?: boolean;
|
|
8265
8475
|
};
|
|
8266
8476
|
|
|
8267
8477
|
export declare type F0ChatMessageReply = {
|
|
@@ -8508,6 +8718,14 @@ export declare type F0ChatProps = {
|
|
|
8508
8718
|
* the array per render with the current label/icon.
|
|
8509
8719
|
*/
|
|
8510
8720
|
headerActions?: F0ChatHeaderAction[] | ((channel: F0ChatChannel) => F0ChatHeaderAction[]);
|
|
8721
|
+
/**
|
|
8722
|
+
* Replaces the built-in header. `null` removes it entirely, for hosts that
|
|
8723
|
+
* already frame the chat with their own chrome — the in-call panel puts its
|
|
8724
|
+
* Chat / Transcript / Notes tabs where this header would be.
|
|
8725
|
+
*
|
|
8726
|
+
* Undefined keeps the default header, so no existing usage changes.
|
|
8727
|
+
*/
|
|
8728
|
+
header?: ReactNode | null;
|
|
8511
8729
|
};
|
|
8512
8730
|
|
|
8513
8731
|
/**
|
|
@@ -10026,6 +10244,109 @@ export declare interface F0MapViewport {
|
|
|
10026
10244
|
zoom?: number;
|
|
10027
10245
|
}
|
|
10028
10246
|
|
|
10247
|
+
/**
|
|
10248
|
+
* Makes a meeting available to the app and renders its surface.
|
|
10249
|
+
*
|
|
10250
|
+
* `runtime: null` means there is no call: no window exists and the meeting hooks
|
|
10251
|
+
* throw, exactly as they do outside a provider. This mirrors `F0AiChatProvider`
|
|
10252
|
+
* — the host owns the transport, F0 owns the UI.
|
|
10253
|
+
*
|
|
10254
|
+
* The providers render whether or not there is a call, and ONLY the surface is
|
|
10255
|
+
* conditional. That is load-bearing: `children` here is the host's entire
|
|
10256
|
+
* application, and if it moved between the root and three providers deep as a
|
|
10257
|
+
* call starts, React would reconcile the two shapes as different elements and
|
|
10258
|
+
* remount the whole app — losing all component state and, for a host that
|
|
10259
|
+
* fetches on mount, re-issuing every request on screen.
|
|
10260
|
+
*
|
|
10261
|
+
* `children` cannot simply sit outside the providers instead: in `panel` mode
|
|
10262
|
+
* the room renders as side-panel content, which the host mounts from within its
|
|
10263
|
+
* own tree, so it has to be able to read the meeting from here.
|
|
10264
|
+
*/
|
|
10265
|
+
export declare const F0Meeting: ({ runtime, actions, actionOrder, defaultMode, pictureInPicture, sidePanel, headerContent, overlay, children, }: F0MeetingProviderProps) => ReactNode;
|
|
10266
|
+
|
|
10267
|
+
export declare type F0MeetingAction = {
|
|
10268
|
+
/**
|
|
10269
|
+
* Reusing a core id (see {@link f0MeetingCoreActionIds}) PATCHES the
|
|
10270
|
+
* synthesized action instead of adding a new one, so a host can restyle the
|
|
10271
|
+
* mic button without reimplementing it.
|
|
10272
|
+
*/
|
|
10273
|
+
id: string;
|
|
10274
|
+
/** Already localized. For toggles the host rebuilds it per render. */
|
|
10275
|
+
label: string;
|
|
10276
|
+
icon: IconType;
|
|
10277
|
+
/** Shown while `pressed` — mic → MicrophoneNegative. */
|
|
10278
|
+
activeIcon?: IconType;
|
|
10279
|
+
/** Toggle semantics: renders `aria-pressed` and the active treatment. */
|
|
10280
|
+
pressed?: boolean;
|
|
10281
|
+
onClick?: () => void;
|
|
10282
|
+
disabled?: boolean;
|
|
10283
|
+
/** Why it is disabled. Without this, a disabled button is a dead end. */
|
|
10284
|
+
disabledReason?: string;
|
|
10285
|
+
/** An operation is in flight: spinner, no double-fire. */
|
|
10286
|
+
pending?: boolean;
|
|
10287
|
+
variant?: "default" | "critical";
|
|
10288
|
+
/** Collapse priority; higher survives longer. */
|
|
10289
|
+
priority?: number;
|
|
10290
|
+
/** Never collapses into the overflow menu. */
|
|
10291
|
+
pinned?: boolean;
|
|
10292
|
+
/** Actions sharing a group render adjacent, separated by a hairline. */
|
|
10293
|
+
group?: string;
|
|
10294
|
+
badge?: number | "dot";
|
|
10295
|
+
/** Restrict to some surface modes. Omit for all. */
|
|
10296
|
+
modes?: F0MeetingSurfaceMode[];
|
|
10297
|
+
/**
|
|
10298
|
+
* Shortcut hint for the tooltip. F0 renders it but does NOT bind it — global
|
|
10299
|
+
* key binding belongs to the host, which owns the rest of the app.
|
|
10300
|
+
*/
|
|
10301
|
+
shortcut?: string;
|
|
10302
|
+
/** Removes a synthesized core action entirely. */
|
|
10303
|
+
hidden?: boolean;
|
|
10304
|
+
};
|
|
10305
|
+
|
|
10306
|
+
export declare type F0MeetingActionInput = F0MeetingAction | F0MeetingActionPatch;
|
|
10307
|
+
|
|
10308
|
+
/**
|
|
10309
|
+
* A partial override of a synthesized core action. Patching only needs the id,
|
|
10310
|
+
* so relabelling the mic button does not mean restating its icon, priority and
|
|
10311
|
+
* pinning — which would be both noise and a chance to get them wrong.
|
|
10312
|
+
*/
|
|
10313
|
+
export declare type F0MeetingActionPatch = Partial<Omit<F0MeetingAction, "id">> & {
|
|
10314
|
+
id: F0MeetingCoreActionId;
|
|
10315
|
+
};
|
|
10316
|
+
|
|
10317
|
+
export declare type F0MeetingActionsProp = F0MeetingActionInput[] | ((runtime: F0MeetingRuntime) => F0MeetingActionInput[]);
|
|
10318
|
+
|
|
10319
|
+
/**
|
|
10320
|
+
* Binds a media track to a DOM element that F0 owns. F0 calls `attach` in a
|
|
10321
|
+
* layout effect and the returned cleanup on unmount / track change.
|
|
10322
|
+
*
|
|
10323
|
+
* factorial → LiveKit: `(el) => { track.attach(el); return () => track.detach(el) }`.
|
|
10324
|
+
* Going through the transport's own attach (instead of assigning `srcObject`)
|
|
10325
|
+
* is what keeps adaptive stream and dynacast working: LiveKit observes the
|
|
10326
|
+
* attached element's size and visibility to pick the simulcast layer and to
|
|
10327
|
+
* pause off-screen tracks.
|
|
10328
|
+
*/
|
|
10329
|
+
export declare type F0MeetingBinding = (element: HTMLMediaElement) => () => void;
|
|
10330
|
+
|
|
10331
|
+
/**
|
|
10332
|
+
* Per-room permissions, defaulting to allowed so hosts only express what their
|
|
10333
|
+
* token or role restricts.
|
|
10334
|
+
*
|
|
10335
|
+
* Capabilities are PERMISSIONS; the optional actions on the runtime are FEATURE
|
|
10336
|
+
* SUPPORT. Omitting `startRecording` means "this deployment has no recording";
|
|
10337
|
+
* `canRecord: false` means "recording exists but not for you".
|
|
10338
|
+
*/
|
|
10339
|
+
export declare type F0MeetingCapabilities = {
|
|
10340
|
+
canPublishAudio?: boolean;
|
|
10341
|
+
canPublishVideo?: boolean;
|
|
10342
|
+
canShareScreen?: boolean;
|
|
10343
|
+
canRecord?: boolean;
|
|
10344
|
+
canMuteOthers?: boolean;
|
|
10345
|
+
canRemoveParticipants?: boolean;
|
|
10346
|
+
/** Per-participant moderation gate (e.g. you cannot remove another host). */
|
|
10347
|
+
canModerate?: (participant: F0MeetingParticipant) => boolean;
|
|
10348
|
+
};
|
|
10349
|
+
|
|
10029
10350
|
/**
|
|
10030
10351
|
* @experimental This is an experimental component, use it at your own risk.
|
|
10031
10352
|
*/
|
|
@@ -10097,6 +10418,506 @@ export declare interface F0MeetingCardProps extends WithDataTestIdProps, DataAtt
|
|
|
10097
10418
|
secondaryActions?: CardSecondaryAction[];
|
|
10098
10419
|
}
|
|
10099
10420
|
|
|
10421
|
+
export declare const f0MeetingConnectionQualities: readonly ["excellent", "good", "poor", "lost"];
|
|
10422
|
+
|
|
10423
|
+
export declare type F0MeetingConnectionQuality = (typeof f0MeetingConnectionQualities)[number];
|
|
10424
|
+
|
|
10425
|
+
export declare type F0MeetingCoreActionId = (typeof f0MeetingCoreActionIds)[number];
|
|
10426
|
+
|
|
10427
|
+
export declare const f0MeetingCoreActionIds: readonly ["core:microphone", "core:microphoneSettings", "core:camera", "core:cameraSettings", "core:screenShare", "core:raiseHand", "core:chat", "core:leave"];
|
|
10428
|
+
|
|
10429
|
+
export declare type F0MeetingDevice = {
|
|
10430
|
+
/** MediaDeviceInfo.deviceId. */
|
|
10431
|
+
id: string;
|
|
10432
|
+
label: string;
|
|
10433
|
+
/** Marks the OS default entry so the UI can render "System default". */
|
|
10434
|
+
isDefault?: boolean;
|
|
10435
|
+
};
|
|
10436
|
+
|
|
10437
|
+
/** Why the room ended — drives the copy of the end state. */
|
|
10438
|
+
export declare type F0MeetingDisconnectReason = (typeof f0MeetingDisconnectReasons)[number];
|
|
10439
|
+
|
|
10440
|
+
export declare const f0MeetingDisconnectReasons: readonly ["user-left", "removed", "room-closed", "duplicate-identity", "server-shutdown", "connection-lost", "unknown"];
|
|
10441
|
+
|
|
10442
|
+
/**
|
|
10443
|
+
* Which tile is in the spotlight, as an INTENT rather than a key.
|
|
10444
|
+
*
|
|
10445
|
+
* A plain `string | null` cannot tell "nobody has pinned anything" apart from
|
|
10446
|
+
* "the user dismissed the spotlight", so in a one-to-one the auto rule kept
|
|
10447
|
+
* re-applying itself and the pin button did nothing. The three states make
|
|
10448
|
+
* dismissal expressible.
|
|
10449
|
+
*/
|
|
10450
|
+
export declare type F0MeetingFocusIntent = {
|
|
10451
|
+
type: "auto";
|
|
10452
|
+
} | {
|
|
10453
|
+
type: "pinned";
|
|
10454
|
+
key: string;
|
|
10455
|
+
} | {
|
|
10456
|
+
type: "none";
|
|
10457
|
+
};
|
|
10458
|
+
|
|
10459
|
+
/**
|
|
10460
|
+
* The local participant's media, split from the roster because it changes on a
|
|
10461
|
+
* different cadence and drives the control bar directly.
|
|
10462
|
+
*/
|
|
10463
|
+
export declare type F0MeetingLocalMedia = {
|
|
10464
|
+
microphone: F0MeetingLocalSource;
|
|
10465
|
+
camera: F0MeetingLocalSource;
|
|
10466
|
+
/** Omit when the host cannot share (mobile web, restricted tenants). */
|
|
10467
|
+
screenShare?: F0MeetingLocalSource;
|
|
10468
|
+
/**
|
|
10469
|
+
* Browsers block autoplay of remote audio until a user gesture. When true,
|
|
10470
|
+
* F0 renders an affordance wired to `unlockAudio`.
|
|
10471
|
+
* factorial → LiveKit `room.canPlaybackAudio === false`, resolved by
|
|
10472
|
+
* `room.startAudio()`.
|
|
10473
|
+
*/
|
|
10474
|
+
audioBlocked?: boolean;
|
|
10475
|
+
unlockAudio?: () => void | Promise<void>;
|
|
10476
|
+
};
|
|
10477
|
+
|
|
10478
|
+
/** State of one local media source. */
|
|
10479
|
+
export declare type F0MeetingLocalSource = {
|
|
10480
|
+
enabled: boolean;
|
|
10481
|
+
/** A toggle is in flight. Renders the pending state and blocks double-clicks. */
|
|
10482
|
+
pending?: boolean;
|
|
10483
|
+
permission?: F0MeetingPermission;
|
|
10484
|
+
/** Devices for the inline picker. Omit to hide the chevron entirely. */
|
|
10485
|
+
devices?: F0MeetingDevice[];
|
|
10486
|
+
selectedDeviceId?: string;
|
|
10487
|
+
selectDevice?: (deviceId: string) => void | Promise<void>;
|
|
10488
|
+
};
|
|
10489
|
+
|
|
10490
|
+
export declare type F0MeetingParticipant = {
|
|
10491
|
+
id: string;
|
|
10492
|
+
/** Display name, already resolved by the host. LiveKit `Participant.name`. */
|
|
10493
|
+
name: string;
|
|
10494
|
+
avatar?: AvatarVariant;
|
|
10495
|
+
isLocal: boolean;
|
|
10496
|
+
/**
|
|
10497
|
+
* Moderator flag — drives moderation affordances. Not a transport concept:
|
|
10498
|
+
* the host derives it from token grants or `participant.metadata`.
|
|
10499
|
+
*/
|
|
10500
|
+
isHost?: boolean;
|
|
10501
|
+
/**
|
|
10502
|
+
* A bot rather than a person (AI notetaker, transcription bot). Renders with
|
|
10503
|
+
* a distinct treatment and never counts toward "N people in the call".
|
|
10504
|
+
*/
|
|
10505
|
+
isAgent?: boolean;
|
|
10506
|
+
/** Joined but has not published anything yet. */
|
|
10507
|
+
isConnecting?: boolean;
|
|
10508
|
+
/**
|
|
10509
|
+
* Whether this person is actually in the room. Absent means `joined`, so a
|
|
10510
|
+
* host that only ever reports real participants needs no change.
|
|
10511
|
+
*
|
|
10512
|
+
* `invited` is someone the call is waiting for: they hold a tile that reads
|
|
10513
|
+
* "Waiting…", publish nothing, and do NOT count toward "N people in the
|
|
10514
|
+
* call". LiveKit does not know them — they come from the host's own list of
|
|
10515
|
+
* attendees, which is why this cannot be derived from the transport.
|
|
10516
|
+
*/
|
|
10517
|
+
presence?: F0MeetingPresence;
|
|
10518
|
+
tracks: F0MeetingTrack[];
|
|
10519
|
+
/**
|
|
10520
|
+
* ISO timestamp the hand was raised, so "who raised first" has an order.
|
|
10521
|
+
* factorial → LiveKit participant attributes or a data-channel message.
|
|
10522
|
+
*/
|
|
10523
|
+
raisedHandAt?: string;
|
|
10524
|
+
/** Free-form host label shown in the tile chip. F0 never parses it. */
|
|
10525
|
+
subtitle?: string;
|
|
10526
|
+
/**
|
|
10527
|
+
* Never crop this person's video: it is letterboxed inside its tile instead
|
|
10528
|
+
* of filling it.
|
|
10529
|
+
*
|
|
10530
|
+
* Tiles take the shape of their cell and crop the sides to fill it, which is
|
|
10531
|
+
* safe for a centred face and NOT safe for someone signing — it takes their
|
|
10532
|
+
* hands with it. Meet exposes the same escape hatch as "Show my full video to
|
|
10533
|
+
* others". The person owns the preference; F0 only honours it.
|
|
10534
|
+
*/
|
|
10535
|
+
preventCrop?: boolean;
|
|
10536
|
+
};
|
|
10537
|
+
|
|
10538
|
+
/**
|
|
10539
|
+
* Media permission as the browser reports it. Modelling it explicitly is what
|
|
10540
|
+
* lets the UI explain a black tile instead of just showing one.
|
|
10541
|
+
*
|
|
10542
|
+
* factorial → the DOMException name from `getUserMedia`: `NotAllowedError` →
|
|
10543
|
+
* "denied", `NotFoundError` → "unavailable", `NotReadableError` → "in-use".
|
|
10544
|
+
*/
|
|
10545
|
+
export declare type F0MeetingPermission = (typeof f0MeetingPermissions)[number];
|
|
10546
|
+
|
|
10547
|
+
export declare const f0MeetingPermissions: readonly ["granted", "prompt", "denied", "unavailable", "in-use"];
|
|
10548
|
+
|
|
10549
|
+
export declare type F0MeetingPresence = (typeof f0MeetingPresences)[number];
|
|
10550
|
+
|
|
10551
|
+
/**
|
|
10552
|
+
* A person in the room. `id` is the transport identity — the SAME string the
|
|
10553
|
+
* transport uses, so F0 never cross-references two id spaces internally. The
|
|
10554
|
+
* domain lookup (identity → employee name/avatar) belongs to the adapter.
|
|
10555
|
+
*
|
|
10556
|
+
* factorial → LiveKit `Participant.identity` (the employee id).
|
|
10557
|
+
*/
|
|
10558
|
+
export declare const f0MeetingPresences: readonly ["invited", "joined"];
|
|
10559
|
+
|
|
10560
|
+
/**
|
|
10561
|
+
* Makes a {@link F0MeetingRuntime} available to the meeting UI. The host owns
|
|
10562
|
+
* the runtime (a mock in stories, a LiveKit adapter in factorial); F0 only
|
|
10563
|
+
* reads it and never imports the transport.
|
|
10564
|
+
*/
|
|
10565
|
+
export declare const F0MeetingProvider: ({ runtime, children, }: {
|
|
10566
|
+
/**
|
|
10567
|
+
* `null` while there is no call. The provider still renders, so `children`
|
|
10568
|
+
* keep their position in the tree — see {@link F0Meeting}. Every hook below
|
|
10569
|
+
* throws on a null context, which keeps the contract intact: you may only read
|
|
10570
|
+
* a meeting from inside one.
|
|
10571
|
+
*/
|
|
10572
|
+
runtime: F0MeetingRuntime | null;
|
|
10573
|
+
children: ReactNode;
|
|
10574
|
+
}) => ReactNode;
|
|
10575
|
+
|
|
10576
|
+
export declare type F0MeetingProviderProps = {
|
|
10577
|
+
/** `null` when there is no active meeting: nothing mounts. */
|
|
10578
|
+
runtime: F0MeetingRuntime | null;
|
|
10579
|
+
/** Host actions, merged by id with the synthesized core ones. */
|
|
10580
|
+
actions?: F0MeetingActionsProp;
|
|
10581
|
+
/** Explicit left-to-right order by action id. Unlisted ids keep their slot. */
|
|
10582
|
+
actionOrder?: string[];
|
|
10583
|
+
/** Surface mode when a meeting first appears. */
|
|
10584
|
+
defaultMode?: F0MeetingSurfaceDestination;
|
|
10585
|
+
/**
|
|
10586
|
+
* Whether the browser may move the call into its picture-in-picture window
|
|
10587
|
+
* when the user leaves the tab. On by default. There is no button for it,
|
|
10588
|
+
* and nothing happens on a browser without either PiP API.
|
|
10589
|
+
*/
|
|
10590
|
+
pictureInPicture?: boolean;
|
|
10591
|
+
/**
|
|
10592
|
+
* The tabs of the in-call side panel (chat, transcript, notes). F0 renders
|
|
10593
|
+
* the bar and owns whether the panel is open, because the button that opens
|
|
10594
|
+
* it lives in F0's own control bar — a bare `ReactNode` could not supply the
|
|
10595
|
+
* tab labels or the unread badge that button needs.
|
|
10596
|
+
*/
|
|
10597
|
+
sidePanel?: F0MeetingSidePanel;
|
|
10598
|
+
/** Host content rendered in the window header, before the mode controls. */
|
|
10599
|
+
headerContent?: React.ReactNode;
|
|
10600
|
+
/** Host content rendered above the whole room (banners, upsells). */
|
|
10601
|
+
overlay?: React.ReactNode;
|
|
10602
|
+
children?: React.ReactNode;
|
|
10603
|
+
};
|
|
10604
|
+
|
|
10605
|
+
export declare type F0MeetingReaction = {
|
|
10606
|
+
id: string;
|
|
10607
|
+
participantId: string;
|
|
10608
|
+
emoji: string;
|
|
10609
|
+
at: string;
|
|
10610
|
+
};
|
|
10611
|
+
|
|
10612
|
+
export declare type F0MeetingRecording = {
|
|
10613
|
+
active: boolean;
|
|
10614
|
+
startedBy?: F0MeetingParticipant;
|
|
10615
|
+
startedAt?: string;
|
|
10616
|
+
/** Legal copy is host-provided and already localized. */
|
|
10617
|
+
consentNotice?: string;
|
|
10618
|
+
};
|
|
10619
|
+
|
|
10620
|
+
/**
|
|
10621
|
+
* The room itself: grid, controls and state chrome. It knows nothing about the
|
|
10622
|
+
* window that hosts it — the surface owns position, size and mode, exactly as
|
|
10623
|
+
* `F0Chat` takes its window controls as callbacks.
|
|
10624
|
+
*/
|
|
10625
|
+
export declare const F0MeetingRoom: ({ actions, actionOrder, sidePanel, overlay, }: F0MeetingRoomProps) => JSX_2.Element;
|
|
10626
|
+
|
|
10627
|
+
export declare type F0MeetingRoomInfo = {
|
|
10628
|
+
id: string;
|
|
10629
|
+
/** Shown in the header and in the minimized pill. */
|
|
10630
|
+
title: string;
|
|
10631
|
+
avatar?: AvatarVariant;
|
|
10632
|
+
/**
|
|
10633
|
+
* ISO timestamp the call started — drives the elapsed timer. LiveKit exposes
|
|
10634
|
+
* no room start time, so the adapter uses its own backend value and falls
|
|
10635
|
+
* back to local join time.
|
|
10636
|
+
*/
|
|
10637
|
+
startedAt?: string;
|
|
10638
|
+
/** Where this meeting came from, so the header can link back to it. */
|
|
10639
|
+
origin?: {
|
|
10640
|
+
label: string;
|
|
10641
|
+
onNavigate: () => void;
|
|
10642
|
+
};
|
|
10643
|
+
};
|
|
10644
|
+
|
|
10645
|
+
export declare type F0MeetingRoomProps = {
|
|
10646
|
+
actions?: F0MeetingActionsProp;
|
|
10647
|
+
actionOrder?: string[];
|
|
10648
|
+
sidePanel?: F0MeetingSidePanel;
|
|
10649
|
+
overlay?: React.ReactNode;
|
|
10650
|
+
};
|
|
10651
|
+
|
|
10652
|
+
/** The roster slice: changes on join/leave/publish, not on every packet. */
|
|
10653
|
+
export declare type F0MeetingRoster = {
|
|
10654
|
+
room: F0MeetingRoomInfo;
|
|
10655
|
+
status: F0MeetingStatus;
|
|
10656
|
+
participants: F0MeetingParticipant[];
|
|
10657
|
+
localMedia: F0MeetingLocalMedia;
|
|
10658
|
+
recording?: F0MeetingRecording;
|
|
10659
|
+
signals?: F0MeetingSignalStore;
|
|
10660
|
+
};
|
|
10661
|
+
|
|
10662
|
+
/**
|
|
10663
|
+
* The data and actions a host provides to drive the meeting UI. F0 is headless:
|
|
10664
|
+
* it never touches the transport. A mock runtime powers Storybook; factorial
|
|
10665
|
+
* implements this against LiveKit.
|
|
10666
|
+
*
|
|
10667
|
+
* As in {@link F0ChatRuntime}, optional callbacks are CAPABILITY DETECTION:
|
|
10668
|
+
* omitting `setScreenShareEnabled` removes the screen-share button entirely.
|
|
10669
|
+
*/
|
|
10670
|
+
export declare type F0MeetingRuntime = {
|
|
10671
|
+
room: F0MeetingRoomInfo;
|
|
10672
|
+
status: F0MeetingStatus;
|
|
10673
|
+
/** Only meaningful with `status: "disconnected"`. */
|
|
10674
|
+
disconnectReason?: F0MeetingDisconnectReason;
|
|
10675
|
+
/** Human-readable failure, already localized. `status: "error"` only. */
|
|
10676
|
+
errorMessage?: string;
|
|
10677
|
+
localParticipantId: string;
|
|
10678
|
+
/**
|
|
10679
|
+
* Everyone in the room INCLUDING the local participant, in a stable order the
|
|
10680
|
+
* host controls (join order). F0 owns speaker promotion and pagination on top
|
|
10681
|
+
* of this — a host that reorders on every speaker change makes the grid churn.
|
|
10682
|
+
*/
|
|
10683
|
+
participants: F0MeetingParticipant[];
|
|
10684
|
+
localMedia: F0MeetingLocalMedia;
|
|
10685
|
+
/**
|
|
10686
|
+
* Volatile per-participant signals. Omit and F0 degrades gracefully to muted
|
|
10687
|
+
* flags with no waveform and no quality bars, which is what tests and simple
|
|
10688
|
+
* hosts want.
|
|
10689
|
+
*/
|
|
10690
|
+
signals?: F0MeetingSignalStore;
|
|
10691
|
+
/**
|
|
10692
|
+
* Leave the room. F0 never calls this implicitly — not on unmount, not on
|
|
10693
|
+
* Escape, not on navigation. Hanging up must be an explicit user act.
|
|
10694
|
+
*/
|
|
10695
|
+
leave: () => void | Promise<void>;
|
|
10696
|
+
setMicrophoneEnabled: (enabled: boolean) => void | Promise<void>;
|
|
10697
|
+
setCameraEnabled: (enabled: boolean) => void | Promise<void>;
|
|
10698
|
+
setScreenShareEnabled?: (enabled: boolean) => void | Promise<void>;
|
|
10699
|
+
startRecording?: () => void | Promise<void>;
|
|
10700
|
+
stopRecording?: () => void | Promise<void>;
|
|
10701
|
+
recording?: F0MeetingRecording;
|
|
10702
|
+
setHandRaised?: (raised: boolean) => void | Promise<void>;
|
|
10703
|
+
sendReaction?: (emoji: string) => void | Promise<void>;
|
|
10704
|
+
/** Transient reactions to animate; the host prunes them after a few seconds. */
|
|
10705
|
+
reactions?: F0MeetingReaction[];
|
|
10706
|
+
muteParticipant?: (participantId: string) => void | Promise<void>;
|
|
10707
|
+
removeParticipant?: (participantId: string) => void | Promise<void>;
|
|
10708
|
+
/**
|
|
10709
|
+
* Live transcription. Omit and the panel has no Transcript tab at all —
|
|
10710
|
+
* the usual capability-by-presence rule.
|
|
10711
|
+
*/
|
|
10712
|
+
transcript?: F0MeetingTranscriptSegment[];
|
|
10713
|
+
/** Shared notes for the room. Present without `setNotes` means read-only. */
|
|
10714
|
+
notes?: string;
|
|
10715
|
+
setNotes?: (value: string) => void;
|
|
10716
|
+
/** Retry after a failed connect — wires the Rejoin action. */
|
|
10717
|
+
reconnect?: () => void | Promise<void>;
|
|
10718
|
+
capabilities?: F0MeetingCapabilities;
|
|
10719
|
+
};
|
|
10720
|
+
|
|
10721
|
+
export declare type F0MeetingSidePanel = {
|
|
10722
|
+
tabs: F0MeetingSidePanelTab[];
|
|
10723
|
+
defaultTabId?: string;
|
|
10724
|
+
};
|
|
10725
|
+
|
|
10726
|
+
/**
|
|
10727
|
+
* A tab in the room's side panel. F0 owns the bar, the selection and the close
|
|
10728
|
+
* button; the host owns what is inside each tab.
|
|
10729
|
+
*/
|
|
10730
|
+
export declare type F0MeetingSidePanelTab = {
|
|
10731
|
+
id: string;
|
|
10732
|
+
label: string;
|
|
10733
|
+
content: React.ReactNode;
|
|
10734
|
+
/** Unread count on the tab and on the control-bar button that opens it. */
|
|
10735
|
+
badge?: number;
|
|
10736
|
+
};
|
|
10737
|
+
|
|
10738
|
+
/**
|
|
10739
|
+
* Per-participant volatile state. Read through `useSyncExternalStore`, never
|
|
10740
|
+
* through context: with a dozen participants LiveKit emits these at 10–20 Hz,
|
|
10741
|
+
* which would re-render the whole tree a hundred times a second.
|
|
10742
|
+
*/
|
|
10743
|
+
export declare type F0MeetingSignal = {
|
|
10744
|
+
/** 0..1, smoothed by the host. LiveKit `Participant.audioLevel`. */
|
|
10745
|
+
audioLevel: number;
|
|
10746
|
+
isSpeaking: boolean;
|
|
10747
|
+
quality: F0MeetingConnectionQuality;
|
|
10748
|
+
};
|
|
10749
|
+
|
|
10750
|
+
/**
|
|
10751
|
+
* Minimal external-store protocol. F0 exports `createMeetingSignalStore` so
|
|
10752
|
+
* hosts never implement subscribe/getSnapshot themselves — the adapter just
|
|
10753
|
+
* calls the setters from its transport listeners.
|
|
10754
|
+
*/
|
|
10755
|
+
export declare type F0MeetingSignalStore = {
|
|
10756
|
+
subscribe: (participantId: string, listener: () => void) => () => void;
|
|
10757
|
+
/**
|
|
10758
|
+
* MUST return the same object identity while nothing changed, or
|
|
10759
|
+
* `useSyncExternalStore` loops forever.
|
|
10760
|
+
*/
|
|
10761
|
+
getSnapshot: (participantId: string) => F0MeetingSignal;
|
|
10762
|
+
subscribeSpeakers: (listener: () => void) => () => void;
|
|
10763
|
+
/** Identity changes only when the SET changes, so the grid doesn't churn. */
|
|
10764
|
+
getSpeakers: () => readonly string[];
|
|
10765
|
+
};
|
|
10766
|
+
|
|
10767
|
+
/**
|
|
10768
|
+
* Reserves space for the meeting on a dedicated page.
|
|
10769
|
+
*
|
|
10770
|
+
* It renders nothing: it is an empty box that publishes its viewport rect, and
|
|
10771
|
+
* the window — which stays in its portal — animates to that rect. Teleporting
|
|
10772
|
+
* by measurement instead of reparenting is what keeps the `<video>` elements
|
|
10773
|
+
* mounted across navigation, and it makes the fullscreen ↔ inline ↔ floating
|
|
10774
|
+
* transition a single animation of x/y/width/height.
|
|
10775
|
+
*/
|
|
10776
|
+
export declare const F0MeetingSlot: () => JSX_2.Element;
|
|
10777
|
+
|
|
10778
|
+
/**
|
|
10779
|
+
* The slow-moving slice, behind a SEPARATE context with a stable value. LiveKit
|
|
10780
|
+
* emits audio levels, speaking changes and quality updates at 10–20 Hz per
|
|
10781
|
+
* participant; anything mounted per-tile that read the full runtime would
|
|
10782
|
+
* re-render on every one of them, defeating the tile memoization.
|
|
10783
|
+
*
|
|
10784
|
+
* The action callbacks are identity-stable delegates into the latest runtime.
|
|
10785
|
+
*/
|
|
10786
|
+
export declare type F0MeetingStable = {
|
|
10787
|
+
roomId: string;
|
|
10788
|
+
localParticipantId: string;
|
|
10789
|
+
capabilities?: F0MeetingCapabilities;
|
|
10790
|
+
/**
|
|
10791
|
+
* Presence flags, not the callbacks themselves: optional runtime actions gate
|
|
10792
|
+
* UI affordances by PRESENCE, so the memo tracks presence, not identity.
|
|
10793
|
+
*/
|
|
10794
|
+
hasScreenShare: boolean;
|
|
10795
|
+
hasRecording: boolean;
|
|
10796
|
+
hasReactions: boolean;
|
|
10797
|
+
hasRaiseHand: boolean;
|
|
10798
|
+
hasModeration: boolean;
|
|
10799
|
+
hasReconnect: boolean;
|
|
10800
|
+
setMicrophoneEnabled: (enabled: boolean) => void;
|
|
10801
|
+
setCameraEnabled: (enabled: boolean) => void;
|
|
10802
|
+
setScreenShareEnabled: (enabled: boolean) => void;
|
|
10803
|
+
setHandRaised: (raised: boolean) => void;
|
|
10804
|
+
sendReaction: (emoji: string) => void;
|
|
10805
|
+
muteParticipant: (participantId: string) => void;
|
|
10806
|
+
removeParticipant: (participantId: string) => void;
|
|
10807
|
+
reconnect: () => void;
|
|
10808
|
+
leave: () => void;
|
|
10809
|
+
};
|
|
10810
|
+
|
|
10811
|
+
/**
|
|
10812
|
+
* Room lifecycle. `reconnecting` shows a non-blocking banner and FREEZES the
|
|
10813
|
+
* last video frame instead of clearing tiles — clearing on a two-second ICE
|
|
10814
|
+
* restart is the worst thing a call UI can do.
|
|
10815
|
+
*
|
|
10816
|
+
* factorial → LiveKit `Room.state` plus the `Disconnected` event's reason.
|
|
10817
|
+
*/
|
|
10818
|
+
export declare type F0MeetingStatus = (typeof f0MeetingStatuses)[number];
|
|
10819
|
+
|
|
10820
|
+
export declare const f0MeetingStatuses: readonly ["idle", "connecting", "connected", "reconnecting", "disconnected", "error"];
|
|
10821
|
+
|
|
10822
|
+
/**
|
|
10823
|
+
* Mounts the room into a portal on `document.body`, once, for the whole life of
|
|
10824
|
+
* the meeting — for every mode EXCEPT `panel` and `pip`.
|
|
10825
|
+
*
|
|
10826
|
+
* It lives outside the application frame on purpose. The frame's root is
|
|
10827
|
+
* `overflow-hidden` and contains transformed elements, and a transformed
|
|
10828
|
+
* ancestor breaks `position: fixed` for everything inside it — which is exactly
|
|
10829
|
+
* what a free-floating window needs. Portalling also keeps the frame's own
|
|
10830
|
+
* z-index map untouched: the surface only claims the 40–49 band at body level,
|
|
10831
|
+
* deliberately below Radix dialogs so a modal can still cover the call.
|
|
10832
|
+
*
|
|
10833
|
+
* `panel` is the one mode with no window at all: there the room is the side
|
|
10834
|
+
* panel's content (see `MeetingPanelContent`), so it needs no chrome of its own
|
|
10835
|
+
* and no rect — the panel supplies both. `pip` has a window, but it is the
|
|
10836
|
+
* browser's: the room portals into that window's document (see `PipFrame`).
|
|
10837
|
+
*
|
|
10838
|
+
* The body-level portal element stays mounted regardless, because two things
|
|
10839
|
+
* must never leave the main document: the live region announcing the call, and
|
|
10840
|
+
* the `<audio>` elements — a media element moved to another document stops
|
|
10841
|
+
* playing, and remounting one in the middle of a sentence is a dropped word.
|
|
10842
|
+
*/
|
|
10843
|
+
export declare const F0MeetingSurface: () => JSX_2.Element | null;
|
|
10844
|
+
|
|
10845
|
+
export declare type F0MeetingSurfaceDestination = (typeof f0MeetingSurfaceDestinations)[number];
|
|
10846
|
+
|
|
10847
|
+
/** The places a call can be sent to — by the user, or by `defaultMode`. */
|
|
10848
|
+
export declare const f0MeetingSurfaceDestinations: readonly ["fullscreen", "panel", "floating", "minimized", "inline"];
|
|
10849
|
+
|
|
10850
|
+
export declare type F0MeetingSurfaceMode = (typeof f0MeetingSurfaceModes)[number];
|
|
10851
|
+
|
|
10852
|
+
/**
|
|
10853
|
+
* Everything the surface can render as. `pip` is the one mode nobody chooses:
|
|
10854
|
+
* the browser moves the call into its picture-in-picture window when the tab
|
|
10855
|
+
* is left, whatever mode it was in, and closing that window returns to it.
|
|
10856
|
+
* Never persisted, never a `defaultMode`, never a button.
|
|
10857
|
+
*/
|
|
10858
|
+
export declare const f0MeetingSurfaceModes: readonly ["fullscreen", "panel", "floating", "minimized", "inline", "pip"];
|
|
10859
|
+
|
|
10860
|
+
/**
|
|
10861
|
+
* A rendered cell. One per published camera (with a placeholder when the camera
|
|
10862
|
+
* is off) plus one per screen share, so a participant who is sharing occupies
|
|
10863
|
+
* two tiles — the same behaviour as every other call product.
|
|
10864
|
+
*/
|
|
10865
|
+
export declare type F0MeetingTile = {
|
|
10866
|
+
/** `${participantId}:${kind}` — stable across re-solves. */
|
|
10867
|
+
key: string;
|
|
10868
|
+
participant: F0MeetingParticipant;
|
|
10869
|
+
kind: Extract<F0MeetingTrackKind, "camera" | "screenShare">;
|
|
10870
|
+
/** Undefined when nothing is published: the tile renders the avatar. */
|
|
10871
|
+
track?: F0MeetingTrack;
|
|
10872
|
+
};
|
|
10873
|
+
|
|
10874
|
+
export declare type F0MeetingTrack = {
|
|
10875
|
+
/** Stable publication id. factorial → LiveKit `TrackPublication.trackSid`. */
|
|
10876
|
+
id: string;
|
|
10877
|
+
kind: F0MeetingTrackKind;
|
|
10878
|
+
/**
|
|
10879
|
+
* Identity key for the binding. F0 re-runs attach ONLY when this changes —
|
|
10880
|
+
* never on `binding`'s identity, which hosts rebuild on every transport
|
|
10881
|
+
* event. Republishing the same source (camera restart, device switch) MUST
|
|
10882
|
+
* change it. factorial → `${trackSid}:${track.mediaStreamID}`.
|
|
10883
|
+
*/
|
|
10884
|
+
bindingKey: string;
|
|
10885
|
+
binding?: F0MeetingBinding;
|
|
10886
|
+
/** Muted at the source. factorial → LiveKit `TrackPublication.isMuted`. */
|
|
10887
|
+
muted: boolean;
|
|
10888
|
+
/** Subscribed and flowing. factorial → `isSubscribed && !isMuted`. */
|
|
10889
|
+
live: boolean;
|
|
10890
|
+
/**
|
|
10891
|
+
* Intrinsic dimensions, when known — lets the tile letterbox before the
|
|
10892
|
+
* first frame lands. Screen shares are rarely 16:9, so forcing them into it
|
|
10893
|
+
* is visible. factorial → LiveKit `TrackPublication.dimensions`.
|
|
10894
|
+
*/
|
|
10895
|
+
width?: number;
|
|
10896
|
+
height?: number;
|
|
10897
|
+
};
|
|
10898
|
+
|
|
10899
|
+
export declare type F0MeetingTrackKind = (typeof f0MeetingTrackKinds)[number];
|
|
10900
|
+
|
|
10901
|
+
export declare const f0MeetingTrackKinds: readonly ["camera", "microphone", "screenShare", "screenShareAudio"];
|
|
10902
|
+
|
|
10903
|
+
/**
|
|
10904
|
+
* One line of live transcription.
|
|
10905
|
+
*
|
|
10906
|
+
* Modelled on LiveKit's own shape so the adapter is a rename: segments arrive
|
|
10907
|
+
* on the `lk.transcription` text-stream topic, and a non-final segment is
|
|
10908
|
+
* REPLACED by its final version under the same id rather than appended.
|
|
10909
|
+
* (`RoomEvent.TranscriptionReceived` is deprecated; do not wire it.)
|
|
10910
|
+
*/
|
|
10911
|
+
export declare type F0MeetingTranscriptSegment = {
|
|
10912
|
+
/** LiveKit `lk.segment_id` — shared between the interim and final versions. */
|
|
10913
|
+
id: string;
|
|
10914
|
+
participantId: string;
|
|
10915
|
+
text: string;
|
|
10916
|
+
at: string;
|
|
10917
|
+
/** LiveKit `lk.transcription_final`. Interim lines render as provisional. */
|
|
10918
|
+
isFinal: boolean;
|
|
10919
|
+
};
|
|
10920
|
+
|
|
10100
10921
|
declare type F0Message = {
|
|
10101
10922
|
id: string;
|
|
10102
10923
|
role: "user" | "assistant" | "system" | "tool";
|
|
@@ -10320,6 +11141,13 @@ export declare type F0ProgressSeriesSize = (typeof f0ProgressSeriesSizes)[number
|
|
|
10320
11141
|
|
|
10321
11142
|
export declare const f0ProgressSeriesSizes: readonly ["sm", "md", "lg"];
|
|
10322
11143
|
|
|
11144
|
+
export declare type F0Rect = {
|
|
11145
|
+
x: number;
|
|
11146
|
+
y: number;
|
|
11147
|
+
width: number;
|
|
11148
|
+
height: number;
|
|
11149
|
+
};
|
|
11150
|
+
|
|
10323
11151
|
/**
|
|
10324
11152
|
* Header for a resource detail page: avatar, title, description, status,
|
|
10325
11153
|
* metadata and its primary, secondary and overflow actions.
|
|
@@ -10913,6 +11741,29 @@ export declare interface F0VersionHistoryProps {
|
|
|
10913
11741
|
activeVersionId?: "current" | (string & {});
|
|
10914
11742
|
}
|
|
10915
11743
|
|
|
11744
|
+
export declare type F0WindowCorner = (typeof f0WindowCorners)[number];
|
|
11745
|
+
|
|
11746
|
+
export declare const f0WindowCorners: readonly ["tl", "tr", "bl", "br"];
|
|
11747
|
+
|
|
11748
|
+
/**
|
|
11749
|
+
* Anchored placement. Storing absolute coordinates is the classic mistake:
|
|
11750
|
+
* shrinking the browser leaves the window off-screen. Anchoring to a corner
|
|
11751
|
+
* keeps it where the user expects across viewport changes.
|
|
11752
|
+
*
|
|
11753
|
+
* It describes the FLOATING window only. `panel` mode stores nothing here: the
|
|
11754
|
+
* room is the side panel's content there, so its width is the panel's and is
|
|
11755
|
+
* persisted by the panel — which is also why docking and undocking returns the
|
|
11756
|
+
* exact floating size the user had chosen.
|
|
11757
|
+
*/
|
|
11758
|
+
export declare type F0WindowPlacement = {
|
|
11759
|
+
corner: F0WindowCorner;
|
|
11760
|
+
/** Distance from the anchored corner, in px, always positive. */
|
|
11761
|
+
dx: number;
|
|
11762
|
+
dy: number;
|
|
11763
|
+
width: number;
|
|
11764
|
+
height: number;
|
|
11765
|
+
};
|
|
11766
|
+
|
|
10916
11767
|
/**
|
|
10917
11768
|
* @deprecated Renamed to `F0SearchInput` to match the F0 input vocabulary
|
|
10918
11769
|
* (any component where the user types in a box has the `Input` suffix and
|
|
@@ -11566,6 +12417,55 @@ declare type GraphVisualizationSettings = {
|
|
|
11566
12417
|
hidden?: string[];
|
|
11567
12418
|
};
|
|
11568
12419
|
|
|
12420
|
+
/** One row of the grid. Rows may hold different counts, so also different widths. */
|
|
12421
|
+
declare type GridRow = {
|
|
12422
|
+
count: number;
|
|
12423
|
+
tileWidth: number;
|
|
12424
|
+
tileHeight: number;
|
|
12425
|
+
};
|
|
12426
|
+
|
|
12427
|
+
export declare type GridSolution = {
|
|
12428
|
+
rows: number;
|
|
12429
|
+
/** Widest row's tile count. */
|
|
12430
|
+
cols: number;
|
|
12431
|
+
/** The NARROWEST row's tile — the worst case, which is what limits are about. */
|
|
12432
|
+
tileWidth: number;
|
|
12433
|
+
tileHeight: number;
|
|
12434
|
+
/** Tiles that fit. `count - visibleCount` go to the overflow chip. */
|
|
12435
|
+
visibleCount: number;
|
|
12436
|
+
rowSpecs: GridRow[];
|
|
12437
|
+
/** Σ tile areas: how much of the container the layout actually covers. */
|
|
12438
|
+
totalArea: number;
|
|
12439
|
+
};
|
|
12440
|
+
|
|
12441
|
+
export declare type GridSolverInput = {
|
|
12442
|
+
count: number;
|
|
12443
|
+
width: number;
|
|
12444
|
+
height: number;
|
|
12445
|
+
gap: number;
|
|
12446
|
+
/**
|
|
12447
|
+
* How far a tile may stray from `preferredAspect` to fill its cell. Inside
|
|
12448
|
+
* this range the tile simply IS the cell, so the grid leaves no dead space.
|
|
12449
|
+
*/
|
|
12450
|
+
minAspect: number;
|
|
12451
|
+
maxAspect: number;
|
|
12452
|
+
/** Only breaks ties between layouts of equal quality. */
|
|
12453
|
+
preferredAspect: number;
|
|
12454
|
+
/** Below this a tile stops being useful; the solver overflows instead. */
|
|
12455
|
+
minTileWidth: number;
|
|
12456
|
+
/**
|
|
12457
|
+
* The same floor for height. Optional, and 0 means "no floor" — a caller with
|
|
12458
|
+
* only a width in mind gets exactly the old behaviour.
|
|
12459
|
+
*/
|
|
12460
|
+
minTileHeight?: number;
|
|
12461
|
+
/**
|
|
12462
|
+
* How much smaller than the best possible worst tile a layout may make its
|
|
12463
|
+
* smallest tile to compete on total coverage. `1` (the default) is pure
|
|
12464
|
+
* maximin; `COVERAGE_TOLERANCE` is what the room uses.
|
|
12465
|
+
*/
|
|
12466
|
+
coverageTolerance?: number;
|
|
12467
|
+
};
|
|
12468
|
+
|
|
11569
12469
|
/**
|
|
11570
12470
|
* Symbol used to identify the groupId in the data
|
|
11571
12471
|
*/
|
|
@@ -12666,6 +13566,19 @@ export declare type lastIntentType = {
|
|
|
12666
13566
|
/** Sentinel for {@link F0ChatRuntime.loadMessageContext} meaning "the live tail". */
|
|
12667
13567
|
export declare const LATEST: "latest";
|
|
12668
13568
|
|
|
13569
|
+
/**
|
|
13570
|
+
* Places the solved tiles. Rows sit in equal-height slots that span the
|
|
13571
|
+
* container, and each row centres its own tiles inside its slot — so a row
|
|
13572
|
+
* that the aspect clamp shrank is centred rather than pinned to a corner.
|
|
13573
|
+
*
|
|
13574
|
+
* Returns absolute rects so the caller can animate x/y/width/height directly —
|
|
13575
|
+
* no `scale`, which is what would warp the video mid-flight.
|
|
13576
|
+
*/
|
|
13577
|
+
export declare const layoutGrid: (solution: GridSolution, box: {
|
|
13578
|
+
width: number;
|
|
13579
|
+
height: number;
|
|
13580
|
+
}, gap: number) => F0Rect[];
|
|
13581
|
+
|
|
12669
13582
|
declare type Level = (typeof levels)[number];
|
|
12670
13583
|
|
|
12671
13584
|
declare const levels: readonly ["info", "warning", "critical", "positive"];
|
|
@@ -12988,8 +13901,15 @@ export declare type MeetingAttendee = {
|
|
|
12988
13901
|
};
|
|
12989
13902
|
|
|
12990
13903
|
export declare interface MeetingJoin {
|
|
12991
|
-
/**
|
|
12992
|
-
|
|
13904
|
+
/**
|
|
13905
|
+
* Called when the Join button is pressed.
|
|
13906
|
+
*
|
|
13907
|
+
* Return the promise and the button shows a spinner until it settles, which
|
|
13908
|
+
* is what joining actually needs: a room has to be asked for before there is
|
|
13909
|
+
* anything to walk into, and without this the card sits there looking as if
|
|
13910
|
+
* the press did nothing.
|
|
13911
|
+
*/
|
|
13912
|
+
onJoin?: () => void | Promise<unknown>;
|
|
12993
13913
|
/** Navigates to the meeting room instead of handling the click. */
|
|
12994
13914
|
href?: string;
|
|
12995
13915
|
/**
|
|
@@ -13006,6 +13926,93 @@ export declare interface MeetingJoin {
|
|
|
13006
13926
|
label?: string;
|
|
13007
13927
|
}
|
|
13008
13928
|
|
|
13929
|
+
/**
|
|
13930
|
+
* Shared notes for the room.
|
|
13931
|
+
*
|
|
13932
|
+
* Uncontrolled-looking but fully controlled: the value comes from the host, so
|
|
13933
|
+
* whatever it syncs the notes through — a data channel, a document, a poll —
|
|
13934
|
+
* arrives here as a re-render rather than as a second source of truth.
|
|
13935
|
+
*/
|
|
13936
|
+
export declare const MeetingNotes: ({ value, onChange }: MeetingNotesProps) => JSX_2.Element;
|
|
13937
|
+
|
|
13938
|
+
declare type MeetingNotesProps = {
|
|
13939
|
+
value: string;
|
|
13940
|
+
/** Absent means read-only: the notes exist but this person cannot edit them. */
|
|
13941
|
+
onChange?: (value: string) => void;
|
|
13942
|
+
};
|
|
13943
|
+
|
|
13944
|
+
/**
|
|
13945
|
+
* The room AS THE SIDE PANEL'S CONTENT — not a window that covers it.
|
|
13946
|
+
*
|
|
13947
|
+
* Everything `FloatingWindow` would draw is deliberately absent: the card, the
|
|
13948
|
+
* border, the shadow, the rect, the drag handles and the resize seam all belong
|
|
13949
|
+
* to the panel, which already has one of each. What is left is the header row
|
|
13950
|
+
* and the room, filling whatever space the panel gives them.
|
|
13951
|
+
*
|
|
13952
|
+
* It takes no props ON PURPOSE. The element is handed to `present()` and stored
|
|
13953
|
+
* in the panel's state, so it must be referentially stable — a fresh element on
|
|
13954
|
+
* every render would re-present in a loop. Everything the chrome needs comes
|
|
13955
|
+
* from {@link useMeetingChrome} instead.
|
|
13956
|
+
*
|
|
13957
|
+
* ## Why it renders nothing when there is no call
|
|
13958
|
+
*
|
|
13959
|
+
* That same `present()` is what makes this OUTLIVE the call. The element lives
|
|
13960
|
+
* in the side panel's state, in the host's tree, so it is not removed with the
|
|
13961
|
+
* meeting surface — it is taken out by `MeetingPanelPresenter`'s effect cleanup,
|
|
13962
|
+
* a whole commit after the runtime became null. There is therefore exactly one
|
|
13963
|
+
* render where this is on screen with no call behind it, and reading the meeting
|
|
13964
|
+
* there used to throw and take the page down on hanging up.
|
|
13965
|
+
*/
|
|
13966
|
+
export declare const MeetingPanelContent: () => ReactNode;
|
|
13967
|
+
|
|
13968
|
+
/**
|
|
13969
|
+
* The call's own chat, for the room's side panel.
|
|
13970
|
+
*
|
|
13971
|
+
* Deliberately plainer than `F0Chat`: this transport has no reactions, no
|
|
13972
|
+
* threads, no read receipts and no history — in production it is LiveKit's data
|
|
13973
|
+
* channel, which delivers a string and forgets it. Rendering it with the full
|
|
13974
|
+
* conversation surface would promise all of those.
|
|
13975
|
+
*/
|
|
13976
|
+
export declare const MeetingRoomChat: ({ messages, onSend }: MeetingRoomChatProps) => JSX_2.Element;
|
|
13977
|
+
|
|
13978
|
+
declare type MeetingRoomChatMessage = {
|
|
13979
|
+
id: string;
|
|
13980
|
+
participantId: string;
|
|
13981
|
+
text: string;
|
|
13982
|
+
at: string;
|
|
13983
|
+
};
|
|
13984
|
+
|
|
13985
|
+
declare type MeetingRoomChatProps = {
|
|
13986
|
+
messages: MeetingRoomChatMessage[];
|
|
13987
|
+
onSend: (text: string) => void;
|
|
13988
|
+
};
|
|
13989
|
+
|
|
13990
|
+
/**
|
|
13991
|
+
* The in-call panel: chat, transcript and notes beside the grid.
|
|
13992
|
+
*
|
|
13993
|
+
* F0 owns the bar, the selection and the close button because the control that
|
|
13994
|
+
* opens the panel lives in F0's own action bar and needs the tab labels and
|
|
13995
|
+
* unread counts. What goes inside each tab is entirely the host's.
|
|
13996
|
+
*
|
|
13997
|
+
* Only one tab is mounted at a time. That is deliberate for the chat tab in
|
|
13998
|
+
* particular: its transcript is virtualized, and measuring rows inside a
|
|
13999
|
+
* display:none subtree yields zero heights that the list then has to correct
|
|
14000
|
+
* on reveal.
|
|
14001
|
+
*/
|
|
14002
|
+
export declare const MeetingSidePanel: ({ panel }: MeetingSidePanelProps) => JSX_2.Element | null;
|
|
14003
|
+
|
|
14004
|
+
declare type MeetingSidePanelProps = {
|
|
14005
|
+
panel: F0MeetingSidePanel;
|
|
14006
|
+
};
|
|
14007
|
+
|
|
14008
|
+
export declare type MeetingSignalStore = F0MeetingSignalStore & {
|
|
14009
|
+
setAudioLevel: (participantId: string, level: number) => void;
|
|
14010
|
+
setSpeaking: (participantIds: readonly string[]) => void;
|
|
14011
|
+
setQuality: (participantId: string, quality: F0MeetingConnectionQuality) => void;
|
|
14012
|
+
remove: (participantId: string) => void;
|
|
14013
|
+
reset: () => void;
|
|
14014
|
+
};
|
|
14015
|
+
|
|
13009
14016
|
export declare type MeetingState = (typeof meetingStates)[number];
|
|
13010
14017
|
|
|
13011
14018
|
/**
|
|
@@ -13015,7 +14022,102 @@ export declare type MeetingState = (typeof meetingStates)[number];
|
|
|
13015
14022
|
* the elapsed label, whether Join is actionable) is computed from `startsAt` and
|
|
13016
14023
|
* `now`.
|
|
13017
14024
|
*/
|
|
13018
|
-
export declare const meetingStates: readonly ["scheduled", "inProgress", "summarizing", "finished", "cancelled"];
|
|
14025
|
+
export declare const meetingStates: readonly ["ringing", "scheduled", "inProgress", "summarizing", "finished", "missed", "cancelled"];
|
|
14026
|
+
|
|
14027
|
+
declare type MeetingSurfaceContextValue = {
|
|
14028
|
+
/** What the user chose. Never mutated by the environment. */
|
|
14029
|
+
mode: F0MeetingSurfaceDestination;
|
|
14030
|
+
/**
|
|
14031
|
+
* What actually renders. A small viewport or an unmounted inline slot derives
|
|
14032
|
+
* a different mode without destroying the user's preference; so does an open
|
|
14033
|
+
* picture-in-picture window, which is `pip` for as long as it is open.
|
|
14034
|
+
*/
|
|
14035
|
+
effectiveMode: F0MeetingSurfaceMode;
|
|
14036
|
+
setMode: (mode: F0MeetingSurfaceDestination) => void;
|
|
14037
|
+
/** Absolute rect the window animates to, in viewport coordinates. */
|
|
14038
|
+
rect: F0Rect;
|
|
14039
|
+
isDragging: boolean;
|
|
14040
|
+
setIsDragging: (dragging: boolean) => void;
|
|
14041
|
+
/** Commit an absolute rect after a drag (re-anchors and snaps). */
|
|
14042
|
+
settleRect: (rect: F0Rect) => void;
|
|
14043
|
+
/** Commit a resize, keeping the current anchor. */
|
|
14044
|
+
resizeRect: (rect: F0Rect) => void;
|
|
14045
|
+
/** True below the md breakpoint: no dragging, pill instead of window. */
|
|
14046
|
+
isCompactViewport: boolean;
|
|
14047
|
+
/**
|
|
14048
|
+
* The frame's content area. `panel` mode does NOT use it — there the room is
|
|
14049
|
+
* the side panel's content and the panel places itself. It is what a window
|
|
14050
|
+
* sizes itself against when it has to sit BESIDE the panel (see
|
|
14051
|
+
* `fitToContent`), and the viewport when no frame published one.
|
|
14052
|
+
*/
|
|
14053
|
+
panelArea: F0Rect;
|
|
14054
|
+
/**
|
|
14055
|
+
* Whether there is a side panel for the call to be the content of.
|
|
14056
|
+
*
|
|
14057
|
+
* Registered by the application frame, the same way `F0MeetingSlot`
|
|
14058
|
+
* registers a rect for `inline`. A call rendered on its own — a story, a
|
|
14059
|
+
* test, a host with no frame — has nowhere to dock, so `panel` derives to
|
|
14060
|
+
* `floating` and the switch stops offering it.
|
|
14061
|
+
*/
|
|
14062
|
+
hasPanelSlot: boolean;
|
|
14063
|
+
setPanelSlot: (available: boolean) => void;
|
|
14064
|
+
/** Registered by `F0MeetingSlot` so `inline` knows where to fly to. */
|
|
14065
|
+
setInlineRect: (rect: F0Rect | null) => void;
|
|
14066
|
+
/**
|
|
14067
|
+
* The application frame's content region, published by the frame itself. The
|
|
14068
|
+
* side panel lives inside it — between the navigation and the content —
|
|
14069
|
+
* rather than on top of the whole viewport.
|
|
14070
|
+
*/
|
|
14071
|
+
setFrameRect: (rect: F0Rect | null) => void;
|
|
14072
|
+
/** What the user asked the spotlight to do, if anything. */
|
|
14073
|
+
focusIntent: F0MeetingFocusIntent;
|
|
14074
|
+
setFocusIntent: (intent: F0MeetingFocusIntent) => void;
|
|
14075
|
+
/** Whether the in-call side panel is open, and on which tab. */
|
|
14076
|
+
isSidePanelOpen: boolean;
|
|
14077
|
+
setSidePanelOpen: (open: boolean) => void;
|
|
14078
|
+
activeTabId: string | null;
|
|
14079
|
+
setActiveTabId: (id: string) => void;
|
|
14080
|
+
announce: (message: string) => void;
|
|
14081
|
+
liveMessage: string;
|
|
14082
|
+
/** What the browser offers for picture-in-picture, after the host's opt-out. */
|
|
14083
|
+
pipSupport: PipSupport;
|
|
14084
|
+
/** The Document PiP window, while the room renders inside it. */
|
|
14085
|
+
pipWindow: Window | null;
|
|
14086
|
+
/**
|
|
14087
|
+
* Move the call into the browser's picture-in-picture. Deliberately not a
|
|
14088
|
+
* destination of `setMode`: the only caller is the browser itself, from the
|
|
14089
|
+
* Media Session `enterpictureinpicture` action when the tab is left — so the
|
|
14090
|
+
* call follows you out of the tab the way Meet's does, and never by a button.
|
|
14091
|
+
*/
|
|
14092
|
+
enterPictureInPicture: () => void;
|
|
14093
|
+
exitPictureInPicture: () => void;
|
|
14094
|
+
/**
|
|
14095
|
+
* Every live `<video>` by tile key, kept by `TileVideo`, so video PiP has an
|
|
14096
|
+
* element to hand to the browser.
|
|
14097
|
+
*/
|
|
14098
|
+
registerVideo: (key: string, element: HTMLVideoElement | null) => void;
|
|
14099
|
+
};
|
|
14100
|
+
|
|
14101
|
+
export declare const MeetingSurfaceProvider: ({ defaultMode, roomId, pictureInPicture, children, }: {
|
|
14102
|
+
defaultMode?: F0MeetingSurfaceDestination;
|
|
14103
|
+
/** Scopes the remembered mode. A different meeting starts at `defaultMode`. */
|
|
14104
|
+
roomId?: string;
|
|
14105
|
+
pictureInPicture?: boolean;
|
|
14106
|
+
children: ReactNode;
|
|
14107
|
+
}) => ReactNode;
|
|
14108
|
+
|
|
14109
|
+
/**
|
|
14110
|
+
* Live transcription, newest at the bottom.
|
|
14111
|
+
*
|
|
14112
|
+
* Interim segments render at reduced emphasis and are REPLACED by their final
|
|
14113
|
+
* version under the same id — appending both is what turns a transcript into
|
|
14114
|
+
* the same sentence three times, each a word longer.
|
|
14115
|
+
*/
|
|
14116
|
+
export declare const MeetingTranscript: ({ segments }: MeetingTranscriptProps) => JSX_2.Element;
|
|
14117
|
+
|
|
14118
|
+
declare type MeetingTranscriptProps = {
|
|
14119
|
+
segments: F0MeetingTranscriptSegment[];
|
|
14120
|
+
};
|
|
13019
14121
|
|
|
13020
14122
|
export declare type MentionedUser = {
|
|
13021
14123
|
id: string | number;
|
|
@@ -13345,6 +14447,9 @@ export declare type NavigationTarget = {
|
|
|
13345
14447
|
|
|
13346
14448
|
declare type NavTarget = HTMLAttributeAnchorTarget;
|
|
13347
14449
|
|
|
14450
|
+
/** The quadrant the rect's centre falls into. */
|
|
14451
|
+
export declare const nearestCorner: (rect: F0Rect, viewport: Viewport) => F0WindowCorner;
|
|
14452
|
+
|
|
13348
14453
|
/**
|
|
13349
14454
|
* Utility type to extract all possible paths from nested object.
|
|
13350
14455
|
* Generates hyphenated paths from nested object structure
|
|
@@ -14429,7 +15534,13 @@ declare interface PieComputation {
|
|
|
14429
15534
|
limit?: number;
|
|
14430
15535
|
}
|
|
14431
15536
|
|
|
15537
|
+
declare type PipSupport = "document" | "video" | "none";
|
|
15538
|
+
|
|
15539
|
+
/** Re-expresses an absolute rect against a given corner. */
|
|
15540
|
+
export declare const placementFromRect: (rect: F0Rect, corner: F0WindowCorner, viewport: Viewport) => F0WindowPlacement;
|
|
15541
|
+
|
|
14432
15542
|
declare type PopoverContentProps = React_2.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> & {
|
|
15543
|
+
/** Portal target. Defaults to the nearest `PortalContainerProvider`. */
|
|
14433
15544
|
container?: HTMLElement | null;
|
|
14434
15545
|
};
|
|
14435
15546
|
|
|
@@ -14856,6 +15967,16 @@ declare type RelaxedNumericWithFormatter = Omit<NumericWithFormatter, "numericVa
|
|
|
14856
15967
|
|
|
14857
15968
|
declare type RendererDefinition = ValueDisplayRendererDefinition;
|
|
14858
15969
|
|
|
15970
|
+
/**
|
|
15971
|
+
* Promotes off-page speakers into the visible page, replacing the tile that has
|
|
15972
|
+
* been quiet the longest rather than the first one — swapping into slot 0 makes
|
|
15973
|
+
* the grid jump on every turn.
|
|
15974
|
+
*
|
|
15975
|
+
* The hold window stops two people alternating from shuffling tiles on every
|
|
15976
|
+
* exchange, which is the single most distracting thing a video grid can do.
|
|
15977
|
+
*/
|
|
15978
|
+
export declare const reorderForSpeakers: ({ tiles, speakerIds, pageSize, lastSpokenAt, now, holdMs, }: SpeakerOrderInput) => F0MeetingTile[];
|
|
15979
|
+
|
|
14859
15980
|
export declare interface ReplaceBlockNotesTextEditorPageDocumentPatch {
|
|
14860
15981
|
type: "replace_block";
|
|
14861
15982
|
targetId: string;
|
|
@@ -14882,6 +16003,19 @@ declare type RequisitionProfile = {
|
|
|
14882
16003
|
};
|
|
14883
16004
|
};
|
|
14884
16005
|
|
|
16006
|
+
/**
|
|
16007
|
+
* Decides which tile is spotlighted. Pure, so every branch is a unit test.
|
|
16008
|
+
*
|
|
16009
|
+
* Priority: the user's pin, then a screen share we have not focused yet, then
|
|
16010
|
+
* the remote participant in a one-to-one.
|
|
16011
|
+
*
|
|
16012
|
+
* The `none` intent is what makes the pin button work in a one-to-one. With a
|
|
16013
|
+
* plain nullable key, dismissing the spotlight fell straight back into the
|
|
16014
|
+
* two-camera rule below and re-focused the same person in the same render, so
|
|
16015
|
+
* the control did nothing at all.
|
|
16016
|
+
*/
|
|
16017
|
+
export declare const resolveAutoFocus: ({ tiles, intent, seenShareKeys, }: AutoFocusInput) => AutoFocusResult;
|
|
16018
|
+
|
|
14885
16019
|
export declare type ResolvedRecordType<R> = R extends RecordType ? R : RecordType;
|
|
14886
16020
|
|
|
14887
16021
|
/**
|
|
@@ -14891,6 +16025,14 @@ export declare type ResolvedRecordType<R> = R extends RecordType ? R : RecordTyp
|
|
|
14891
16025
|
*/
|
|
14892
16026
|
export declare const resolveGranularityDefinition: (key: NavigationGranularityKey) => GranularityDefinition;
|
|
14893
16027
|
|
|
16028
|
+
/**
|
|
16029
|
+
* Resolves an anchored placement into an absolute rect, clamped into the
|
|
16030
|
+
* current viewport. Anchoring to a corner (rather than storing x/y) is what
|
|
16031
|
+
* keeps the window sensible when the browser is resized: it stays glued to
|
|
16032
|
+
* "its" corner instead of drifting off-screen.
|
|
16033
|
+
*/
|
|
16034
|
+
export declare const resolvePlacement: (placement: F0WindowPlacement, viewport: Viewport, minWidth?: number, minHeight?: number) => F0Rect;
|
|
16035
|
+
|
|
14894
16036
|
/** A renderer entry in its full form — a bare function is just its `render`. */
|
|
14895
16037
|
export declare const resolveSlotRenderer: (entry: SlotRendererEntry | undefined) => {
|
|
14896
16038
|
render: SlotRenderer;
|
|
@@ -15184,6 +16326,12 @@ export declare const selectSizes: readonly ["sm", "md"];
|
|
|
15184
16326
|
|
|
15185
16327
|
export declare const selectVariants: readonly ["field", "inline"];
|
|
15186
16328
|
|
|
16329
|
+
/**
|
|
16330
|
+
* Placement after a drag: always re-anchored to the nearest corner, and pulled
|
|
16331
|
+
* flush to it when the window was dropped close enough.
|
|
16332
|
+
*/
|
|
16333
|
+
export declare const settlePlacement: (rect: F0Rect, viewport: Viewport) => F0WindowPlacement;
|
|
16334
|
+
|
|
15187
16335
|
/**
|
|
15188
16336
|
* @experimental This is an experimental component use it at your own risk
|
|
15189
16337
|
*/
|
|
@@ -15958,6 +17106,30 @@ export declare type SlotWidgetProps = HomeWidgetChrome & {
|
|
|
15958
17106
|
ctx?: HomeRenderCtx;
|
|
15959
17107
|
};
|
|
15960
17108
|
|
|
17109
|
+
/**
|
|
17110
|
+
* Picks the row split for the most people the floors admit, each row filling
|
|
17111
|
+
* the container's width on its own.
|
|
17112
|
+
*
|
|
17113
|
+
* Two ideas do the work. A tile takes the shape of its own cell within
|
|
17114
|
+
* `[minAspect, maxAspect]`, so inside that range the tile IS the cell and the
|
|
17115
|
+
* block covers the container instead of letterboxing a fixed 16:9 box in every
|
|
17116
|
+
* cell. And rows are sized independently, so an incomplete last row spreads its
|
|
17117
|
+
* tiles over the full width rather than leaving the missing cells as a hole —
|
|
17118
|
+
* three people fill the room, they do not sit next to an empty square.
|
|
17119
|
+
*
|
|
17120
|
+
* Selection is coverage within a tolerance of maximin — see `pick`.
|
|
17121
|
+
*
|
|
17122
|
+
* Pure, so it is tested without rendering.
|
|
17123
|
+
*/
|
|
17124
|
+
export declare const solveGrid: (input: GridSolverInput) => GridSolution;
|
|
17125
|
+
|
|
17126
|
+
/**
|
|
17127
|
+
* Spotlight plus a thumbnail strip. The strip is a PROPORTION of the container
|
|
17128
|
+
* rather than a fixed height: the previous implementation hard-coded 125px,
|
|
17129
|
+
* which is most of a small floating window.
|
|
17130
|
+
*/
|
|
17131
|
+
export declare const solveSpotlight: ({ stripCount, width, height, gap, stripRange, spotlightRange, }: SpotlightSolverInput) => SpotlightSolution;
|
|
17132
|
+
|
|
15961
17133
|
/**
|
|
15962
17134
|
* Type helper to extract keys from a SortingsDefinition
|
|
15963
17135
|
*/
|
|
@@ -15982,6 +17154,20 @@ export declare type SortingsStateMultiple = {
|
|
|
15982
17154
|
|
|
15983
17155
|
export declare type SortOrder = "asc" | "desc";
|
|
15984
17156
|
|
|
17157
|
+
declare type SpeakerOrderInput = {
|
|
17158
|
+
tiles: F0MeetingTile[];
|
|
17159
|
+
/** Participants currently speaking. */
|
|
17160
|
+
speakerIds: readonly string[];
|
|
17161
|
+
/** How many tiles the grid can show at once. */
|
|
17162
|
+
pageSize: number;
|
|
17163
|
+
/** participantId → epoch ms of their last turn. */
|
|
17164
|
+
lastSpokenAt: Readonly<Record<string, number>>;
|
|
17165
|
+
/** Now, injected so the function stays pure and testable. */
|
|
17166
|
+
now: number;
|
|
17167
|
+
/** A visible tile is only displaced after being quiet this long. */
|
|
17168
|
+
holdMs: number;
|
|
17169
|
+
};
|
|
17170
|
+
|
|
15985
17171
|
/**
|
|
15986
17172
|
* @experimental This is an experimental component use it at your own risk
|
|
15987
17173
|
*/
|
|
@@ -16033,6 +17219,43 @@ class?: never;
|
|
|
16033
17219
|
className?: ClassValue;
|
|
16034
17220
|
})) | undefined) => string> & RefAttributes<HTMLDivElement>, "ref"> & RefAttributes<HTMLElement | SVGElement>>;
|
|
16035
17221
|
|
|
17222
|
+
export declare type SpotlightSolution = {
|
|
17223
|
+
spotlight: F0Rect;
|
|
17224
|
+
strip: F0Rect[];
|
|
17225
|
+
/** Thumbnails that did not fit, for the "+N" chip. */
|
|
17226
|
+
stripOverflow: number;
|
|
17227
|
+
stripSide: "bottom" | "right" | "none";
|
|
17228
|
+
};
|
|
17229
|
+
|
|
17230
|
+
export declare type SpotlightSolverInput = {
|
|
17231
|
+
/** Participants that are NOT the spotlight. */
|
|
17232
|
+
stripCount: number;
|
|
17233
|
+
width: number;
|
|
17234
|
+
height: number;
|
|
17235
|
+
gap: number;
|
|
17236
|
+
/**
|
|
17237
|
+
* How far a thumbnail may stray to take the shape of its own slot. Uniform
|
|
17238
|
+
* across the strip, but derived from the container rather than fixed: a wide
|
|
17239
|
+
* room gets nearly square thumbnails, a side panel portrait ones.
|
|
17240
|
+
*/
|
|
17241
|
+
stripRange: {
|
|
17242
|
+
min: number;
|
|
17243
|
+
max: number;
|
|
17244
|
+
};
|
|
17245
|
+
/**
|
|
17246
|
+
* Cameras pass a range: the spotlight takes the shape of its box, clamped, so
|
|
17247
|
+
* it crops the sides rather than leaving most of a tall panel empty.
|
|
17248
|
+
*
|
|
17249
|
+
* Screen shares omit it and the spotlight takes the WHOLE box, letterboxing
|
|
17250
|
+
* the presentation inside its own tile. That is what puts the black exactly
|
|
17251
|
+
* where the picture is missing instead of darkening the whole room.
|
|
17252
|
+
*/
|
|
17253
|
+
spotlightRange?: {
|
|
17254
|
+
min: number;
|
|
17255
|
+
max: number;
|
|
17256
|
+
};
|
|
17257
|
+
};
|
|
17258
|
+
|
|
16036
17259
|
export declare const Stack: ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
|
|
16037
17260
|
overflow?: "hidden" | "auto" | undefined;
|
|
16038
17261
|
paddingX?: "none" | "p-4" | "p-2" | "p-8" | "p-12" | "p-16" | undefined;
|
|
@@ -16598,6 +17821,11 @@ declare type TextCellConfig = {
|
|
|
16598
17821
|
/** The HTML-ish input type of a text cell. Drives a default leading icon. */
|
|
16599
17822
|
declare type TextCellInputType = "text" | "email" | "url" | "tel";
|
|
16600
17823
|
|
|
17824
|
+
/** Ratio to lay a tile out with: screen shares keep their intrinsic one. */
|
|
17825
|
+
export declare const tileAspectRatio: (tile: F0MeetingTile, fallback: number) => number;
|
|
17826
|
+
|
|
17827
|
+
export declare const tileKey: (participantId: string, kind: string) => string;
|
|
17828
|
+
|
|
16601
17829
|
/** A button rendered in the footer at the bottom of the table of contents */
|
|
16602
17830
|
export declare type TOCAction = {
|
|
16603
17831
|
label: string;
|
|
@@ -17122,6 +18350,26 @@ declare interface UseExportActionProps<R extends RecordType, Filters extends Fil
|
|
|
17122
18350
|
/** Read the chat runtime. Throws when used outside an {@link F0ChatProvider}. */
|
|
17123
18351
|
export declare function useF0Chat(): F0ChatRuntime;
|
|
17124
18352
|
|
|
18353
|
+
export declare const useF0Meeting: () => F0MeetingRuntime;
|
|
18354
|
+
|
|
18355
|
+
export declare const useF0MeetingRoster: () => F0MeetingRoster;
|
|
18356
|
+
|
|
18357
|
+
export declare const useF0MeetingStable: () => F0MeetingStable;
|
|
18358
|
+
|
|
18359
|
+
/**
|
|
18360
|
+
* Whether there is a call at all.
|
|
18361
|
+
*
|
|
18362
|
+
* The providers render with or without one (see {@link F0Meeting}), so being
|
|
18363
|
+
* inside them does NOT imply a live runtime and the three hooks below still
|
|
18364
|
+
* throw. Ask this first from anywhere that can outlive the call.
|
|
18365
|
+
*
|
|
18366
|
+
* Which is not a rare corner: anything the HOST mounts — panel content, a slot,
|
|
18367
|
+
* its own chrome — is removed by an effect, a commit after the runtime went
|
|
18368
|
+
* null. That one render is enough to take the page down, and it is exactly what
|
|
18369
|
+
* hanging up out of `panel` mode used to do.
|
|
18370
|
+
*/
|
|
18371
|
+
export declare const useHasF0Meeting: () => boolean;
|
|
18372
|
+
|
|
17125
18373
|
export declare const useInfiniteScrollPagination: (paginationInfo: PaginationInfo | null, isLoading: boolean, isLoadingMore: boolean, loadMore: () => void) => {
|
|
17126
18374
|
loadingIndicatorRef: RefObject<HTMLTableCellElement>;
|
|
17127
18375
|
};
|
|
@@ -17133,6 +18381,34 @@ export declare const useInfiniteScrollPagination: (paginationInfo: PaginationInf
|
|
|
17133
18381
|
*/
|
|
17134
18382
|
export declare const useIsBulkChange: (count: number, threshold?: number) => boolean;
|
|
17135
18383
|
|
|
18384
|
+
/**
|
|
18385
|
+
* Subscribes to one participant's volatile signals. Call it as deep in the tree
|
|
18386
|
+
* as possible — ideally in the leaf that draws the waveform — so an audio burst
|
|
18387
|
+
* repaints a handful of bars instead of the whole tile.
|
|
18388
|
+
*
|
|
18389
|
+
* With a `selector` the component re-renders only when the SELECTED value
|
|
18390
|
+
* changes: the quality bars can watch `quality` and sit out every audio level.
|
|
18391
|
+
* `isEqual` defaults to `Object.is`, which is all a primitive needs.
|
|
18392
|
+
*
|
|
18393
|
+
* When the host provides no signal store the hook returns a frozen default, so
|
|
18394
|
+
* the room degrades to muted flags with no waveform instead of breaking.
|
|
18395
|
+
*/
|
|
18396
|
+
export declare function useMeetingSignal(participantId: string): F0MeetingSignal;
|
|
18397
|
+
|
|
18398
|
+
export declare function useMeetingSignal<T>(participantId: string, selector: (signal: F0MeetingSignal) => T, isEqual?: (previous: T, next: T) => boolean): T;
|
|
18399
|
+
|
|
18400
|
+
/** The set of currently speaking participants, for the layout's ordering. */
|
|
18401
|
+
export declare const useMeetingSpeakers: () => readonly string[];
|
|
18402
|
+
|
|
18403
|
+
export declare const useMeetingSurface: () => MeetingSurfaceContextValue;
|
|
18404
|
+
|
|
18405
|
+
/**
|
|
18406
|
+
* The same state, for consumers that render whether or not a call exists — the
|
|
18407
|
+
* application frame reads this to decide how much width to reserve, and there
|
|
18408
|
+
* is no provider at all when `runtime` is null.
|
|
18409
|
+
*/
|
|
18410
|
+
export declare const useMeetingSurfaceOptional: () => MeetingSurfaceContextValue | null;
|
|
18411
|
+
|
|
17136
18412
|
/**
|
|
17137
18413
|
* Converts an item-navigation result into the `NavigationProps` shape that
|
|
17138
18414
|
* `PageHeader` and `F0Dialog` accept (directly or via
|
|
@@ -17204,6 +18480,18 @@ export declare const useSidebarChats: () => SidebarChatStore;
|
|
|
17204
18480
|
*/
|
|
17205
18481
|
export declare function useSidePanel(): SidePanelContextValue;
|
|
17206
18482
|
|
|
18483
|
+
/**
|
|
18484
|
+
* Attaches a track to a media element F0 owns.
|
|
18485
|
+
*
|
|
18486
|
+
* The effect depends on `bindingKey` and on WHETHER there is a binding — never
|
|
18487
|
+
* on the function's identity. Hosts rebuild the runtime, and with it every
|
|
18488
|
+
* `binding` closure, on each transport event, so depending on identity would
|
|
18489
|
+
* detach and re-attach the element around twenty times a second, black-flashing
|
|
18490
|
+
* the video continuously. The presence flag is what lets a binding that arrives
|
|
18491
|
+
* a commit after its key (a stream that opened late) still get attached.
|
|
18492
|
+
*/
|
|
18493
|
+
export declare const useTrackBinding: <T extends HTMLMediaElement>(track: F0MeetingTrack | undefined) => React.RefObject<T>;
|
|
18494
|
+
|
|
17207
18495
|
export declare const useWidgetIsWide: () => boolean;
|
|
17208
18496
|
|
|
17209
18497
|
/**
|
|
@@ -17351,6 +18639,11 @@ declare interface VideoPlayerContent {
|
|
|
17351
18639
|
descriptions?: Localized<string>;
|
|
17352
18640
|
}
|
|
17353
18641
|
|
|
18642
|
+
declare type Viewport = {
|
|
18643
|
+
width: number;
|
|
18644
|
+
height: number;
|
|
18645
|
+
};
|
|
18646
|
+
|
|
17354
18647
|
/**
|
|
17355
18648
|
* Region of the canvas (in screen px) covered by external chrome — typically a
|
|
17356
18649
|
* side panel / drawer opened over the graph. All fly-to paths shift their target
|
|
@@ -17369,6 +18662,9 @@ export declare interface ViewportInset {
|
|
|
17369
18662
|
left?: number;
|
|
17370
18663
|
}
|
|
17371
18664
|
|
|
18665
|
+
/** The whole viewport as a rect, for hosts that publish no content area. */
|
|
18666
|
+
export declare const viewportRect: (viewport: Viewport) => F0Rect;
|
|
18667
|
+
|
|
17372
18668
|
/**
|
|
17373
18669
|
* @experimental This is an experimental component use it at your own risk
|
|
17374
18670
|
*/
|