@dxos/plugin-thread 0.8.4-main.28f8d3d → 0.8.4-main.406dc2a
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/lib/browser/ChannelContainer-BGDGZHV4.mjs +16 -0
- package/dist/lib/browser/ChatContainer-75KJZ4XR.mjs +15 -0
- package/dist/lib/browser/{app-graph-builder-AF3M7UWN.mjs → app-graph-builder-ODKIAXR7.mjs} +17 -17
- package/dist/lib/browser/app-graph-builder-ODKIAXR7.mjs.map +7 -0
- package/dist/lib/browser/{call-manager-XRRCAVLI.mjs → call-manager-BCKLI4QD.mjs} +7 -7
- package/dist/lib/browser/{call-manager-XRRCAVLI.mjs.map → call-manager-BCKLI4QD.mjs.map} +1 -1
- package/dist/lib/browser/chunk-2MUYQOQE.mjs +23 -0
- package/dist/lib/browser/{chunk-2CWJBXBH.mjs.map → chunk-2MUYQOQE.mjs.map} +3 -3
- package/dist/lib/browser/chunk-B7YQ7QR2.mjs +376 -0
- package/dist/lib/browser/chunk-B7YQ7QR2.mjs.map +7 -0
- package/dist/lib/browser/{chunk-ZJ7QBXK6.mjs → chunk-CMCVHULC.mjs} +17 -15
- package/dist/lib/browser/chunk-CMCVHULC.mjs.map +7 -0
- package/dist/lib/browser/{chunk-GERVMFQW.mjs → chunk-CP7E2HRE.mjs} +2 -2
- package/dist/lib/browser/chunk-CP7E2HRE.mjs.map +7 -0
- package/dist/lib/browser/{chunk-X5PIP5YR.mjs → chunk-HDEQRBOC.mjs} +37 -5
- package/dist/lib/{node-esm/chunk-SED3O2XO.mjs.map → browser/chunk-HDEQRBOC.mjs.map} +4 -4
- package/dist/lib/browser/chunk-L326LSNS.mjs +18 -0
- package/dist/lib/browser/chunk-L326LSNS.mjs.map +7 -0
- package/dist/lib/browser/{chunk-EV4JWI7L.mjs → chunk-T4KJ5JR4.mjs} +5 -7
- package/dist/lib/browser/chunk-T4KJ5JR4.mjs.map +7 -0
- package/dist/lib/browser/chunk-VJMKS4CZ.mjs +619 -0
- package/dist/lib/browser/chunk-VJMKS4CZ.mjs.map +7 -0
- package/dist/lib/browser/{chunk-DW7JD64V.mjs → chunk-VTYX3SIM.mjs} +26 -16
- package/dist/lib/browser/chunk-VTYX3SIM.mjs.map +7 -0
- package/dist/lib/browser/{chunk-JGKMMI65.mjs → chunk-XYUJXHYV.mjs} +54 -4
- package/dist/lib/browser/chunk-XYUJXHYV.mjs.map +7 -0
- package/dist/lib/browser/{chunk-TUFWPOVS.mjs → chunk-ZCEU5K23.mjs} +460 -268
- package/dist/lib/browser/chunk-ZCEU5K23.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +22 -13
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-resolver-DCY4P4OX.mjs → intent-resolver-VOQD3TQ2.mjs} +73 -15
- package/dist/lib/browser/intent-resolver-VOQD3TQ2.mjs.map +7 -0
- package/dist/lib/browser/{markdown-WZSXCEZJ.mjs → markdown-R6MGRIA6.mjs} +6 -6
- package/dist/lib/browser/{markdown-WZSXCEZJ.mjs.map → markdown-R6MGRIA6.mjs.map} +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react-root-UMSBTN6H.mjs +28 -0
- package/dist/lib/browser/react-root-UMSBTN6H.mjs.map +7 -0
- package/dist/lib/browser/{react-surface-PYAMIADB.mjs → react-surface-SXMQEWKE.mjs} +22 -22
- package/dist/lib/browser/react-surface-SXMQEWKE.mjs.map +7 -0
- package/dist/lib/browser/{settings-AC6YSASL.mjs → settings-TCNF54PN.mjs} +5 -5
- package/dist/lib/browser/{settings-AC6YSASL.mjs.map → settings-TCNF54PN.mjs.map} +1 -1
- package/dist/lib/browser/{state-2T4KDWBX.mjs → state-ZQ4IPOJT.mjs} +5 -5
- package/dist/lib/browser/{state-2T4KDWBX.mjs.map → state-ZQ4IPOJT.mjs.map} +1 -1
- package/dist/lib/browser/toolkit-JF4B4QIO.mjs +84 -0
- package/dist/lib/browser/toolkit-JF4B4QIO.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +2 -2
- package/dist/lib/node-esm/ChannelContainer-OXC6BTU7.mjs +17 -0
- package/dist/lib/node-esm/{ChatContainer-2CT4PJ7I.mjs → ChatContainer-SH6LTFQL.mjs} +6 -6
- package/dist/lib/node-esm/{app-graph-builder-OLSJVCWY.mjs → app-graph-builder-DMPT3MY6.mjs} +17 -17
- package/dist/lib/node-esm/app-graph-builder-DMPT3MY6.mjs.map +7 -0
- package/dist/lib/node-esm/{call-manager-EI7FXRAU.mjs → call-manager-Q7RY2YP4.mjs} +7 -7
- package/dist/lib/node-esm/{call-manager-EI7FXRAU.mjs.map → call-manager-Q7RY2YP4.mjs.map} +1 -1
- package/dist/lib/node-esm/{chunk-YIDU3DXK.mjs → chunk-2KZ4ODHU.mjs} +17 -15
- package/dist/lib/node-esm/chunk-2KZ4ODHU.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-SED3O2XO.mjs → chunk-2MMJF7DW.mjs} +37 -5
- package/dist/lib/node-esm/chunk-2MMJF7DW.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-QBHKLWGR.mjs → chunk-2V3WSLUZ.mjs} +54 -4
- package/dist/lib/node-esm/chunk-2V3WSLUZ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-57XR3LEF.mjs → chunk-ABUFOZVX.mjs} +2 -2
- package/dist/lib/node-esm/chunk-ABUFOZVX.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XVKWHTH4.mjs → chunk-BAMZXJS4.mjs} +26 -16
- package/dist/lib/node-esm/chunk-BAMZXJS4.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-BTGKI5IK.mjs +377 -0
- package/dist/lib/node-esm/chunk-BTGKI5IK.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-GZ4WL2IS.mjs +25 -0
- package/dist/lib/node-esm/{chunk-6CRHHOST.mjs.map → chunk-GZ4WL2IS.mjs.map} +3 -3
- package/dist/lib/node-esm/chunk-LCHTNRK7.mjs +19 -0
- package/dist/lib/node-esm/chunk-LCHTNRK7.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-NHSIAEDW.mjs +620 -0
- package/dist/lib/node-esm/chunk-NHSIAEDW.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-GRLRWTRU.mjs → chunk-OBVAURUU.mjs} +5 -7
- package/dist/lib/node-esm/chunk-OBVAURUU.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-4TME3BR4.mjs → chunk-TIPIOH2J.mjs} +460 -268
- package/dist/lib/node-esm/chunk-TIPIOH2J.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +22 -13
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/{intent-resolver-QGTPU6QB.mjs → intent-resolver-AKVH66PH.mjs} +73 -15
- package/dist/lib/node-esm/intent-resolver-AKVH66PH.mjs.map +7 -0
- package/dist/lib/node-esm/{markdown-3MZXUGUA.mjs → markdown-MYGTDXT6.mjs} +6 -6
- package/dist/lib/node-esm/{markdown-3MZXUGUA.mjs.map → markdown-MYGTDXT6.mjs.map} +1 -1
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/react-root-W6AVTL5M.mjs +29 -0
- package/dist/lib/node-esm/react-root-W6AVTL5M.mjs.map +7 -0
- package/dist/lib/node-esm/{react-surface-UJFCSFNO.mjs → react-surface-NLSZJGMO.mjs} +22 -22
- package/dist/lib/node-esm/react-surface-NLSZJGMO.mjs.map +7 -0
- package/dist/lib/node-esm/{settings-N52O7MLS.mjs → settings-ZQHGVFBY.mjs} +5 -5
- package/dist/lib/node-esm/{settings-N52O7MLS.mjs.map → settings-ZQHGVFBY.mjs.map} +1 -1
- package/dist/lib/node-esm/{state-62TQKQVB.mjs → state-FSLLJ5TZ.mjs} +5 -5
- package/dist/lib/node-esm/{state-62TQKQVB.mjs.map → state-FSLLJ5TZ.mjs.map} +1 -1
- package/dist/lib/node-esm/toolkit-DHPKJITO.mjs +85 -0
- package/dist/lib/node-esm/toolkit-DHPKJITO.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +2 -2
- package/dist/types/src/ThreadPlugin.d.ts +1 -1
- package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
- package/dist/types/src/calls/media-manager.d.ts +1 -1
- package/dist/types/src/calls/media-manager.d.ts.map +1 -1
- package/dist/types/src/calls/types.d.ts.map +1 -1
- package/dist/types/src/calls/util/calls-service.d.ts +3 -1
- package/dist/types/src/calls/util/calls-service.d.ts.map +1 -1
- package/dist/types/src/calls/util/stub-media-streams.d.ts.map +1 -1
- package/dist/types/src/calls-service.stories.d.ts +10 -9
- package/dist/types/src/calls-service.stories.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/call-manager.d.ts +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +11 -10
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/markdown.d.ts +1 -1
- package/dist/types/src/capabilities/react-root.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/settings.d.ts +1 -1
- package/dist/types/src/capabilities/state.d.ts +2 -2
- package/dist/types/src/capabilities/toolkit.d.ts +6 -0
- package/dist/types/src/capabilities/toolkit.d.ts.map +1 -0
- package/dist/types/src/components/CallDebugPanel.d.ts +7 -0
- package/dist/types/src/components/CallDebugPanel.d.ts.map +1 -1
- package/dist/types/src/components/ChannelContainer.stories.d.ts +89 -5
- package/dist/types/src/components/ChannelContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/Chat.stories.d.ts +91 -5
- package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
- package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
- package/dist/types/src/components/Comments.stories.d.ts +156 -4
- package/dist/types/src/components/Comments.stories.d.ts.map +1 -1
- package/dist/types/src/components/CommentsThreadContainer.d.ts +2 -2
- package/dist/types/src/components/CommentsThreadContainer.d.ts.map +1 -1
- package/dist/types/src/components/Media/VideoObject.d.ts +2 -2
- package/dist/types/src/components/Media/VideoObject.d.ts.map +1 -1
- package/dist/types/src/components/Media/VideoObject.stories.d.ts +18 -4
- package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +1 -1
- package/dist/types/src/components/MessageContainer.d.ts +4 -1
- package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
- package/dist/types/src/components/Participant/Participant.d.ts.map +1 -1
- package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts +155 -3
- package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +157 -4
- package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +1 -1
- package/dist/types/src/components/ThreadComplementary.d.ts.map +1 -1
- package/dist/types/src/components/ThreadSettings.d.ts +1 -1
- package/dist/types/src/components/ThreadSettings.d.ts.map +1 -1
- package/dist/types/src/components/command-extension.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +1 -0
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts +2 -0
- package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts.map +1 -0
- package/dist/types/src/hooks/useVideoStreamTrack.d.ts +1 -1
- package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +1 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +3 -1
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +126 -111
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +259 -174
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +60 -58
- package/src/ThreadPlugin.tsx +128 -122
- package/src/calls/call-manager.ts +1 -1
- package/src/calls/media-manager.ts +58 -32
- package/src/calls/types.ts +7 -3
- package/src/calls/util/calls-service.ts +61 -11
- package/src/calls/util/stub-media-streams.ts +60 -3
- package/src/calls-service.stories.tsx +76 -63
- package/src/capabilities/app-graph-builder.ts +13 -10
- package/src/capabilities/capabilities.ts +5 -5
- package/src/capabilities/index.ts +1 -0
- package/src/capabilities/intent-resolver.ts +39 -6
- package/src/capabilities/react-root.tsx +2 -2
- package/src/capabilities/react-surface.tsx +9 -9
- package/src/capabilities/toolkit.ts +82 -0
- package/src/components/Call/Toolbar.tsx +4 -4
- package/src/components/CallDebugPanel.tsx +108 -49
- package/src/components/ChannelContainer.stories.tsx +9 -9
- package/src/components/ChannelContainer.tsx +1 -1
- package/src/components/Chat.stories.tsx +31 -29
- package/src/components/ChatContainer.tsx +4 -1
- package/src/components/Comments.stories.tsx +33 -35
- package/src/components/CommentsThreadContainer.tsx +8 -7
- package/src/components/Media/VideoObject.stories.tsx +35 -28
- package/src/components/MessageContainer.tsx +40 -7
- package/src/components/Participant/Participant.tsx +13 -7
- package/src/components/ResponsiveGrid/ResponsiveContainer.stories.tsx +5 -6
- package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +41 -40
- package/src/components/ThreadComplementary.tsx +36 -6
- package/src/components/ThreadSettings.tsx +6 -7
- package/src/components/command-extension.ts +4 -1
- package/src/components/testing.ts +22 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useBlackCanvasStreamTrack.tsx +27 -0
- package/src/hooks/useVideoStreamTrack.tsx +6 -3
- package/src/meta.ts +3 -4
- package/src/testing/stories.ts +1 -1
- package/src/translations.ts +3 -1
- package/src/types/schema.ts +1 -1
- package/src/types/types.ts +21 -13
- package/src/typings/peermetrics-webrtc-stats.d.ts +17 -1
- package/src/util.ts +1 -1
- package/dist/lib/browser/ChannelContainer-O2SFQJU7.mjs +0 -16
- package/dist/lib/browser/ChatContainer-PVT3DUZJ.mjs +0 -15
- package/dist/lib/browser/app-graph-builder-AF3M7UWN.mjs.map +0 -7
- package/dist/lib/browser/chunk-2CWJBXBH.mjs +0 -21
- package/dist/lib/browser/chunk-4APCDRSH.mjs +0 -18
- package/dist/lib/browser/chunk-4APCDRSH.mjs.map +0 -7
- package/dist/lib/browser/chunk-DW7JD64V.mjs.map +0 -7
- package/dist/lib/browser/chunk-EV4JWI7L.mjs.map +0 -7
- package/dist/lib/browser/chunk-FY4ZRD5X.mjs +0 -367
- package/dist/lib/browser/chunk-FY4ZRD5X.mjs.map +0 -7
- package/dist/lib/browser/chunk-GERVMFQW.mjs.map +0 -7
- package/dist/lib/browser/chunk-J3JO5NWO.mjs +0 -477
- package/dist/lib/browser/chunk-J3JO5NWO.mjs.map +0 -7
- package/dist/lib/browser/chunk-JGKMMI65.mjs.map +0 -7
- package/dist/lib/browser/chunk-TUFWPOVS.mjs.map +0 -7
- package/dist/lib/browser/chunk-X5PIP5YR.mjs.map +0 -7
- package/dist/lib/browser/chunk-ZJ7QBXK6.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-DCY4P4OX.mjs.map +0 -7
- package/dist/lib/browser/react-root-QXPALOUQ.mjs +0 -28
- package/dist/lib/browser/react-root-QXPALOUQ.mjs.map +0 -7
- package/dist/lib/browser/react-surface-PYAMIADB.mjs.map +0 -7
- package/dist/lib/node-esm/ChannelContainer-B2ZGAE4P.mjs +0 -17
- package/dist/lib/node-esm/app-graph-builder-OLSJVCWY.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-4TME3BR4.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-57XR3LEF.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-6CRHHOST.mjs +0 -23
- package/dist/lib/node-esm/chunk-BF4UKS55.mjs +0 -368
- package/dist/lib/node-esm/chunk-BF4UKS55.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-GRLRWTRU.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-PYTVBN5J.mjs +0 -19
- package/dist/lib/node-esm/chunk-PYTVBN5J.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-QBHKLWGR.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-VNG6M2IY.mjs +0 -478
- package/dist/lib/node-esm/chunk-VNG6M2IY.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XVKWHTH4.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YIDU3DXK.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-QGTPU6QB.mjs.map +0 -7
- package/dist/lib/node-esm/react-root-7ZFJYVUZ.mjs +0 -29
- package/dist/lib/node-esm/react-root-7ZFJYVUZ.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-UJFCSFNO.mjs.map +0 -7
- /package/dist/lib/browser/{ChannelContainer-O2SFQJU7.mjs.map → ChannelContainer-BGDGZHV4.mjs.map} +0 -0
- /package/dist/lib/browser/{ChatContainer-PVT3DUZJ.mjs.map → ChatContainer-75KJZ4XR.mjs.map} +0 -0
- /package/dist/lib/node-esm/{ChannelContainer-B2ZGAE4P.mjs.map → ChannelContainer-OXC6BTU7.mjs.map} +0 -0
- /package/dist/lib/node-esm/{ChatContainer-2CT4PJ7I.mjs.map → ChatContainer-SH6LTFQL.mjs.map} +0 -0
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
7
|
-
import { type Meta } from '@storybook/react-vite';
|
|
8
|
-
import React, { useEffect, useState } from 'react';
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import React, { useState } from 'react';
|
|
9
7
|
|
|
10
8
|
import { Capabilities, IntentPlugin, contributes, createSurface } from '@dxos/app-framework';
|
|
11
9
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
@@ -15,9 +13,11 @@ import { useClient } from '@dxos/react-client';
|
|
|
15
13
|
import { type Space } from '@dxos/react-client/echo';
|
|
16
14
|
import { useIdentity } from '@dxos/react-client/halo';
|
|
17
15
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
16
|
+
import { useAsyncEffect } from '@dxos/react-ui';
|
|
17
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
18
18
|
import { Thread } from '@dxos/react-ui-thread';
|
|
19
19
|
import { DataType } from '@dxos/schema';
|
|
20
|
-
import {
|
|
20
|
+
import { render } from '@dxos/storybook-utils';
|
|
21
21
|
|
|
22
22
|
import { translations } from '../translations';
|
|
23
23
|
import { ChannelType, ThreadType } from '../types';
|
|
@@ -26,25 +26,23 @@ import { ChatContainer } from './ChatContainer';
|
|
|
26
26
|
|
|
27
27
|
faker.seed(1);
|
|
28
28
|
|
|
29
|
-
const
|
|
29
|
+
const DefaultStory = () => {
|
|
30
30
|
const client = useClient();
|
|
31
31
|
const identity = useIdentity();
|
|
32
32
|
const [space, setSpace] = useState<Space>();
|
|
33
33
|
const [channel, setChannel] = useState<ChannelType | null>();
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
useAsyncEffect(async () => {
|
|
36
36
|
if (identity) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Obj.make(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
setChannel(channel);
|
|
47
|
-
});
|
|
37
|
+
const space = await client.spaces.create();
|
|
38
|
+
const channel = space.db.add(
|
|
39
|
+
Obj.make(ChannelType, {
|
|
40
|
+
defaultThread: Ref.make(Obj.make(ThreadType, { messages: [], status: 'active' })),
|
|
41
|
+
threads: [],
|
|
42
|
+
}),
|
|
43
|
+
);
|
|
44
|
+
setSpace(space);
|
|
45
|
+
setChannel(channel);
|
|
48
46
|
}
|
|
49
47
|
}, [identity]);
|
|
50
48
|
|
|
@@ -53,19 +51,18 @@ const Story = () => {
|
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
return (
|
|
56
|
-
<main className='max-is-prose mli-auto bs-dvh overflow-hidden'>
|
|
54
|
+
<main className='is-full max-is-prose mli-auto bs-dvh overflow-hidden'>
|
|
57
55
|
<ChatContainer space={space} thread={channel.defaultThread.target} />
|
|
58
56
|
</main>
|
|
59
57
|
);
|
|
60
58
|
};
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const meta: Meta<typeof Thread.Root> = {
|
|
60
|
+
const meta = {
|
|
65
61
|
title: 'plugins/plugin-thread/Chat',
|
|
66
|
-
component: Thread.Root,
|
|
67
|
-
render: ()
|
|
62
|
+
component: Thread.Root as any,
|
|
63
|
+
render: render(DefaultStory),
|
|
68
64
|
decorators: [
|
|
65
|
+
withTheme,
|
|
69
66
|
withPluginManager({
|
|
70
67
|
plugins: [IntentPlugin()],
|
|
71
68
|
capabilities: [
|
|
@@ -79,11 +76,16 @@ const meta: Meta<typeof Thread.Root> = {
|
|
|
79
76
|
),
|
|
80
77
|
],
|
|
81
78
|
}),
|
|
82
|
-
|
|
83
|
-
withLayout({ fullscreen: true }),
|
|
84
|
-
withClientProvider({ createSpace: true, types: [ThreadType, DataType.Message] }),
|
|
79
|
+
withClientProvider({ createSpace: true, types: [ThreadType, ChannelType, DataType.Message] }),
|
|
85
80
|
],
|
|
86
|
-
parameters: {
|
|
87
|
-
|
|
81
|
+
parameters: {
|
|
82
|
+
layout: 'fullscreen',
|
|
83
|
+
translations,
|
|
84
|
+
},
|
|
85
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
88
86
|
|
|
89
87
|
export default meta;
|
|
88
|
+
|
|
89
|
+
type Story = StoryObj<typeof meta>;
|
|
90
|
+
|
|
91
|
+
export const Default: Story = {};
|
|
@@ -112,7 +112,10 @@ export const ChatContainer = ({ space, thread, context, current, autoFocusTextbo
|
|
|
112
112
|
<Thread.Root
|
|
113
113
|
current={current}
|
|
114
114
|
id={id}
|
|
115
|
-
classNames=
|
|
115
|
+
classNames={[
|
|
116
|
+
'bs-full is-full max-is-prose mli-auto grid-rows-[1fr_min-content_min-content] overflow-hidden',
|
|
117
|
+
'transition-[padding-block-end] [[data-sidebar-inline-start-state=open]_&]:lg:pbe-0',
|
|
118
|
+
]}
|
|
116
119
|
>
|
|
117
120
|
<ScrollArea.Root classNames='col-span-2'>
|
|
118
121
|
<ScrollArea.Viewport classNames='overflow-anchored after:overflow-anchor after:block after:bs-px after:-mbs-px [&>div]:min-bs-full [&>div]:!grid [&>div]:grid-rows-[1fr_0]'>
|
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
7
|
-
import { type Meta } from '@storybook/react-vite';
|
|
8
|
-
import React, { useEffect } from 'react';
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import React from 'react';
|
|
9
7
|
|
|
10
8
|
import { IntentPlugin } from '@dxos/app-framework';
|
|
11
9
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
@@ -14,14 +12,16 @@ import { ClientPlugin } from '@dxos/plugin-client';
|
|
|
14
12
|
import { faker } from '@dxos/random';
|
|
15
13
|
import { useQuery, useSpace } from '@dxos/react-client/echo';
|
|
16
14
|
import { useIdentity } from '@dxos/react-client/halo';
|
|
15
|
+
import { useAsyncEffect } from '@dxos/react-ui';
|
|
16
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
17
17
|
import { AnchoredTo, DataType } from '@dxos/schema';
|
|
18
|
-
import {
|
|
18
|
+
import { render } from '@dxos/storybook-utils';
|
|
19
19
|
|
|
20
20
|
import { translations } from '../translations';
|
|
21
21
|
import { ThreadType } from '../types';
|
|
22
22
|
|
|
23
23
|
import { CommentsContainer } from './CommentsContainer';
|
|
24
|
-
import { createCommentThread } from './testing';
|
|
24
|
+
import { createCommentThread, createProposalThread } from './testing';
|
|
25
25
|
|
|
26
26
|
faker.seed(1);
|
|
27
27
|
|
|
@@ -30,27 +30,25 @@ const DefaultStory = () => {
|
|
|
30
30
|
const space = useSpace();
|
|
31
31
|
const anchors = useQuery(space, Query.type(AnchoredTo));
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
useAsyncEffect(async () => {
|
|
34
34
|
if (identity && space) {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Relation.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return () => clearTimeout(t);
|
|
35
|
+
const object = space.db.add(Obj.make(Type.Expando, {}));
|
|
36
|
+
const thread1 = space.db.add(createCommentThread(identity));
|
|
37
|
+
const thread2 = space.db.add(createProposalThread(identity));
|
|
38
|
+
space.db.add(
|
|
39
|
+
Relation.make(AnchoredTo, {
|
|
40
|
+
[Relation.Source]: thread1,
|
|
41
|
+
[Relation.Target]: object,
|
|
42
|
+
anchor: 'test',
|
|
43
|
+
}),
|
|
44
|
+
);
|
|
45
|
+
space.db.add(
|
|
46
|
+
Relation.make(AnchoredTo, {
|
|
47
|
+
[Relation.Source]: thread2,
|
|
48
|
+
[Relation.Target]: object,
|
|
49
|
+
anchor: 'test',
|
|
50
|
+
}),
|
|
51
|
+
);
|
|
54
52
|
}
|
|
55
53
|
}, [identity, space]);
|
|
56
54
|
|
|
@@ -58,19 +56,17 @@ const DefaultStory = () => {
|
|
|
58
56
|
return null;
|
|
59
57
|
}
|
|
60
58
|
|
|
61
|
-
return
|
|
62
|
-
<div className='w-[30rem] overflow-y-auto bg-baseSurface'>
|
|
63
|
-
<CommentsContainer anchors={anchors} onThreadDelete={console.log} />
|
|
64
|
-
</div>
|
|
65
|
-
);
|
|
59
|
+
return <CommentsContainer anchors={anchors} onThreadDelete={console.log} onAcceptProposal={console.log} />;
|
|
66
60
|
};
|
|
67
61
|
|
|
68
|
-
const meta
|
|
62
|
+
const meta = {
|
|
69
63
|
title: 'plugins/plugin-thread/Comments',
|
|
70
64
|
render: render(DefaultStory),
|
|
71
65
|
decorators: [
|
|
72
66
|
withTheme,
|
|
73
|
-
withLayout({
|
|
67
|
+
withLayout({ container: 'column', scroll: true }),
|
|
68
|
+
// TODO(wittjosiah): This shouldn't depend on app framework (use withClientProvider instead).
|
|
69
|
+
// Currently this is required due to useOnEditAnalytics.
|
|
74
70
|
withPluginManager({
|
|
75
71
|
plugins: [
|
|
76
72
|
IntentPlugin(),
|
|
@@ -86,8 +82,10 @@ const meta: Meta = {
|
|
|
86
82
|
parameters: {
|
|
87
83
|
translations,
|
|
88
84
|
},
|
|
89
|
-
}
|
|
85
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
90
86
|
|
|
91
87
|
export default meta;
|
|
92
88
|
|
|
93
|
-
|
|
89
|
+
type Story = StoryObj<typeof meta>;
|
|
90
|
+
|
|
91
|
+
export const Default: Story = {};
|
|
@@ -20,10 +20,7 @@ import { type ThreadType } from '../types';
|
|
|
20
20
|
import { getMessageMetadata } from '../util';
|
|
21
21
|
|
|
22
22
|
import { command } from './command-extension';
|
|
23
|
-
import { MessageContainer } from './MessageContainer';
|
|
24
|
-
|
|
25
|
-
// TODO(burdon): Remove need for p-1.
|
|
26
|
-
export const commentControlClassNames = '!p-1 transition-opacity';
|
|
23
|
+
import { MessageContainer, buttonClassNames, buttonGroupClassNames } from './MessageContainer';
|
|
27
24
|
|
|
28
25
|
export type CommentsThreadContainerProps = {
|
|
29
26
|
anchor: AnchoredTo;
|
|
@@ -32,6 +29,7 @@ export type CommentsThreadContainerProps = {
|
|
|
32
29
|
onResolve?: (anchor: AnchoredTo) => void;
|
|
33
30
|
onMessageDelete?: (anchor: AnchoredTo, messageId: string) => void;
|
|
34
31
|
onThreadDelete?: (anchor: AnchoredTo) => void;
|
|
32
|
+
onAcceptProposal?: (anchor: AnchoredTo, messageId: string) => void;
|
|
35
33
|
} & Pick<ThreadRootProps, 'current'>;
|
|
36
34
|
|
|
37
35
|
export const CommentsThreadContainer = ({
|
|
@@ -42,6 +40,7 @@ export const CommentsThreadContainer = ({
|
|
|
42
40
|
onResolve,
|
|
43
41
|
onMessageDelete,
|
|
44
42
|
onThreadDelete,
|
|
43
|
+
onAcceptProposal,
|
|
45
44
|
}: CommentsThreadContainerProps) => {
|
|
46
45
|
const { t } = useTranslation(meta.id);
|
|
47
46
|
const identity = useIdentity()!;
|
|
@@ -76,6 +75,7 @@ export const CommentsThreadContainer = ({
|
|
|
76
75
|
const handleResolve = useCallback(() => onResolve?.(anchor), [onResolve, anchor]);
|
|
77
76
|
const handleMessageDelete = useCallback((id: string) => onMessageDelete?.(anchor, id), [onMessageDelete, anchor]);
|
|
78
77
|
const handleThreadDelete = useCallback(() => onThreadDelete?.(anchor), [onThreadDelete, anchor]);
|
|
78
|
+
const handleAcceptProposal = useCallback((id: string) => onAcceptProposal?.(anchor, id), [onAcceptProposal, anchor]);
|
|
79
79
|
|
|
80
80
|
const handleComment: MessageTextboxProps['onSend'] = useCallback(() => {
|
|
81
81
|
if (!messageRef.current) {
|
|
@@ -113,7 +113,7 @@ export const CommentsThreadContainer = ({
|
|
|
113
113
|
) : (
|
|
114
114
|
<Thread.Header>{thread.name}</Thread.Header>
|
|
115
115
|
)}
|
|
116
|
-
<div
|
|
116
|
+
<div role='none' className={buttonGroupClassNames}>
|
|
117
117
|
{thread.status === 'staged' && <Tag palette='neutral'>{t('draft button')}</Tag>}
|
|
118
118
|
{onResolve && !(thread?.status === 'staged') && (
|
|
119
119
|
<IconButton
|
|
@@ -122,7 +122,7 @@ export const CommentsThreadContainer = ({
|
|
|
122
122
|
icon={thread?.status === 'resolved' ? 'ph--check--fill' : 'ph--check--regular'}
|
|
123
123
|
iconOnly
|
|
124
124
|
label={t('resolve thread label')}
|
|
125
|
-
classNames={[
|
|
125
|
+
classNames={[buttonClassNames, thread?.status !== 'resolved' && hoverableControlItem]}
|
|
126
126
|
onClick={handleResolve}
|
|
127
127
|
/>
|
|
128
128
|
)}
|
|
@@ -133,7 +133,7 @@ export const CommentsThreadContainer = ({
|
|
|
133
133
|
icon='ph--x--regular'
|
|
134
134
|
iconOnly
|
|
135
135
|
label={t('delete thread label')}
|
|
136
|
-
classNames={[
|
|
136
|
+
classNames={[buttonClassNames, hoverableControlItem]}
|
|
137
137
|
onClick={handleThreadDelete}
|
|
138
138
|
/>
|
|
139
139
|
)}
|
|
@@ -148,6 +148,7 @@ export const CommentsThreadContainer = ({
|
|
|
148
148
|
message={message}
|
|
149
149
|
members={members}
|
|
150
150
|
onDelete={handleMessageDelete}
|
|
151
|
+
onAcceptProposal={handleAcceptProposal}
|
|
151
152
|
/>
|
|
152
153
|
))}
|
|
153
154
|
|
|
@@ -2,48 +2,55 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
7
|
-
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
5
|
+
import { type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React, { useEffect, useState } from 'react';
|
|
9
7
|
|
|
10
8
|
import { scheduleTask } from '@dxos/async';
|
|
11
9
|
import { Context } from '@dxos/context';
|
|
12
10
|
import { log } from '@dxos/log';
|
|
13
|
-
import {
|
|
11
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
14
12
|
|
|
15
13
|
import { getUserMediaTrack } from '../../calls';
|
|
16
14
|
import { ResponsiveContainer } from '../ResponsiveGrid';
|
|
17
15
|
|
|
18
|
-
import { VideoObject } from './VideoObject';
|
|
16
|
+
import { VideoObject, type VideoObjectProps } from './VideoObject';
|
|
19
17
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const ctx = new Context();
|
|
28
|
-
scheduleTask(ctx, async () => {
|
|
18
|
+
const DefaultStory = (props: VideoObjectProps) => {
|
|
19
|
+
log.info('render');
|
|
20
|
+
const [videoStream, setVideoStream] = useState<MediaStream>();
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
const ctx = new Context();
|
|
23
|
+
scheduleTask(ctx, async () => {
|
|
24
|
+
try {
|
|
29
25
|
const stream = new MediaStream();
|
|
30
26
|
stream.addTrack(await getUserMediaTrack('videoinput'));
|
|
31
27
|
setVideoStream(stream);
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
28
|
+
} catch (err) {
|
|
29
|
+
log.catch(err);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return () => {
|
|
34
|
+
void ctx.dispose();
|
|
35
|
+
videoStream?.getTracks().forEach((track) => track.stop());
|
|
36
|
+
};
|
|
37
|
+
}, []);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<ResponsiveContainer>
|
|
41
|
+
<VideoObject videoStream={videoStream} flip {...props} />
|
|
42
|
+
</ResponsiveContainer>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const meta = {
|
|
47
|
+
title: 'plugins/plugin-thread/VideoObject',
|
|
48
|
+
component: VideoObject,
|
|
49
|
+
render: DefaultStory,
|
|
50
|
+
decorators: [withTheme],
|
|
51
|
+
parameters: {
|
|
52
|
+
layout: 'fullscreen',
|
|
45
53
|
},
|
|
46
|
-
decorators: [withTheme, withLayout({ fullscreen: true, classNames: 'justify-center' })],
|
|
47
54
|
};
|
|
48
55
|
|
|
49
56
|
export default meta;
|
|
@@ -21,16 +21,25 @@ import { meta } from '../meta';
|
|
|
21
21
|
import { getMessageMetadata } from '../util';
|
|
22
22
|
|
|
23
23
|
import { command } from './command-extension';
|
|
24
|
-
|
|
24
|
+
|
|
25
|
+
export const buttonGroupClassNames = 'flex flex-row items-center gap-0.5 pie-2';
|
|
26
|
+
export const buttonClassNames = '!p-1 transition-opacity';
|
|
25
27
|
|
|
26
28
|
export type MessageContainerProps = {
|
|
27
29
|
message: DataType.Message;
|
|
28
30
|
members: SpaceMember[];
|
|
29
31
|
editable?: boolean;
|
|
30
32
|
onDelete?: (id: string) => void;
|
|
33
|
+
onAcceptProposal?: (id: string) => void;
|
|
31
34
|
};
|
|
32
35
|
|
|
33
|
-
export const MessageContainer = ({
|
|
36
|
+
export const MessageContainer = ({
|
|
37
|
+
message,
|
|
38
|
+
members,
|
|
39
|
+
editable = false,
|
|
40
|
+
onDelete,
|
|
41
|
+
onAcceptProposal,
|
|
42
|
+
}: MessageContainerProps) => {
|
|
34
43
|
const { t } = useTranslation(meta.id);
|
|
35
44
|
const senderIdentity = members.find(
|
|
36
45
|
(member) =>
|
|
@@ -40,8 +49,11 @@ export const MessageContainer = ({ message, members, editable = false, onDelete
|
|
|
40
49
|
const messageMetadata = getMessageMetadata(message.id, senderIdentity);
|
|
41
50
|
const userIsAuthor = useIdentity()?.did === messageMetadata.authorId;
|
|
42
51
|
const [editing, setEditing] = useState(false);
|
|
52
|
+
const handleEdit = useCallback(() => setEditing((editing) => !editing), []);
|
|
43
53
|
const handleDelete = useCallback(() => onDelete?.(message.id), [message, onDelete]);
|
|
54
|
+
const handleAcceptProposal = useCallback(() => onAcceptProposal?.(message.id), [message, onAcceptProposal]);
|
|
44
55
|
const textBlock = message.blocks.find((block) => block._tag === 'text');
|
|
56
|
+
const proposalBlock = message.blocks.find((block) => block._tag === 'proposal');
|
|
45
57
|
const references = message.blocks.filter((block) => block._tag === 'reference').map((block) => block.reference);
|
|
46
58
|
|
|
47
59
|
useOnEditAnalytics(message, textBlock, !!editing);
|
|
@@ -49,7 +61,7 @@ export const MessageContainer = ({ message, members, editable = false, onDelete
|
|
|
49
61
|
return (
|
|
50
62
|
<MessageRoot {...messageMetadata} classNames={[hoverableControls, hoverableFocusedWithinControls]}>
|
|
51
63
|
<MessageHeading authorName={messageMetadata.authorName} timestamp={messageMetadata.timestamp}>
|
|
52
|
-
<div
|
|
64
|
+
<div role='none' className={buttonGroupClassNames}>
|
|
53
65
|
{userIsAuthor && editable && (
|
|
54
66
|
<IconButton
|
|
55
67
|
data-testid={editing ? 'thread.message.save' : 'thread.message.edit'}
|
|
@@ -57,8 +69,20 @@ export const MessageContainer = ({ message, members, editable = false, onDelete
|
|
|
57
69
|
icon={editing ? 'ph--check--regular' : 'ph--pencil-simple--regular'}
|
|
58
70
|
iconOnly
|
|
59
71
|
label={t(editing ? 'save message label' : 'edit message label')}
|
|
60
|
-
classNames={[
|
|
61
|
-
onClick={
|
|
72
|
+
classNames={[buttonClassNames, hoverableControlItem]}
|
|
73
|
+
onClick={handleEdit}
|
|
74
|
+
/>
|
|
75
|
+
)}
|
|
76
|
+
{/* TODO(wittjosiah): Proposal controls should probably be hoisted to thread level. */}
|
|
77
|
+
{proposalBlock && onAcceptProposal && (
|
|
78
|
+
<IconButton
|
|
79
|
+
data-testid='thread.message.accept'
|
|
80
|
+
variant='ghost'
|
|
81
|
+
icon='ph--check--regular'
|
|
82
|
+
iconOnly
|
|
83
|
+
label={t('accept proposal label')}
|
|
84
|
+
classNames={[buttonClassNames, hoverableControlItem]}
|
|
85
|
+
onClick={handleAcceptProposal}
|
|
62
86
|
/>
|
|
63
87
|
)}
|
|
64
88
|
{onDelete && (
|
|
@@ -68,13 +92,14 @@ export const MessageContainer = ({ message, members, editable = false, onDelete
|
|
|
68
92
|
icon='ph--x--regular'
|
|
69
93
|
iconOnly
|
|
70
94
|
label={t('delete message label')}
|
|
71
|
-
classNames={[
|
|
72
|
-
onClick={
|
|
95
|
+
classNames={[buttonClassNames, hoverableControlItem]}
|
|
96
|
+
onClick={handleDelete}
|
|
73
97
|
/>
|
|
74
98
|
)}
|
|
75
99
|
</div>
|
|
76
100
|
</MessageHeading>
|
|
77
101
|
{textBlock && <TextboxBlock block={textBlock} isAuthor={userIsAuthor} editing={editing} />}
|
|
102
|
+
{proposalBlock && <ProposalBlock block={proposalBlock} />}
|
|
78
103
|
{Ref.Array.targets(references).map((reference, index) => (
|
|
79
104
|
<MessagePart key={index} part={reference} />
|
|
80
105
|
))}
|
|
@@ -133,6 +158,14 @@ const TextboxBlock = ({
|
|
|
133
158
|
return <div role='none' ref={parentRef} className='mie-4' {...focusAttributes} />;
|
|
134
159
|
};
|
|
135
160
|
|
|
161
|
+
const ProposalBlock = ({ block }: { block: DataType.MessageBlock.Proposal }) => {
|
|
162
|
+
return (
|
|
163
|
+
<div role='none' className='mie-4 italic'>
|
|
164
|
+
{block.text}
|
|
165
|
+
</div>
|
|
166
|
+
);
|
|
167
|
+
};
|
|
168
|
+
|
|
136
169
|
const MessageBlockObjectTile = forwardRef<HTMLDivElement, { subject: Obj.Any }>(({ subject }, forwardedRef) => {
|
|
137
170
|
// TODO(burdon): Use annotation to get title.
|
|
138
171
|
let title = (subject as any).name ?? (subject as any).title ?? (subject as any).type ?? 'Object';
|
|
@@ -17,15 +17,21 @@ export const Participant = memo(({ item: user, debug, ...props }: ResponsiveGrid
|
|
|
17
17
|
const call = useCapability(ThreadCapabilities.CallManager);
|
|
18
18
|
const isSelf: boolean = call.self.id !== undefined && user.id !== undefined && user.id.startsWith(call.self.id);
|
|
19
19
|
const isScreenshare = user.id?.endsWith(SCREENSHARE_SUFFIX);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
|
|
21
|
+
const pulledVideoStream =
|
|
22
|
+
!isSelf && isScreenshare && user.tracks?.screenshareEnabled
|
|
23
|
+
? call.getVideoStream(user.tracks?.screenshare as EncodedTrackName)
|
|
24
|
+
: !isSelf && !isScreenshare && user.tracks?.videoEnabled
|
|
25
|
+
? call.getVideoStream(user.tracks?.video as EncodedTrackName)
|
|
26
|
+
: undefined;
|
|
23
27
|
|
|
24
28
|
const videoStream = useMemo<MediaStream | undefined>(() => {
|
|
25
|
-
if (isSelf
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
if (isSelf) {
|
|
30
|
+
if (isScreenshare) {
|
|
31
|
+
return call.media.screenshareVideoStream;
|
|
32
|
+
} else if (!isScreenshare) {
|
|
33
|
+
return call.media.videoStream;
|
|
34
|
+
}
|
|
29
35
|
} else if (!isSelf) {
|
|
30
36
|
return pulledVideoStream;
|
|
31
37
|
}
|
|
@@ -2,26 +2,25 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React from 'react';
|
|
9
7
|
|
|
10
|
-
import {
|
|
8
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
11
9
|
|
|
12
10
|
import { translations } from '../../translations';
|
|
13
11
|
import { VideoObject as VideoObjectComponent } from '../Media';
|
|
14
12
|
|
|
15
13
|
import { ResponsiveContainer } from './ResponsiveContainer';
|
|
16
14
|
|
|
17
|
-
const meta
|
|
15
|
+
const meta = {
|
|
18
16
|
title: 'plugins/plugin-thread/ResponsiveContainer',
|
|
19
17
|
component: ResponsiveContainer,
|
|
20
|
-
decorators: [withTheme
|
|
18
|
+
decorators: [withTheme],
|
|
21
19
|
parameters: {
|
|
20
|
+
layout: 'fullscreen',
|
|
22
21
|
translations,
|
|
23
22
|
},
|
|
24
|
-
}
|
|
23
|
+
} satisfies Meta<typeof ResponsiveContainer>;
|
|
25
24
|
|
|
26
25
|
export default meta;
|
|
27
26
|
|
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React, { useEffect, useState } from 'react';
|
|
9
7
|
|
|
10
8
|
import { faker } from '@dxos/random';
|
|
11
|
-
import {
|
|
9
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
12
10
|
|
|
13
11
|
import { translations } from '../../translations';
|
|
14
12
|
|
|
@@ -57,46 +55,49 @@ const TestCell = ({ item, ...props }: ResponsiveGridItemProps<TestItem>) => {
|
|
|
57
55
|
|
|
58
56
|
type StoryProps = ResponsiveGridProps<TestItem> & { random?: boolean; autoHideGallery?: boolean };
|
|
59
57
|
|
|
60
|
-
const
|
|
58
|
+
const DefaultStory = (props: StoryProps) => {
|
|
59
|
+
const [pinned, setPinned] = useState<string | undefined>(
|
|
60
|
+
(props.pinned ?? props.items.length > 1) ? props.items[0]?.id : undefined,
|
|
61
|
+
);
|
|
62
|
+
const [items, setItems] = useState<TestItem[]>(props.items);
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (!props.random) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const interval = setInterval(() => {
|
|
69
|
+
setItems((items) => {
|
|
70
|
+
const p = Math.random();
|
|
71
|
+
if (p < 0.5) {
|
|
72
|
+
return items;
|
|
73
|
+
} else if (p < 0.99 && items.length > 1) {
|
|
74
|
+
return items.slice(0, -1);
|
|
75
|
+
} else {
|
|
76
|
+
return [...items, createItem(items[0]?.type)];
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}, 3_000);
|
|
80
|
+
|
|
81
|
+
return () => clearInterval(interval);
|
|
82
|
+
}, []);
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<div className='grid grow p-4'>
|
|
86
|
+
<ResponsiveGrid {...props} Cell={TestCell} items={items} pinned={pinned} onPinnedChange={setPinned} />
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const meta = {
|
|
61
92
|
title: 'plugins/plugin-thread/ResponsiveGrid',
|
|
62
|
-
component: ResponsiveGrid,
|
|
63
|
-
render:
|
|
64
|
-
|
|
65
|
-
(args.pinned ?? args.items.length > 1) ? args.items[0]?.id : undefined,
|
|
66
|
-
);
|
|
67
|
-
const [items, setItems] = useState<TestItem[]>(args.items);
|
|
68
|
-
useEffect(() => {
|
|
69
|
-
if (!args.random) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const interval = setInterval(() => {
|
|
74
|
-
setItems((items) => {
|
|
75
|
-
const p = Math.random();
|
|
76
|
-
if (p < 0.5) {
|
|
77
|
-
return items;
|
|
78
|
-
} else if (p < 0.99 && items.length > 1) {
|
|
79
|
-
return items.slice(0, -1);
|
|
80
|
-
} else {
|
|
81
|
-
return [...items, createItem(items[0]?.type)];
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
}, 3_000);
|
|
85
|
-
|
|
86
|
-
return () => clearInterval(interval);
|
|
87
|
-
}, []);
|
|
88
|
-
|
|
89
|
-
return (
|
|
90
|
-
<div className='grid grow p-4'>
|
|
91
|
-
<ResponsiveGrid {...args} Cell={TestCell} items={items} pinned={pinned} onPinnedChange={setPinned} />
|
|
92
|
-
</div>
|
|
93
|
-
);
|
|
94
|
-
},
|
|
95
|
-
decorators: [withTheme, withLayout({ fullscreen: true, classNames: 'justify-center' })],
|
|
93
|
+
component: ResponsiveGrid as any,
|
|
94
|
+
render: DefaultStory,
|
|
95
|
+
decorators: [withTheme],
|
|
96
96
|
parameters: {
|
|
97
|
+
layout: 'fullscreen',
|
|
97
98
|
translations,
|
|
98
99
|
},
|
|
99
|
-
}
|
|
100
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
100
101
|
|
|
101
102
|
const videoUrls = [
|
|
102
103
|
'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4',
|
|
@@ -118,7 +119,7 @@ const createItem = (type?: 'image' | 'video') => {
|
|
|
118
119
|
|
|
119
120
|
export default meta;
|
|
120
121
|
|
|
121
|
-
type Story = StoryObj<
|
|
122
|
+
type Story = StoryObj<typeof meta>;
|
|
122
123
|
|
|
123
124
|
// TODO(burdon): Story to join/leave repeatedly to test stable position.
|
|
124
125
|
|