@flamingo-stack/openframe-frontend-core 0.0.700 → 0.0.701-snapshot.20261005171139
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/{chunk-MFORWVGD.js → chunk-2V4Z44G6.js} +4 -4
- package/dist/{chunk-GFXZMFDX.cjs → chunk-3G76LRGL.cjs} +9 -9
- package/dist/{chunk-65YVUYWJ.cjs → chunk-3WSFIV5G.cjs} +32 -32
- package/dist/{chunk-GD4JALTR.js → chunk-446KS5BG.js} +1 -1
- package/dist/{chunk-BRQY2HKD.cjs → chunk-AEQANLBW.cjs} +17 -17
- package/dist/{chunk-ZSPHOHOW.cjs → chunk-ASN65P3F.cjs} +2 -2
- package/dist/{chunk-YBC346FY.cjs → chunk-B3LZJ6J3.cjs} +12 -12
- package/dist/{chunk-JPVDJB27.js → chunk-BO5ZHDA4.js} +3 -3
- package/dist/{chunk-2CSYUMNM.cjs → chunk-CXDJUKC6.cjs} +2 -2
- package/dist/{chunk-QPNR4N7N.cjs → chunk-CYYTD5ZK.cjs} +16 -16
- package/dist/{chunk-B7M6QEEM.js → chunk-CZ34HXDW.js} +661 -275
- package/dist/{chunk-4H5Q6MQG.cjs → chunk-E3DH543A.cjs} +35 -35
- package/dist/{chunk-BZYMGI4L.js → chunk-ETFFEA3J.js} +1 -1
- package/dist/{chunk-QDIX2ZRL.cjs → chunk-FD4DBTFO.cjs} +430 -44
- package/dist/{chunk-BPS7JQCI.cjs → chunk-FHM7GD5B.cjs} +2 -2
- package/dist/{chunk-QZGFJBG5.cjs → chunk-HIXGAY2L.cjs} +50 -50
- package/dist/{chunk-V5QNDOEL.js → chunk-HPJ4XS2L.js} +3 -3
- package/dist/{chunk-DJLZXJYB.js → chunk-HYFLTFFB.js} +1 -1
- package/dist/{chunk-CUPJCGLB.js → chunk-IZKOQVXO.js} +1 -1
- package/dist/{chunk-N7DPIH57.js → chunk-JOY6HVPV.js} +1 -1
- package/dist/{chunk-NIT257DV.cjs → chunk-L7KZA7ZD.cjs} +2 -2
- package/dist/{chunk-BQ34PIFC.cjs → chunk-LZNJH23A.cjs} +3 -3
- package/dist/{chunk-EONNPRAW.js → chunk-MWUBBBWZ.js} +1 -1
- package/dist/{chunk-N7HMUQRV.js → chunk-PLK6GHN7.js} +1 -1
- package/dist/{chunk-DG2I57UM.cjs → chunk-QFW3RUZS.cjs} +16 -16
- package/dist/{chunk-S4ADN25W.js → chunk-RS7HWAYX.js} +1 -1
- package/dist/{chunk-PNWIVND4.js → chunk-SAA7B3DA.js} +2 -2
- package/dist/{chunk-6JG75WVO.js → chunk-UJJWTJ6S.js} +4 -4
- package/dist/{chunk-7ZDTAABP.cjs → chunk-YGRHITPY.cjs} +3 -3
- package/dist/{chunk-A5ZGKBN2.js → chunk-Z5HDCZAS.js} +1 -1
- package/dist/components/announcement-bar.d.ts +1 -1
- package/dist/components/announcement-bar.d.ts.map +1 -1
- package/dist/components/case-studies/index.cjs +11 -11
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +6 -6
- package/dist/components/docs/index.js +5 -5
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/index.cjs +22 -2
- package/dist/components/features/index.js +21 -1
- package/dist/components/features/remote-session/index.d.ts +9 -1
- package/dist/components/features/remote-session/index.d.ts.map +1 -1
- package/dist/components/features/remote-session/remote-session-block.d.ts +4 -2
- package/dist/components/features/remote-session/remote-session-block.d.ts.map +1 -1
- package/dist/components/features/remote-session/remote-session-chat-panel.d.ts +4 -2
- package/dist/components/features/remote-session/remote-session-chat-panel.d.ts.map +1 -1
- package/dist/components/features/remote-session/remote-session-events.d.ts +24 -0
- package/dist/components/features/remote-session/remote-session-events.d.ts.map +1 -0
- package/dist/components/features/remote-session/remote-session-keep-modals.d.ts +41 -0
- package/dist/components/features/remote-session/remote-session-keep-modals.d.ts.map +1 -0
- package/dist/components/features/remote-session/remote-session-parts.d.ts +13 -2
- package/dist/components/features/remote-session/remote-session-parts.d.ts.map +1 -1
- package/dist/components/features/remote-session/remote-session-status.d.ts +34 -0
- package/dist/components/features/remote-session/remote-session-status.d.ts.map +1 -0
- package/dist/components/features/remote-session/remote-session-viewers.d.ts +15 -0
- package/dist/components/features/remote-session/remote-session-viewers.d.ts.map +1 -0
- package/dist/components/features/remote-session/types.d.ts +22 -0
- package/dist/components/features/remote-session/types.d.ts.map +1 -1
- package/dist/components/help-center-pages/index.cjs +49 -49
- package/dist/components/help-center-pages/index.js +13 -13
- package/dist/components/index.cjs +55 -34
- package/dist/components/index.js +35 -14
- package/dist/components/meeting-scheduler/index.cjs +22 -22
- package/dist/components/meeting-scheduler/index.js +1 -1
- package/dist/components/navigation/index.cjs +5 -5
- package/dist/components/navigation/index.js +4 -4
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/tickets/index.cjs +6 -6
- package/dist/components/tickets/index.js +5 -5
- package/dist/components/ui/index.cjs +2 -2
- package/dist/components/ui/index.js +1 -1
- package/dist/index.cjs +26 -6
- package/dist/index.js +25 -5
- package/dist/tailwind.config.cjs +7 -1
- package/dist/tailwind.config.js +7 -1
- package/dist/types/announcement.d.ts +1 -6
- package/dist/types/announcement.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/announcement-bar.tsx +7 -2
- package/src/components/features/remote-session/index.ts +28 -0
- package/src/components/features/remote-session/remote-session-block.tsx +6 -3
- package/src/components/features/remote-session/remote-session-chat-panel.tsx +11 -7
- package/src/components/features/remote-session/remote-session-events.tsx +93 -0
- package/src/components/features/remote-session/remote-session-keep-modals.tsx +208 -0
- package/src/components/features/remote-session/remote-session-parts.tsx +32 -3
- package/src/components/features/remote-session/remote-session-status.tsx +102 -0
- package/src/components/features/remote-session/remote-session-viewers.tsx +103 -0
- package/src/components/features/remote-session/types.ts +26 -0
- package/src/types/announcement.ts +1 -6
- package/tailwind.config.ts +6 -0
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
SoftwareInfo,
|
|
10
10
|
SoftwareSourceBadge,
|
|
11
11
|
ToolBadge
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-PLK6GHN7.js";
|
|
13
13
|
import {
|
|
14
14
|
AppHeader,
|
|
15
15
|
AppLayout,
|
|
@@ -29,14 +29,14 @@ import {
|
|
|
29
29
|
SlidingSidebar,
|
|
30
30
|
TicketAlertsButton,
|
|
31
31
|
TopNavigation
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-SAA7B3DA.js";
|
|
33
33
|
import {
|
|
34
34
|
MobileNavigationDropdown,
|
|
35
35
|
MultiLevelNavigation,
|
|
36
36
|
StickySectionNav,
|
|
37
37
|
useSectionNavigation
|
|
38
|
-
} from "./chunk-
|
|
39
|
-
import "./chunk-
|
|
38
|
+
} from "./chunk-HYFLTFFB.js";
|
|
39
|
+
import "./chunk-RS7HWAYX.js";
|
|
40
40
|
import {
|
|
41
41
|
AIEnrichButton,
|
|
42
42
|
AIEnrichSection,
|
|
@@ -233,6 +233,7 @@ import {
|
|
|
233
233
|
InputTrigger,
|
|
234
234
|
InviteLinkInvalidModal,
|
|
235
235
|
JsonDetailList,
|
|
236
|
+
KeepRecordingModal,
|
|
236
237
|
KnowledgeBaseLinksManager,
|
|
237
238
|
LabeledDivider,
|
|
238
239
|
LazyMount,
|
|
@@ -334,6 +335,7 @@ import {
|
|
|
334
335
|
QueryReportTableRow,
|
|
335
336
|
QueryReportTableSkeleton,
|
|
336
337
|
REMOTE_SESSION_DRAG_HANDLE_CLASS,
|
|
338
|
+
REMOTE_SESSION_KEEP_REASON_LABELS,
|
|
337
339
|
ROADMAP_STATUS_OPTIONS,
|
|
338
340
|
ROW_HEIGHT_DESKTOP,
|
|
339
341
|
ROW_HEIGHT_MOBILE,
|
|
@@ -342,6 +344,7 @@ import {
|
|
|
342
344
|
RadioGroupBlock,
|
|
343
345
|
RadioGroupItem,
|
|
344
346
|
ReleaseChangelogSection,
|
|
347
|
+
ReleaseKeepingModal,
|
|
345
348
|
RemoteAccessRequestCard,
|
|
346
349
|
RemoteSessionBlockFrame,
|
|
347
350
|
RemoteSessionBorder,
|
|
@@ -349,12 +352,18 @@ import {
|
|
|
349
352
|
RemoteSessionDialog,
|
|
350
353
|
RemoteSessionDragger,
|
|
351
354
|
RemoteSessionEndButton,
|
|
355
|
+
RemoteSessionEventList,
|
|
356
|
+
RemoteSessionExpiry,
|
|
352
357
|
RemoteSessionMinimizedChip,
|
|
353
358
|
RemoteSessionOrgLogo,
|
|
354
359
|
RemoteSessionPill,
|
|
355
360
|
RemoteSessionRecordingTag,
|
|
356
361
|
RemoteSessionScope,
|
|
362
|
+
RemoteSessionStatusTag,
|
|
363
|
+
RemoteSessionStorageAlert,
|
|
357
364
|
RemoteSessionSummary,
|
|
365
|
+
RemoteSessionTimelineMarkers,
|
|
366
|
+
RemoteSessionViewers,
|
|
358
367
|
ReopenTicketModal,
|
|
359
368
|
ReopenTicketRequestModal,
|
|
360
369
|
RichMarkdownRenderer,
|
|
@@ -528,6 +537,7 @@ import {
|
|
|
528
537
|
formatDocName,
|
|
529
538
|
formatPhoneE164,
|
|
530
539
|
formatRemoteSessionElapsed,
|
|
540
|
+
formatRemoteSessionOffset,
|
|
531
541
|
formatTestRunDuration,
|
|
532
542
|
generateBiteId,
|
|
533
543
|
getApprovalMeta,
|
|
@@ -655,7 +665,7 @@ import {
|
|
|
655
665
|
withFirstTouchAttribution,
|
|
656
666
|
withWalkthroughOpenParam,
|
|
657
667
|
writeDismissCookie
|
|
658
|
-
} from "./chunk-
|
|
668
|
+
} from "./chunk-CZ34HXDW.js";
|
|
659
669
|
import "./chunk-LQYXMEYF.js";
|
|
660
670
|
import "./chunk-4JPLYOS6.js";
|
|
661
671
|
import {
|
|
@@ -2390,6 +2400,7 @@ export {
|
|
|
2390
2400
|
InviteLinkInvalidModal,
|
|
2391
2401
|
JsonDetailList,
|
|
2392
2402
|
JumpInIcon,
|
|
2403
|
+
KeepRecordingModal,
|
|
2393
2404
|
KnowledgeBaseLinksManager,
|
|
2394
2405
|
LOG_SEVERITY_COLORS,
|
|
2395
2406
|
LOG_SEVERITY_LABELS,
|
|
@@ -2620,6 +2631,7 @@ export {
|
|
|
2620
2631
|
RATIO_GRID_CLASS,
|
|
2621
2632
|
RATIO_TO_CSS_ASPECT,
|
|
2622
2633
|
REMOTE_SESSION_DRAG_HANDLE_CLASS,
|
|
2634
|
+
REMOTE_SESSION_KEEP_REASON_LABELS,
|
|
2623
2635
|
RESCUE_FORMS,
|
|
2624
2636
|
RESYNC_AFTER_HIDDEN_MS,
|
|
2625
2637
|
ROADMAP_STATUS_OPTIONS,
|
|
@@ -2634,6 +2646,7 @@ export {
|
|
|
2634
2646
|
ReclaimProfitsIcon,
|
|
2635
2647
|
RedditIcon,
|
|
2636
2648
|
ReleaseChangelogSection,
|
|
2649
|
+
ReleaseKeepingModal,
|
|
2637
2650
|
RemoteAccessRequestCard,
|
|
2638
2651
|
RemoteControlIcon,
|
|
2639
2652
|
RemoteSessionBlockFrame,
|
|
@@ -2642,12 +2655,18 @@ export {
|
|
|
2642
2655
|
RemoteSessionDialog,
|
|
2643
2656
|
RemoteSessionDragger,
|
|
2644
2657
|
RemoteSessionEndButton,
|
|
2658
|
+
RemoteSessionEventList,
|
|
2659
|
+
RemoteSessionExpiry,
|
|
2645
2660
|
RemoteSessionMinimizedChip,
|
|
2646
2661
|
RemoteSessionOrgLogo,
|
|
2647
2662
|
RemoteSessionPill,
|
|
2648
2663
|
RemoteSessionRecordingTag,
|
|
2649
2664
|
RemoteSessionScope,
|
|
2665
|
+
RemoteSessionStatusTag,
|
|
2666
|
+
RemoteSessionStorageAlert,
|
|
2650
2667
|
RemoteSessionSummary,
|
|
2668
|
+
RemoteSessionTimelineMarkers,
|
|
2669
|
+
RemoteSessionViewers,
|
|
2651
2670
|
RenameChatModal,
|
|
2652
2671
|
ReopenTicketModal,
|
|
2653
2672
|
ReopenTicketRequestModal,
|
|
@@ -3105,6 +3124,7 @@ export {
|
|
|
3105
3124
|
formatRelativeTime,
|
|
3106
3125
|
formatReleaseDate,
|
|
3107
3126
|
formatRemoteSessionElapsed,
|
|
3127
|
+
formatRemoteSessionOffset,
|
|
3108
3128
|
formatSingularLookupInvocation,
|
|
3109
3129
|
formatTestRunDuration,
|
|
3110
3130
|
formatTicketFullTimestamp,
|
package/dist/tailwind.config.cjs
CHANGED
|
@@ -486,6 +486,11 @@ var config = {
|
|
|
486
486
|
"dot-pulse": {
|
|
487
487
|
"0%, 80%, 100%": { transform: "scale(1)", opacity: "0.7" },
|
|
488
488
|
"40%": { transform: "scale(1.5)", opacity: "1" }
|
|
489
|
+
},
|
|
490
|
+
// The dot on a LIVE tag: opacity only, so it reads as "on air" without moving.
|
|
491
|
+
"live-pulse": {
|
|
492
|
+
"0%, 100%": { opacity: "1" },
|
|
493
|
+
"50%": { opacity: "0.25" }
|
|
489
494
|
}
|
|
490
495
|
},
|
|
491
496
|
animation: {
|
|
@@ -493,7 +498,8 @@ var config = {
|
|
|
493
498
|
"accordion-up": "accordion-up 0.2s ease-out",
|
|
494
499
|
"fade-in": "fade-in 0.3s ease-out",
|
|
495
500
|
"cursor-blink": "cursor-blink 1s steps(1) infinite",
|
|
496
|
-
"dot-pulse": "dot-pulse 1.4s ease-in-out infinite"
|
|
501
|
+
"dot-pulse": "dot-pulse 1.4s ease-in-out infinite",
|
|
502
|
+
"live-pulse": "live-pulse 1.6s ease-in-out infinite"
|
|
497
503
|
}
|
|
498
504
|
}
|
|
499
505
|
},
|
package/dist/tailwind.config.js
CHANGED
|
@@ -479,6 +479,11 @@ var config = {
|
|
|
479
479
|
"dot-pulse": {
|
|
480
480
|
"0%, 80%, 100%": { transform: "scale(1)", opacity: "0.7" },
|
|
481
481
|
"40%": { transform: "scale(1.5)", opacity: "1" }
|
|
482
|
+
},
|
|
483
|
+
// The dot on a LIVE tag: opacity only, so it reads as "on air" without moving.
|
|
484
|
+
"live-pulse": {
|
|
485
|
+
"0%, 100%": { opacity: "1" },
|
|
486
|
+
"50%": { opacity: "0.25" }
|
|
482
487
|
}
|
|
483
488
|
},
|
|
484
489
|
animation: {
|
|
@@ -486,7 +491,8 @@ var config = {
|
|
|
486
491
|
"accordion-up": "accordion-up 0.2s ease-out",
|
|
487
492
|
"fade-in": "fade-in 0.3s ease-out",
|
|
488
493
|
"cursor-blink": "cursor-blink 1s steps(1) infinite",
|
|
489
|
-
"dot-pulse": "dot-pulse 1.4s ease-in-out infinite"
|
|
494
|
+
"dot-pulse": "dot-pulse 1.4s ease-in-out infinite",
|
|
495
|
+
"live-pulse": "live-pulse 1.6s ease-in-out infinite"
|
|
490
496
|
}
|
|
491
497
|
}
|
|
492
498
|
},
|
|
@@ -15,7 +15,7 @@ export interface Announcement {
|
|
|
15
15
|
is_active: boolean;
|
|
16
16
|
/** A one-line form of the title for tight spots (a hero's news pill). */
|
|
17
17
|
short_title?: string | null;
|
|
18
|
-
/**
|
|
18
|
+
/** Path patterns the bar is NOT shown on (regular expressions matched against the whole path): the page shows the news itself. */
|
|
19
19
|
excluded_paths?: string[] | null;
|
|
20
20
|
cta_enabled?: boolean;
|
|
21
21
|
cta_text?: string;
|
|
@@ -215,11 +215,6 @@ export interface AnnouncementBarProps {
|
|
|
215
215
|
* currentPlatform()).
|
|
216
216
|
*/
|
|
217
217
|
initialAnnouncement?: Announcement | null;
|
|
218
|
-
/**
|
|
219
|
-
* The path the bar is rendered on. When the announcement lists it in
|
|
220
|
-
* `excluded_paths`, the bar stays collapsed. Omitted: never excluded.
|
|
221
|
-
*/
|
|
222
|
-
pathname?: string | null;
|
|
223
218
|
/**
|
|
224
219
|
* Render-only mode for the admin live preview: no fetch/revalidation, inert
|
|
225
220
|
* dismiss button, and no storage side effects (never writes dismissal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"announcement.d.ts","sourceRoot":"","sources":["../../src/types/announcement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjE,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC;iFAC6E;IAC7E,sBAAsB,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,
|
|
1
|
+
{"version":3,"file":"announcement.d.ts","sourceRoot":"","sources":["../../src/types/announcement.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { X } from 'lucide-react';
|
|
4
4
|
import { useEffect, useMemo, useState, useSyncExternalStore } from 'react';
|
|
5
5
|
import { useEndpointsRuntime } from '../contexts/endpoints-runtime-context';
|
|
6
|
+
import { usePathname } from '../embed-shims/next-navigation';
|
|
6
7
|
import { useSelfFetch } from '../hooks/use-self-fetch';
|
|
7
8
|
import type { Announcement, AnnouncementBarProps, AnnouncementResponse } from '../types/announcement';
|
|
8
9
|
import { ANNOUNCEMENT_CTA_DEFAULTS } from '../types/announcement';
|
|
@@ -70,7 +71,6 @@ export function AnnouncementBar({
|
|
|
70
71
|
initialAnnouncement,
|
|
71
72
|
previewMode = false,
|
|
72
73
|
dismissible = true,
|
|
73
|
-
pathname,
|
|
74
74
|
className,
|
|
75
75
|
}: AnnouncementBarProps = {}) {
|
|
76
76
|
// Namespace for the dismissal cookie/legacy keys. Next hosts inline
|
|
@@ -80,6 +80,11 @@ export function AnnouncementBar({
|
|
|
80
80
|
// serves one platform's announcements.
|
|
81
81
|
const platform = getAppType();
|
|
82
82
|
|
|
83
|
+
// The path the bar is on, from the host's router (the navigation shim: Next's
|
|
84
|
+
// `usePathname` on a Next host, the embedder's registered router elsewhere).
|
|
85
|
+
// Read HERE so every host gets `excluded_paths` with no wiring of its own.
|
|
86
|
+
const pathname = usePathname();
|
|
87
|
+
|
|
83
88
|
// Optional endpoint runtime: no provider → no URL → fetching disabled.
|
|
84
89
|
const endpoints = useEndpointsRuntime();
|
|
85
90
|
const url = previewMode ? null : (endpoints?.announcementsUrl ?? null);
|
|
@@ -143,7 +148,7 @@ export function AnnouncementBar({
|
|
|
143
148
|
// Preview always mirrors the draft directly (storage is not consulted there).
|
|
144
149
|
// A page that shows the news itself (a hero's news pill) is listed in the
|
|
145
150
|
// announcement's `excluded_paths` (path patterns); the bar stays collapsed there.
|
|
146
|
-
const excludedHere =
|
|
151
|
+
const excludedHere = pathMatchesAny(pathname, announcement?.excluded_paths);
|
|
147
152
|
const expanded = previewMode
|
|
148
153
|
? announcement != null
|
|
149
154
|
: announcement != null && expandedState && !dismissed && !excludedHere;
|
|
@@ -16,6 +16,30 @@ export type { RemoteSessionChatPanelProps } from './remote-session-chat-panel';
|
|
|
16
16
|
export { RemoteSessionDialog } from './remote-session-dialog';
|
|
17
17
|
export type { RemoteSessionDialogProps } from './remote-session-dialog';
|
|
18
18
|
export { RemoteSessionBorder, RemoteSessionPill } from './remote-session-overlay';
|
|
19
|
+
export {
|
|
20
|
+
REMOTE_SESSION_KEEP_REASON_LABELS,
|
|
21
|
+
KeepRecordingModal,
|
|
22
|
+
ReleaseKeepingModal,
|
|
23
|
+
} from './remote-session-keep-modals';
|
|
24
|
+
export type {
|
|
25
|
+
KeepRecordingModalProps,
|
|
26
|
+
KeepRecordingSelection,
|
|
27
|
+
ReleaseKeepingModalProps,
|
|
28
|
+
} from './remote-session-keep-modals';
|
|
29
|
+
export {
|
|
30
|
+
RemoteSessionEventList,
|
|
31
|
+
RemoteSessionTimelineMarkers,
|
|
32
|
+
formatRemoteSessionOffset,
|
|
33
|
+
} from './remote-session-events';
|
|
34
|
+
export type { RemoteSessionEventListProps, RemoteSessionTimelineMarkersProps } from './remote-session-events';
|
|
35
|
+
export { RemoteSessionExpiry, RemoteSessionStatusTag, RemoteSessionStorageAlert } from './remote-session-status';
|
|
36
|
+
export type {
|
|
37
|
+
RemoteSessionExpiryProps,
|
|
38
|
+
RemoteSessionStatusTagProps,
|
|
39
|
+
RemoteSessionStorageAlertProps,
|
|
40
|
+
} from './remote-session-status';
|
|
41
|
+
export { RemoteSessionViewers } from './remote-session-viewers';
|
|
42
|
+
export type { RemoteSessionViewersProps } from './remote-session-viewers';
|
|
19
43
|
export {
|
|
20
44
|
REMOTE_SESSION_DRAG_HANDLE_CLASS,
|
|
21
45
|
RemoteSessionDragger,
|
|
@@ -32,5 +56,9 @@ export type {
|
|
|
32
56
|
RemoteSessionChatMessage,
|
|
33
57
|
RemoteSessionDialogVariant,
|
|
34
58
|
RemoteSessionDragHandlers,
|
|
59
|
+
RemoteSessionEvent,
|
|
60
|
+
RemoteSessionKeepReason,
|
|
35
61
|
RemoteSessionParty,
|
|
62
|
+
RemoteSessionStatus,
|
|
63
|
+
RemoteSessionViewer,
|
|
36
64
|
} from './types';
|
|
@@ -10,9 +10,9 @@ import {
|
|
|
10
10
|
REMOTE_SESSION_DRAG_HANDLE_CLASS,
|
|
11
11
|
RemoteSessionDragger,
|
|
12
12
|
RemoteSessionOrgLogo,
|
|
13
|
-
|
|
13
|
+
RemoteSessionStatusRow,
|
|
14
14
|
} from './remote-session-parts';
|
|
15
|
-
import type { RemoteSessionDragHandlers, RemoteSessionParty } from './types';
|
|
15
|
+
import type { RemoteSessionDragHandlers, RemoteSessionParty, RemoteSessionViewer } from './types';
|
|
16
16
|
|
|
17
17
|
export interface RemoteSessionBlockFrameProps {
|
|
18
18
|
/** The summary or the chat panel. */
|
|
@@ -74,6 +74,8 @@ export interface RemoteSessionSummaryProps {
|
|
|
74
74
|
/** Elapsed session time, e.g. from `useRemoteSessionTimer`. */
|
|
75
75
|
elapsed: string;
|
|
76
76
|
showRecordingTag?: boolean;
|
|
77
|
+
/** Everyone in the session while colleagues watch it, the host included; hidden when empty. */
|
|
78
|
+
viewers?: RemoteSessionViewer[];
|
|
77
79
|
onOpenChat: () => void;
|
|
78
80
|
onEndSession: () => void;
|
|
79
81
|
/** Makes the header row and the dragger move the window. */
|
|
@@ -85,6 +87,7 @@ export function RemoteSessionSummary({
|
|
|
85
87
|
party,
|
|
86
88
|
elapsed,
|
|
87
89
|
showRecordingTag = false,
|
|
90
|
+
viewers,
|
|
88
91
|
onOpenChat,
|
|
89
92
|
onEndSession,
|
|
90
93
|
dragHandlers,
|
|
@@ -118,7 +121,7 @@ export function RemoteSessionSummary({
|
|
|
118
121
|
<p className="w-full truncate text-ods-text-secondary text-h4">{party.organizationName}</p>
|
|
119
122
|
</div>
|
|
120
123
|
</div>
|
|
121
|
-
{showRecordingTag
|
|
124
|
+
<RemoteSessionStatusRow showRecordingTag={showRecordingTag} viewers={viewers} />
|
|
122
125
|
<div className="flex w-full items-stretch gap-[var(--spacing-system-m)]">
|
|
123
126
|
<Button
|
|
124
127
|
variant="outline"
|
|
@@ -6,12 +6,13 @@ import { MessageOffIcon, Send03Icon } from '../../icons-v2-generated';
|
|
|
6
6
|
import { Button } from '../../ui/button/button';
|
|
7
7
|
import { SquareAvatar } from '../../ui/square-avatar';
|
|
8
8
|
import { RemoteSessionEndButton } from './remote-session-block';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
import { REMOTE_SESSION_DRAG_HANDLE_CLASS, RemoteSessionDragger, RemoteSessionStatusRow } from './remote-session-parts';
|
|
10
|
+
import type {
|
|
11
|
+
RemoteSessionChatMessage,
|
|
12
|
+
RemoteSessionDragHandlers,
|
|
13
|
+
RemoteSessionParty,
|
|
14
|
+
RemoteSessionViewer,
|
|
15
|
+
} from './types';
|
|
15
16
|
|
|
16
17
|
export interface RemoteSessionChatPanelProps {
|
|
17
18
|
party: RemoteSessionParty;
|
|
@@ -19,6 +20,8 @@ export interface RemoteSessionChatPanelProps {
|
|
|
19
20
|
elapsed: string;
|
|
20
21
|
messages: RemoteSessionChatMessage[];
|
|
21
22
|
showRecordingTag?: boolean;
|
|
23
|
+
/** Everyone in the session while colleagues watch it, the host included; hidden when empty. */
|
|
24
|
+
viewers?: RemoteSessionViewer[];
|
|
22
25
|
/** The composer's text; owned by the host so it survives hiding the block. */
|
|
23
26
|
draft: string;
|
|
24
27
|
onDraftChange: (draft: string) => void;
|
|
@@ -43,6 +46,7 @@ export function RemoteSessionChatPanel({
|
|
|
43
46
|
elapsed,
|
|
44
47
|
messages,
|
|
45
48
|
showRecordingTag = false,
|
|
49
|
+
viewers,
|
|
46
50
|
draft,
|
|
47
51
|
onDraftChange,
|
|
48
52
|
onSend,
|
|
@@ -83,7 +87,7 @@ export function RemoteSessionChatPanel({
|
|
|
83
87
|
</p>
|
|
84
88
|
<p className="w-full truncate text-ods-text-secondary text-h4">You can end this session at any time</p>
|
|
85
89
|
</div>
|
|
86
|
-
{showRecordingTag
|
|
90
|
+
<RemoteSessionStatusRow showRecordingTag={showRecordingTag} viewers={viewers} />
|
|
87
91
|
<div className="flex w-full items-stretch gap-[var(--spacing-system-m)]">
|
|
88
92
|
<Button
|
|
89
93
|
variant="outline"
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { cn } from '../../../utils/cn';
|
|
4
|
+
import type { RemoteSessionEvent } from './types';
|
|
5
|
+
|
|
6
|
+
/** `mm:ss` from the start of a recording; `h:mm:ss` from the first hour on. */
|
|
7
|
+
export function formatRemoteSessionOffset(offsetMs: number): string {
|
|
8
|
+
const total = Math.max(0, Math.floor(offsetMs / 1000));
|
|
9
|
+
const hours = Math.floor(total / 3600);
|
|
10
|
+
const minutes = String(Math.floor((total % 3600) / 60)).padStart(2, '0');
|
|
11
|
+
const seconds = String(total % 60).padStart(2, '0');
|
|
12
|
+
return hours > 0 ? `${hours}:${minutes}:${seconds}` : `${minutes}:${seconds}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface RemoteSessionEventListProps {
|
|
16
|
+
events: RemoteSessionEvent[];
|
|
17
|
+
/** The event the playhead is on; highlighted. */
|
|
18
|
+
activeEventId?: string | null;
|
|
19
|
+
/** Seek the player to the event. */
|
|
20
|
+
onSelect?: (event: RemoteSessionEvent) => void;
|
|
21
|
+
className?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** SESSION EVENTS under the recording player: each event with its time, newest last. */
|
|
25
|
+
export function RemoteSessionEventList({ events, activeEventId, onSelect, className }: RemoteSessionEventListProps) {
|
|
26
|
+
return (
|
|
27
|
+
<section className={cn('flex w-full flex-col gap-[var(--spacing-system-xxs)]', className)}>
|
|
28
|
+
<h2 className="text-ods-text-secondary text-h5">Session Events</h2>
|
|
29
|
+
<ol className="flex w-full flex-col gap-[var(--spacing-system-xxs)] rounded-md border border-ods-border bg-ods-card p-[var(--spacing-system-m)]">
|
|
30
|
+
{events.map(event => (
|
|
31
|
+
<li key={event.id}>
|
|
32
|
+
<button
|
|
33
|
+
type="button"
|
|
34
|
+
aria-current={event.id === activeEventId || undefined}
|
|
35
|
+
onClick={() => onSelect?.(event)}
|
|
36
|
+
className={cn(
|
|
37
|
+
'flex w-full items-start gap-[var(--spacing-system-xxs)] rounded-md p-[var(--spacing-system-xxs)] text-left outline-none transition-colors',
|
|
38
|
+
'hover:bg-ods-bg-hover focus-visible:ring-2 focus-visible:ring-ods-focus',
|
|
39
|
+
event.id === activeEventId && 'bg-ods-border hover:bg-ods-border',
|
|
40
|
+
)}
|
|
41
|
+
>
|
|
42
|
+
<span className="w-[84px] shrink-0 text-ods-text-secondary text-h4">
|
|
43
|
+
{formatRemoteSessionOffset(event.offsetMs)}
|
|
44
|
+
</span>
|
|
45
|
+
<span className="flex min-w-0 flex-1 flex-col">
|
|
46
|
+
<span className="text-ods-text-primary text-h4">{event.title}</span>
|
|
47
|
+
{event.detail && <span className="text-ods-text-secondary text-h6">{event.detail}</span>}
|
|
48
|
+
</span>
|
|
49
|
+
</button>
|
|
50
|
+
</li>
|
|
51
|
+
))}
|
|
52
|
+
</ol>
|
|
53
|
+
</section>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface RemoteSessionTimelineMarkersProps {
|
|
58
|
+
events: RemoteSessionEvent[];
|
|
59
|
+
/** Length of the recording; events past it are pinned to the end. */
|
|
60
|
+
durationMs: number;
|
|
61
|
+
/** Seek the player to the event. */
|
|
62
|
+
onSelect?: (event: RemoteSessionEvent) => void;
|
|
63
|
+
className?: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The event marks above the player's track, one per event, at its share of the recording. */
|
|
67
|
+
export function RemoteSessionTimelineMarkers({
|
|
68
|
+
events,
|
|
69
|
+
durationMs,
|
|
70
|
+
onSelect,
|
|
71
|
+
className,
|
|
72
|
+
}: RemoteSessionTimelineMarkersProps) {
|
|
73
|
+
if (durationMs <= 0) return null;
|
|
74
|
+
return (
|
|
75
|
+
<div className={cn('relative h-4 w-full', className)}>
|
|
76
|
+
{events.map(event => {
|
|
77
|
+
const share = Math.min(1, Math.max(0, event.offsetMs / durationMs));
|
|
78
|
+
const label = `${event.title} at ${formatRemoteSessionOffset(event.offsetMs)}`;
|
|
79
|
+
return (
|
|
80
|
+
<button
|
|
81
|
+
key={event.id}
|
|
82
|
+
type="button"
|
|
83
|
+
aria-label={label}
|
|
84
|
+
title={label}
|
|
85
|
+
onClick={() => onSelect?.(event)}
|
|
86
|
+
style={{ left: `${share * 100}%` }}
|
|
87
|
+
className="absolute top-0 h-4 w-1 -translate-x-1/2 rounded-md bg-ods-text-secondary outline-none transition-colors hover:bg-ods-text-primary focus-visible:ring-2 focus-visible:ring-ods-focus"
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
})}
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|