@dxos/plugin-thread 0.8.3 → 0.8.4-main.c1de068
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-IY2UIRLF.mjs +16 -0
- package/dist/lib/browser/ChatContainer-AIGIWAUG.mjs +15 -0
- package/dist/lib/browser/{app-graph-builder-OY7R7EJP.mjs → app-graph-builder-N7BE5TYW.mjs} +6 -6
- package/dist/lib/browser/{call-manager-APQAZWHT.mjs → call-manager-NIPDYUVD.mjs} +6 -5
- package/dist/lib/browser/chunk-4OYAYON2.mjs +21 -0
- package/dist/lib/browser/chunk-6NSMBO3B.mjs +56 -0
- package/dist/lib/browser/chunk-6NSMBO3B.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5P5BH5GE.mjs → chunk-ERWASUQK.mjs} +66 -5
- package/dist/lib/browser/chunk-ERWASUQK.mjs.map +7 -0
- package/dist/lib/browser/{chunk-IIUTBDVB.mjs → chunk-EV4JWI7L.mjs} +2 -2
- package/dist/lib/browser/{chunk-AEXWNS6Z.mjs → chunk-GCLD5ESP.mjs} +14 -5
- package/dist/lib/browser/chunk-GCLD5ESP.mjs.map +7 -0
- package/dist/lib/browser/{chunk-JKQUJOTX.mjs → chunk-GERVMFQW.mjs} +2 -2
- package/dist/lib/browser/{chunk-XZKBN3NS.mjs → chunk-KWPRNHTK.mjs} +32 -31
- package/dist/lib/browser/chunk-KWPRNHTK.mjs.map +7 -0
- package/dist/lib/browser/{chunk-R5MDLUPC.mjs → chunk-LGSDKXPF.mjs} +3 -3
- package/dist/lib/browser/chunk-VUWC4IJM.mjs +479 -0
- package/dist/lib/browser/chunk-VUWC4IJM.mjs.map +7 -0
- package/dist/lib/browser/chunk-XLPJXUKO.mjs +367 -0
- package/dist/lib/browser/chunk-XLPJXUKO.mjs.map +7 -0
- package/dist/lib/browser/{chunk-4H4A264L.mjs → chunk-ZE7KWN36.mjs} +85 -124
- package/dist/lib/browser/chunk-ZE7KWN36.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +35 -41
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-resolver-FK2MDVDT.mjs → intent-resolver-JFGLZ6VI.mjs} +30 -14
- package/dist/lib/browser/intent-resolver-JFGLZ6VI.mjs.map +7 -0
- package/dist/lib/browser/{markdown-TE5SWWNJ.mjs → markdown-GEXBVJYN.mjs} +7 -7
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react-root-X4UIVGTX.mjs +28 -0
- package/dist/lib/browser/{react-surface-VXUJKSOG.mjs → react-surface-YCYEFBPM.mjs} +12 -11
- package/dist/lib/browser/{settings-RB2RSLXV.mjs → settings-E32MTL7A.mjs} +4 -4
- package/dist/lib/browser/{state-RKL5MSDP.mjs → state-H6CYONWE.mjs} +4 -4
- package/dist/lib/browser/types/index.mjs +2 -2
- package/dist/lib/node-esm/ChannelContainer-DET6T5N2.mjs +17 -0
- package/dist/lib/node-esm/{ChatContainer-F6CSADV7.mjs → ChatContainer-IQUWU426.mjs} +6 -5
- package/dist/lib/node-esm/{app-graph-builder-BAHBHYWI.mjs → app-graph-builder-VCW76Z6V.mjs} +6 -6
- package/dist/lib/node-esm/{call-manager-UUYXLF4T.mjs → call-manager-D6O5ZJJ4.mjs} +6 -5
- package/dist/lib/{browser/call-manager-APQAZWHT.mjs.map → node-esm/call-manager-D6O5ZJJ4.mjs.map} +1 -1
- package/dist/lib/node-esm/{chunk-O3V45YJP.mjs → chunk-25ABSYP2.mjs} +65 -5
- package/dist/lib/node-esm/chunk-25ABSYP2.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-2MFNK53T.mjs +480 -0
- package/dist/lib/node-esm/chunk-2MFNK53T.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-PGRP3O4O.mjs → chunk-57XR3LEF.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-K4KAUOKT.mjs → chunk-75RJ5DJI.mjs} +3 -3
- package/dist/lib/node-esm/{chunk-2RNIPFDA.mjs → chunk-C3XFMUAY.mjs} +32 -31
- package/dist/lib/node-esm/chunk-C3XFMUAY.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-ESQC6SYE.mjs → chunk-GRLRWTRU.mjs} +2 -2
- package/dist/lib/node-esm/chunk-GW37AAM4.mjs +23 -0
- package/dist/lib/node-esm/{chunk-WXNPD542.mjs → chunk-IHDNQLLR.mjs} +84 -124
- package/dist/lib/node-esm/chunk-IHDNQLLR.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-J4NSON5Q.mjs +368 -0
- package/dist/lib/node-esm/chunk-J4NSON5Q.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-OU5BYIDO.mjs +58 -0
- package/dist/lib/node-esm/chunk-OU5BYIDO.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-UJMPYKT3.mjs → chunk-TDFHTCZZ.mjs} +14 -5
- package/dist/lib/node-esm/chunk-TDFHTCZZ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +35 -41
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/{intent-resolver-BU73VYW3.mjs → intent-resolver-OXGNQ44Y.mjs} +30 -14
- package/dist/lib/node-esm/intent-resolver-OXGNQ44Y.mjs.map +7 -0
- package/dist/lib/node-esm/{markdown-HJUWNBLS.mjs → markdown-LIJZDK2J.mjs} +7 -7
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-root-RUXOAQNW.mjs → react-root-M7J6PZVW.mjs} +12 -11
- package/dist/lib/{browser/react-root-NK3A4VG7.mjs.map → node-esm/react-root-M7J6PZVW.mjs.map} +1 -1
- package/dist/lib/node-esm/{react-surface-ELXFYKP6.mjs → react-surface-IRSEKM42.mjs} +12 -11
- package/dist/lib/{browser/react-surface-VXUJKSOG.mjs.map → node-esm/react-surface-IRSEKM42.mjs.map} +1 -1
- package/dist/lib/node-esm/{settings-EA7DFSM6.mjs → settings-SJ24YG7M.mjs} +4 -4
- package/dist/lib/node-esm/{state-6AUTNROZ.mjs → state-D7WNDT3N.mjs} +4 -4
- package/dist/lib/node-esm/types/index.mjs +2 -2
- package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
- package/dist/types/src/calls/call-manager.d.ts +1 -1
- package/dist/types/src/calls/call-manager.d.ts.map +1 -1
- package/dist/types/src/calls/media-manager.d.ts.map +1 -1
- package/dist/types/src/calls/util/calls-service.d.ts +4 -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 +22 -0
- package/dist/types/src/calls-service.stories.d.ts.map +1 -0
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/components/ChannelContainer.d.ts.map +1 -1
- package/dist/types/src/components/ChannelContainer.stories.d.ts +2 -2
- package/dist/types/src/components/ChannelContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/Chat.stories.d.ts +3 -2
- package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
- package/dist/types/src/components/ChatContainer.d.ts +2 -2
- package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
- package/dist/types/src/components/Comments.stories.d.ts +1 -1
- package/dist/types/src/components/Comments.stories.d.ts.map +1 -1
- package/dist/types/src/components/CommentsContainer.d.ts +4 -4
- package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
- package/dist/types/src/components/CommentsThreadContainer.d.ts +14 -0
- package/dist/types/src/components/CommentsThreadContainer.d.ts.map +1 -0
- package/dist/types/src/components/Media/VideoObject.stories.d.ts +1 -1
- package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +1 -1
- package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
- package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts +1 -1
- package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +1 -1
- package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts +2 -0
- package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts.map +1 -0
- package/dist/types/src/hooks/useVideoStreamTrack.d.ts +3 -0
- package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +1 -0
- package/dist/types/src/testing/stories.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +74 -194
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +50 -21
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +68 -22
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +17 -2
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +47 -48
- package/src/ThreadPlugin.tsx +7 -22
- package/src/calls/call-manager.ts +6 -2
- package/src/calls/media-manager.ts +11 -4
- package/src/calls/util/calls-service.ts +8 -5
- package/src/calls/util/stub-media-streams.ts +3 -6
- package/src/calls-service.stories.tsx +216 -0
- package/src/capabilities/intent-resolver.ts +22 -4
- package/src/components/Call/Call.tsx +1 -1
- package/src/components/Call/Toolbar.tsx +3 -3
- package/src/components/CallDebugPanel.tsx +2 -2
- package/src/components/ChannelContainer.stories.tsx +5 -5
- package/src/components/ChannelContainer.tsx +6 -5
- package/src/components/Chat.stories.tsx +4 -4
- package/src/components/ChatContainer.tsx +12 -11
- package/src/components/Comments.stories.tsx +22 -15
- package/src/components/CommentsContainer.tsx +16 -11
- package/src/components/{CommentContainer.tsx → CommentsThreadContainer.tsx} +49 -80
- package/src/components/Media/VideoObject.stories.tsx +1 -1
- package/src/components/MessageContainer.tsx +29 -45
- package/src/components/ResponsiveGrid/ResponsiveContainer.stories.tsx +2 -2
- package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +3 -3
- package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +2 -2
- package/src/components/ThreadComplementary.tsx +2 -2
- package/src/components/ThreadSettings.tsx +2 -2
- package/src/components/index.ts +1 -1
- package/src/components/testing.ts +2 -2
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useInaudibleAudioStreamTrack.tsx +27 -0
- package/src/hooks/useVideoStreamTrack.tsx +33 -0
- package/src/testing/stories.ts +5 -1
- package/src/translations.ts +11 -8
- package/src/types/types.ts +9 -1
- package/dist/lib/browser/ChannelContainer-PKFBVENP.mjs +0 -15
- package/dist/lib/browser/ChatContainer-RSOKYAMK.mjs +0 -14
- package/dist/lib/browser/chunk-4H4A264L.mjs.map +0 -7
- package/dist/lib/browser/chunk-5P5BH5GE.mjs.map +0 -7
- package/dist/lib/browser/chunk-6NBVNXTM.mjs +0 -21
- package/dist/lib/browser/chunk-AEXWNS6Z.mjs.map +0 -7
- package/dist/lib/browser/chunk-PG5CTFKK.mjs +0 -550
- package/dist/lib/browser/chunk-PG5CTFKK.mjs.map +0 -7
- package/dist/lib/browser/chunk-TAFSCSUR.mjs +0 -351
- package/dist/lib/browser/chunk-TAFSCSUR.mjs.map +0 -7
- package/dist/lib/browser/chunk-XZKBN3NS.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-FK2MDVDT.mjs.map +0 -7
- package/dist/lib/browser/react-root-NK3A4VG7.mjs +0 -27
- package/dist/lib/node/ChannelContainer-YS5YT2ML.cjs +0 -36
- package/dist/lib/node/ChannelContainer-YS5YT2ML.cjs.map +0 -7
- package/dist/lib/node/ChatContainer-GCOM3M56.cjs +0 -35
- package/dist/lib/node/ChatContainer-GCOM3M56.cjs.map +0 -7
- package/dist/lib/node/app-graph-builder-PBHJNDQY.cjs +0 -179
- package/dist/lib/node/app-graph-builder-PBHJNDQY.cjs.map +0 -7
- package/dist/lib/node/call-manager-HV2XJW5O.cjs +0 -37
- package/dist/lib/node/call-manager-HV2XJW5O.cjs.map +0 -7
- package/dist/lib/node/chunk-44I33JDT.cjs +0 -1731
- package/dist/lib/node/chunk-44I33JDT.cjs.map +0 -7
- package/dist/lib/node/chunk-4YSNVPWU.cjs +0 -37
- package/dist/lib/node/chunk-4YSNVPWU.cjs.map +0 -7
- package/dist/lib/node/chunk-E3WBZTTI.cjs +0 -371
- package/dist/lib/node/chunk-E3WBZTTI.cjs.map +0 -7
- package/dist/lib/node/chunk-ERG7G6FF.cjs +0 -59
- package/dist/lib/node/chunk-ERG7G6FF.cjs.map +0 -7
- package/dist/lib/node/chunk-FUXJAVFZ.cjs +0 -108
- package/dist/lib/node/chunk-FUXJAVFZ.cjs.map +0 -7
- package/dist/lib/node/chunk-HLMCEE5K.cjs +0 -41
- package/dist/lib/node/chunk-HLMCEE5K.cjs.map +0 -7
- package/dist/lib/node/chunk-IP533AMV.cjs +0 -554
- package/dist/lib/node/chunk-IP533AMV.cjs.map +0 -7
- package/dist/lib/node/chunk-LR5NENBE.cjs +0 -54
- package/dist/lib/node/chunk-LR5NENBE.cjs.map +0 -7
- package/dist/lib/node/chunk-UM36TPCT.cjs +0 -984
- package/dist/lib/node/chunk-UM36TPCT.cjs.map +0 -7
- package/dist/lib/node/chunk-ZGDN3XBR.cjs +0 -149
- package/dist/lib/node/chunk-ZGDN3XBR.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -310
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/intent-resolver-SYSJ5SJG.cjs +0 -363
- package/dist/lib/node/intent-resolver-SYSJ5SJG.cjs.map +0 -7
- package/dist/lib/node/markdown-GQIPJS2F.cjs +0 -178
- package/dist/lib/node/markdown-GQIPJS2F.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/react-root-6HHDMULJ.cjs +0 -51
- package/dist/lib/node/react-root-6HHDMULJ.cjs.map +0 -7
- package/dist/lib/node/react-surface-NBH42NN2.cjs +0 -122
- package/dist/lib/node/react-surface-NBH42NN2.cjs.map +0 -7
- package/dist/lib/node/settings-4LQSFEDK.cjs +0 -36
- package/dist/lib/node/settings-4LQSFEDK.cjs.map +0 -7
- package/dist/lib/node/state-IY5XX3H2.cjs +0 -50
- package/dist/lib/node/state-IY5XX3H2.cjs.map +0 -7
- package/dist/lib/node/types/index.cjs +0 -38
- package/dist/lib/node/types/index.cjs.map +0 -7
- package/dist/lib/node-esm/ChannelContainer-O4QJII2P.mjs +0 -16
- package/dist/lib/node-esm/chunk-2RNIPFDA.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-O3V45YJP.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-O63QJPQX.mjs +0 -23
- package/dist/lib/node-esm/chunk-P6RLFCNT.mjs +0 -352
- package/dist/lib/node-esm/chunk-P6RLFCNT.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-UJMPYKT3.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-UZWVVFT3.mjs +0 -551
- package/dist/lib/node-esm/chunk-UZWVVFT3.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-WXNPD542.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-BU73VYW3.mjs.map +0 -7
- package/dist/types/src/components/CommentContainer.d.ts +0 -13
- package/dist/types/src/components/CommentContainer.d.ts.map +0 -1
- package/dist/types/src/peers.stories.d.ts +0 -11
- package/dist/types/src/peers.stories.d.ts.map +0 -1
- package/src/peers.stories.tsx +0 -189
- /package/dist/lib/browser/{ChannelContainer-PKFBVENP.mjs.map → ChannelContainer-IY2UIRLF.mjs.map} +0 -0
- /package/dist/lib/browser/{ChatContainer-RSOKYAMK.mjs.map → ChatContainer-AIGIWAUG.mjs.map} +0 -0
- /package/dist/lib/browser/{app-graph-builder-OY7R7EJP.mjs.map → app-graph-builder-N7BE5TYW.mjs.map} +0 -0
- /package/dist/lib/{node-esm/call-manager-UUYXLF4T.mjs.map → browser/call-manager-NIPDYUVD.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-6NBVNXTM.mjs.map → chunk-4OYAYON2.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-IIUTBDVB.mjs.map → chunk-EV4JWI7L.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-JKQUJOTX.mjs.map → chunk-GERVMFQW.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-R5MDLUPC.mjs.map → chunk-LGSDKXPF.mjs.map} +0 -0
- /package/dist/lib/browser/{markdown-TE5SWWNJ.mjs.map → markdown-GEXBVJYN.mjs.map} +0 -0
- /package/dist/lib/{node-esm/react-root-RUXOAQNW.mjs.map → browser/react-root-X4UIVGTX.mjs.map} +0 -0
- /package/dist/lib/{node-esm/react-surface-ELXFYKP6.mjs.map → browser/react-surface-YCYEFBPM.mjs.map} +0 -0
- /package/dist/lib/browser/{settings-RB2RSLXV.mjs.map → settings-E32MTL7A.mjs.map} +0 -0
- /package/dist/lib/browser/{state-RKL5MSDP.mjs.map → state-H6CYONWE.mjs.map} +0 -0
- /package/dist/lib/node-esm/{ChannelContainer-O4QJII2P.mjs.map → ChannelContainer-DET6T5N2.mjs.map} +0 -0
- /package/dist/lib/node-esm/{ChatContainer-F6CSADV7.mjs.map → ChatContainer-IQUWU426.mjs.map} +0 -0
- /package/dist/lib/node-esm/{app-graph-builder-BAHBHYWI.mjs.map → app-graph-builder-VCW76Z6V.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-PGRP3O4O.mjs.map → chunk-57XR3LEF.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-K4KAUOKT.mjs.map → chunk-75RJ5DJI.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-ESQC6SYE.mjs.map → chunk-GRLRWTRU.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-O63QJPQX.mjs.map → chunk-GW37AAM4.mjs.map} +0 -0
- /package/dist/lib/node-esm/{markdown-HJUWNBLS.mjs.map → markdown-LIJZDK2J.mjs.map} +0 -0
- /package/dist/lib/node-esm/{settings-EA7DFSM6.mjs.map → settings-SJ24YG7M.mjs.map} +0 -0
- /package/dist/lib/node-esm/{state-6AUTNROZ.mjs.map → state-D7WNDT3N.mjs.map} +0 -0
|
@@ -7,6 +7,7 @@ import React, { useCallback, useEffect, useMemo, useState, type ChangeEvent } fr
|
|
|
7
7
|
|
|
8
8
|
import { useCapabilities, useCapability } from '@dxos/app-framework';
|
|
9
9
|
import { Context } from '@dxos/context';
|
|
10
|
+
import { failUndefined } from '@dxos/debug';
|
|
10
11
|
import { log } from '@dxos/log';
|
|
11
12
|
import { useClient } from '@dxos/react-client';
|
|
12
13
|
import { fullyQualifiedId, getSpace } from '@dxos/react-client/echo';
|
|
@@ -20,7 +21,7 @@ import { StackItem } from '@dxos/react-ui-stack';
|
|
|
20
21
|
import { Call } from './Call';
|
|
21
22
|
import ChatContainer from './ChatContainer';
|
|
22
23
|
import { ThreadCapabilities } from '../capabilities';
|
|
23
|
-
import {
|
|
24
|
+
import { meta } from '../meta';
|
|
24
25
|
import { type ChannelType } from '../types';
|
|
25
26
|
|
|
26
27
|
export type ChannelContainerProps = {
|
|
@@ -36,7 +37,7 @@ export type ChannelContainerProps = {
|
|
|
36
37
|
export const ChannelContainer = ({ channel, roomId: _roomId, role, fullscreen }: ChannelContainerProps) => {
|
|
37
38
|
const space = getSpace(channel);
|
|
38
39
|
const callManager = useCapability(ThreadCapabilities.CallManager);
|
|
39
|
-
const roomId = channel ? fullyQualifiedId(channel) :
|
|
40
|
+
const roomId = _roomId ?? (channel ? fullyQualifiedId(channel) : failUndefined());
|
|
40
41
|
const identity = useIdentity();
|
|
41
42
|
const isNamed = !!identity?.profile?.displayName;
|
|
42
43
|
const joinSound = useSoundEffect('JoinCall');
|
|
@@ -133,7 +134,7 @@ export const ChannelContainer = ({ channel, roomId: _roomId, role, fullscreen }:
|
|
|
133
134
|
export default ChannelContainer;
|
|
134
135
|
|
|
135
136
|
const DisplayNameMissing = () => {
|
|
136
|
-
const { t } = useTranslation(
|
|
137
|
+
const { t } = useTranslation(meta.id);
|
|
137
138
|
const client = useClient();
|
|
138
139
|
const [displayName, setDisplayName] = useState('');
|
|
139
140
|
const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => setDisplayName(event.target.value), []);
|
|
@@ -163,10 +164,10 @@ const useChannelToolbarActions = (onJoinCall?: () => void) => {
|
|
|
163
164
|
return {
|
|
164
165
|
nodes: [
|
|
165
166
|
createMenuItemGroup('root', {
|
|
166
|
-
label: ['channel toolbar title', { ns:
|
|
167
|
+
label: ['channel toolbar title', { ns: meta.id }],
|
|
167
168
|
}),
|
|
168
169
|
createMenuAction('video-call', () => onJoinCall?.(), {
|
|
169
|
-
label: ['start video call label', { ns:
|
|
170
|
+
label: ['start video call label', { ns: meta.id }],
|
|
170
171
|
icon: 'ph--video-camera--regular',
|
|
171
172
|
type: 'video-call',
|
|
172
173
|
}),
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
|
-
import { type Meta } from '@storybook/react';
|
|
7
|
+
import { type Meta } from '@storybook/react-vite';
|
|
8
8
|
import React, { useEffect, useState } from 'react';
|
|
9
9
|
|
|
10
10
|
import { Capabilities, contributes, createSurface, IntentPlugin } from '@dxos/app-framework';
|
|
@@ -20,7 +20,7 @@ import { DataType } from '@dxos/schema';
|
|
|
20
20
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
21
21
|
|
|
22
22
|
import { ChatContainer } from './ChatContainer';
|
|
23
|
-
import translations from '../translations';
|
|
23
|
+
import { translations } from '../translations';
|
|
24
24
|
import { ChannelType, ThreadType } from '../types';
|
|
25
25
|
|
|
26
26
|
faker.seed(1);
|
|
@@ -60,9 +60,9 @@ const Story = () => {
|
|
|
60
60
|
|
|
61
61
|
export const Default = {};
|
|
62
62
|
|
|
63
|
-
const meta: Meta = {
|
|
63
|
+
const meta: Meta<typeof Thread.Root> = {
|
|
64
64
|
title: 'plugins/plugin-thread/Chat',
|
|
65
|
-
component: Thread,
|
|
65
|
+
component: Thread.Root,
|
|
66
66
|
render: () => <Story />,
|
|
67
67
|
decorators: [
|
|
68
68
|
withPluginManager({
|
|
@@ -15,9 +15,8 @@ import {
|
|
|
15
15
|
MessageTextbox,
|
|
16
16
|
type MessageTextboxProps,
|
|
17
17
|
Thread,
|
|
18
|
-
|
|
18
|
+
type ThreadRootProps,
|
|
19
19
|
threadLayout,
|
|
20
|
-
type ThreadProps,
|
|
21
20
|
} from '@dxos/react-ui-thread';
|
|
22
21
|
import { DataType } from '@dxos/schema';
|
|
23
22
|
import { isNonNullable } from '@dxos/util';
|
|
@@ -25,12 +24,12 @@ import { isNonNullable } from '@dxos/util';
|
|
|
25
24
|
import { MessageContainer } from './MessageContainer';
|
|
26
25
|
import { command } from './command-extension';
|
|
27
26
|
import { useStatus } from '../hooks';
|
|
28
|
-
import {
|
|
27
|
+
import { meta } from '../meta';
|
|
29
28
|
import { type ThreadType } from '../types';
|
|
30
29
|
import { getMessageMetadata } from '../util';
|
|
31
30
|
|
|
32
31
|
export const ChatHeading = ({ attendableId }: { attendableId?: string }) => {
|
|
33
|
-
const { t } = useTranslation(
|
|
32
|
+
const { t } = useTranslation(meta.id);
|
|
34
33
|
return (
|
|
35
34
|
<div role='none' className='flex items-center'>
|
|
36
35
|
<StackItem.SigilButton attendableId={attendableId}>
|
|
@@ -46,14 +45,14 @@ export type ChatContainerProps = {
|
|
|
46
45
|
thread: ThreadType;
|
|
47
46
|
context?: Obj.Any;
|
|
48
47
|
autoFocusTextbox?: boolean;
|
|
49
|
-
} & Pick<
|
|
48
|
+
} & Pick<ThreadRootProps, 'current'>;
|
|
50
49
|
|
|
51
50
|
export const ChatContainer = ({ space, thread, context, current, autoFocusTextbox }: ChatContainerProps) => {
|
|
51
|
+
const { t } = useTranslation(meta.id);
|
|
52
52
|
const id = fullyQualifiedId(thread);
|
|
53
53
|
const identity = useIdentity()!;
|
|
54
54
|
const members = useMembers(space?.key);
|
|
55
55
|
const activity = useStatus(space, id);
|
|
56
|
-
const { t } = useTranslation(THREAD_PLUGIN);
|
|
57
56
|
// TODO(wittjosiah): This is a hack to reset the editor after a message is sent.
|
|
58
57
|
const [_count, _setCount] = useState(0);
|
|
59
58
|
const rerenderEditor = () => _setCount((count) => count + 1);
|
|
@@ -93,9 +92,9 @@ export const ChatContainer = ({ space, thread, context, current, autoFocusTextbo
|
|
|
93
92
|
thread.messages.push(
|
|
94
93
|
Ref.make(
|
|
95
94
|
Obj.make(DataType.Message, {
|
|
96
|
-
sender: { identityDid: identity.did },
|
|
97
95
|
created: new Date().toISOString(),
|
|
98
|
-
|
|
96
|
+
sender: { identityDid: identity.did },
|
|
97
|
+
blocks: [{ _tag: 'text', text: messageRef.current }],
|
|
99
98
|
properties: context ? { context: Ref.make(context) } : undefined,
|
|
100
99
|
}),
|
|
101
100
|
),
|
|
@@ -109,7 +108,7 @@ export const ChatContainer = ({ space, thread, context, current, autoFocusTextbo
|
|
|
109
108
|
};
|
|
110
109
|
|
|
111
110
|
return (
|
|
112
|
-
<Thread
|
|
111
|
+
<Thread.Root
|
|
113
112
|
current={current}
|
|
114
113
|
id={id}
|
|
115
114
|
classNames='bs-full grid-rows-[1fr_min-content_min-content] overflow-hidden transition-[padding-block-end] [[data-sidebar-inline-start-state=open]_&]:lg:pbe-0'
|
|
@@ -131,9 +130,11 @@ export const ChatContainer = ({ space, thread, context, current, autoFocusTextbo
|
|
|
131
130
|
</ScrollArea.Scrollbar>
|
|
132
131
|
</ScrollArea.Viewport>
|
|
133
132
|
</ScrollArea.Root>
|
|
133
|
+
|
|
134
134
|
<MessageTextbox extensions={extensions} autoFocus={autoFocus} onSend={handleCreate} {...textboxMetadata} />
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
|
|
136
|
+
<Thread.Status activity={activity}>{t('activity message')}</Thread.Status>
|
|
137
|
+
</Thread.Root>
|
|
137
138
|
);
|
|
138
139
|
};
|
|
139
140
|
|
|
@@ -4,29 +4,29 @@
|
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
|
-
import { type Meta } from '@storybook/react';
|
|
7
|
+
import { type Meta } from '@storybook/react-vite';
|
|
8
8
|
import React, { useEffect } from 'react';
|
|
9
9
|
|
|
10
10
|
import { IntentPlugin } from '@dxos/app-framework';
|
|
11
11
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
12
12
|
import { Obj, Query, Relation, Type } from '@dxos/echo';
|
|
13
|
+
import { ClientPlugin } from '@dxos/plugin-client';
|
|
13
14
|
import { faker } from '@dxos/random';
|
|
14
15
|
import { useQuery, useSpace } from '@dxos/react-client/echo';
|
|
15
16
|
import { useIdentity } from '@dxos/react-client/halo';
|
|
16
|
-
import { type ClientRepeatedComponentProps, ClientRepeater } from '@dxos/react-client/testing';
|
|
17
17
|
import { AnchoredTo, DataType } from '@dxos/schema';
|
|
18
|
-
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
18
|
+
import { layoutCentered, render, withLayout, withTheme } from '@dxos/storybook-utils';
|
|
19
19
|
|
|
20
20
|
import { CommentsContainer } from './CommentsContainer';
|
|
21
21
|
import { createCommentThread } from './testing';
|
|
22
|
-
import translations from '../translations';
|
|
22
|
+
import { translations } from '../translations';
|
|
23
23
|
import { ThreadType } from '../types';
|
|
24
24
|
|
|
25
25
|
faker.seed(1);
|
|
26
26
|
|
|
27
|
-
const
|
|
27
|
+
const DefaultStory = () => {
|
|
28
28
|
const identity = useIdentity();
|
|
29
|
-
const space = useSpace(
|
|
29
|
+
const space = useSpace();
|
|
30
30
|
const anchors = useQuery(space, Query.type(AnchoredTo));
|
|
31
31
|
|
|
32
32
|
useEffect(() => {
|
|
@@ -58,26 +58,33 @@ const Story = ({ spaceKey }: ClientRepeatedComponentProps) => {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
return (
|
|
61
|
-
<div className='
|
|
62
|
-
<
|
|
63
|
-
<CommentsContainer anchors={anchors} onThreadDelete={console.log} />
|
|
64
|
-
</div>
|
|
61
|
+
<div className='w-[30rem] overflow-y-auto bg-baseSurface'>
|
|
62
|
+
<CommentsContainer anchors={anchors} onThreadDelete={console.log} />
|
|
65
63
|
</div>
|
|
66
64
|
);
|
|
67
65
|
};
|
|
68
66
|
|
|
69
67
|
const meta: Meta = {
|
|
70
68
|
title: 'plugins/plugin-thread/Comments',
|
|
71
|
-
|
|
72
|
-
render: () => <ClientRepeater component={Story} createIdentity createSpace types={[ThreadType, DataType.Message]} />,
|
|
69
|
+
render: render(DefaultStory),
|
|
73
70
|
decorators: [
|
|
74
71
|
withTheme,
|
|
75
|
-
withLayout({ fullscreen: true }),
|
|
72
|
+
withLayout({ fullscreen: true, classNames: layoutCentered }),
|
|
76
73
|
withPluginManager({
|
|
77
|
-
plugins: [
|
|
74
|
+
plugins: [
|
|
75
|
+
IntentPlugin(),
|
|
76
|
+
ClientPlugin({
|
|
77
|
+
types: [DataType.Message, ThreadType, AnchoredTo],
|
|
78
|
+
onClientInitialized: async (_, client) => {
|
|
79
|
+
await client.halo.createIdentity();
|
|
80
|
+
},
|
|
81
|
+
}),
|
|
82
|
+
],
|
|
78
83
|
}),
|
|
79
84
|
],
|
|
80
|
-
parameters: {
|
|
85
|
+
parameters: {
|
|
86
|
+
translations,
|
|
87
|
+
},
|
|
81
88
|
};
|
|
82
89
|
|
|
83
90
|
export default meta;
|
|
@@ -9,21 +9,22 @@ import { fullyQualifiedId } from '@dxos/react-client/echo';
|
|
|
9
9
|
import { Callout, Icon, Trans, useTranslation } from '@dxos/react-ui';
|
|
10
10
|
import { type AnchoredTo } from '@dxos/schema';
|
|
11
11
|
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { CommentsThreadContainer, type CommentsThreadContainerProps } from './CommentsThreadContainer';
|
|
13
|
+
import { meta } from '../meta';
|
|
14
14
|
import { type ThreadType } from '../types';
|
|
15
15
|
|
|
16
|
-
export type
|
|
16
|
+
export type CommentsContainerProps = Omit<CommentsThreadContainerProps, 'anchor' | 'current'> & {
|
|
17
17
|
anchors: AnchoredTo[];
|
|
18
18
|
currentId?: string;
|
|
19
19
|
showResolvedThreads?: boolean;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Root container for collection of comment threads.
|
|
24
24
|
*/
|
|
25
|
-
export const CommentsContainer = ({ anchors, currentId, showResolvedThreads, ...props }:
|
|
26
|
-
const { t } = useTranslation(
|
|
25
|
+
export const CommentsContainer = ({ anchors, currentId, showResolvedThreads, ...props }: CommentsContainerProps) => {
|
|
26
|
+
const { t } = useTranslation(meta.id);
|
|
27
|
+
|
|
27
28
|
// TODO(wittjosiah): There seems to be a race between thread and anchor being deleted.
|
|
28
29
|
const filteredAnchors = showResolvedThreads
|
|
29
30
|
? anchors.filter((anchor) => !!Relation.getSource(anchor))
|
|
@@ -58,9 +59,13 @@ export const CommentsContainer = ({ anchors, currentId, showResolvedThreads, ...
|
|
|
58
59
|
);
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
return
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
return (
|
|
63
|
+
<div>
|
|
64
|
+
{filteredAnchors.map((anchor) => {
|
|
65
|
+
const thread = Relation.getSource(anchor) as ThreadType;
|
|
66
|
+
const threadId = fullyQualifiedId(thread);
|
|
67
|
+
return <CommentsThreadContainer key={threadId} anchor={anchor} current={currentId === threadId} {...props} />;
|
|
68
|
+
})}
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
66
71
|
};
|
|
@@ -2,97 +2,38 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { CheckCircle, X } from '@phosphor-icons/react';
|
|
6
5
|
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
|
7
6
|
|
|
8
|
-
import { Relation } from '@dxos/echo';
|
|
9
|
-
import { RefArray } from '@dxos/live-object';
|
|
7
|
+
import { Ref, Relation } from '@dxos/echo';
|
|
10
8
|
import { fullyQualifiedId, getSpace, useMembers } from '@dxos/react-client/echo';
|
|
11
9
|
import { useIdentity } from '@dxos/react-client/halo';
|
|
12
|
-
import {
|
|
10
|
+
import { IconButton, Tag, Tooltip, useThemeContext, useTranslation } from '@dxos/react-ui';
|
|
13
11
|
import { createBasicExtensions, createThemeExtensions, listener } from '@dxos/react-ui-editor';
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
hoverableControlItem,
|
|
17
|
-
hoverableControls,
|
|
18
|
-
hoverableFocusedWithinControls,
|
|
19
|
-
mx,
|
|
20
|
-
} from '@dxos/react-ui-theme';
|
|
21
|
-
import {
|
|
22
|
-
MessageTextbox,
|
|
23
|
-
type MessageTextboxProps,
|
|
24
|
-
Thread,
|
|
25
|
-
ThreadFooter,
|
|
26
|
-
ThreadHeading,
|
|
27
|
-
type ThreadProps,
|
|
28
|
-
} from '@dxos/react-ui-thread';
|
|
12
|
+
import { hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from '@dxos/react-ui-theme';
|
|
13
|
+
import { MessageTextbox, type MessageTextboxProps, Thread, type ThreadRootProps } from '@dxos/react-ui-thread';
|
|
29
14
|
import { type AnchoredTo } from '@dxos/schema';
|
|
30
15
|
import { isNonNullable } from '@dxos/util';
|
|
31
16
|
|
|
32
17
|
import { MessageContainer } from './MessageContainer';
|
|
33
18
|
import { command } from './command-extension';
|
|
34
19
|
import { useStatus } from '../hooks';
|
|
35
|
-
import {
|
|
20
|
+
import { meta } from '../meta';
|
|
36
21
|
import { type ThreadType } from '../types';
|
|
37
22
|
import { getMessageMetadata } from '../util';
|
|
38
23
|
|
|
39
|
-
|
|
24
|
+
// TODO(burdon): Remove need for p-1.
|
|
25
|
+
export const commentControlClassNames = '!p-1 transition-opacity';
|
|
40
26
|
|
|
41
|
-
|
|
42
|
-
const commentControlClassNames = '!p-1 !min-bs-0 transition-opacity';
|
|
43
|
-
|
|
44
|
-
const ToggleResolvedButton = ({
|
|
45
|
-
isResolved,
|
|
46
|
-
onResolve,
|
|
47
|
-
}: {
|
|
48
|
-
isResolved: boolean | undefined;
|
|
49
|
-
onResolve: () => void;
|
|
50
|
-
}) => {
|
|
51
|
-
const { t } = useTranslation(THREAD_PLUGIN);
|
|
52
|
-
const label = t(isResolved ? 'mark as unresolved label' : 'mark as resolved label');
|
|
53
|
-
return (
|
|
54
|
-
<Tooltip.Trigger asChild content={label}>
|
|
55
|
-
<Button
|
|
56
|
-
variant='ghost'
|
|
57
|
-
data-testid='thread.toggle-resolved'
|
|
58
|
-
onClick={onResolve}
|
|
59
|
-
classNames={[commentControlClassNames, !isResolved && hoverableControlItem]}
|
|
60
|
-
>
|
|
61
|
-
<span className='sr-only'>{label}</span>
|
|
62
|
-
{isResolved ? <CheckCircle className={sizeClass} weight='fill' /> : <CheckCircle className={sizeClass} />}
|
|
63
|
-
</Button>
|
|
64
|
-
</Tooltip.Trigger>
|
|
65
|
-
);
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const DeleteThreadButton = ({ onDelete }: { onDelete: () => void }) => {
|
|
69
|
-
const { t } = useTranslation(THREAD_PLUGIN);
|
|
70
|
-
const label = t('delete thread label');
|
|
71
|
-
return (
|
|
72
|
-
<Tooltip.Trigger asChild content={label}>
|
|
73
|
-
<Button
|
|
74
|
-
variant='ghost'
|
|
75
|
-
data-testid='thread.delete'
|
|
76
|
-
onClick={onDelete}
|
|
77
|
-
classNames={[commentControlClassNames, hoverableControlItem]}
|
|
78
|
-
>
|
|
79
|
-
<span className='sr-only'>{label}</span>
|
|
80
|
-
<X className={sizeClass} />
|
|
81
|
-
</Button>
|
|
82
|
-
</Tooltip.Trigger>
|
|
83
|
-
);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export type CommentContainerProps = {
|
|
27
|
+
export type CommentsThreadContainerProps = {
|
|
87
28
|
anchor: AnchoredTo;
|
|
88
29
|
onAttend?: (anchor: AnchoredTo) => void;
|
|
89
30
|
onComment?: (anchor: AnchoredTo, message: string) => void;
|
|
90
31
|
onResolve?: (anchor: AnchoredTo) => void;
|
|
91
32
|
onMessageDelete?: (anchor: AnchoredTo, messageId: string) => void;
|
|
92
33
|
onThreadDelete?: (anchor: AnchoredTo) => void;
|
|
93
|
-
} & Pick<
|
|
34
|
+
} & Pick<ThreadRootProps, 'current'>;
|
|
94
35
|
|
|
95
|
-
export const
|
|
36
|
+
export const CommentsThreadContainer = ({
|
|
96
37
|
anchor,
|
|
97
38
|
current,
|
|
98
39
|
onAttend,
|
|
@@ -100,14 +41,14 @@ export const CommentContainer = ({
|
|
|
100
41
|
onResolve,
|
|
101
42
|
onMessageDelete,
|
|
102
43
|
onThreadDelete,
|
|
103
|
-
}:
|
|
44
|
+
}: CommentsThreadContainerProps) => {
|
|
45
|
+
const { t } = useTranslation(meta.id);
|
|
104
46
|
const identity = useIdentity()!;
|
|
105
47
|
const space = getSpace(anchor);
|
|
106
48
|
const members = useMembers(space?.key);
|
|
107
49
|
const detached = !anchor.anchor;
|
|
108
50
|
const thread = Relation.getSource(anchor) as ThreadType;
|
|
109
51
|
const activity = useStatus(space, fullyQualifiedId(thread));
|
|
110
|
-
const { t } = useTranslation(THREAD_PLUGIN);
|
|
111
52
|
const threadScrollRef = useRef<HTMLDivElement | null>(null);
|
|
112
53
|
const { themeMode } = useThemeContext();
|
|
113
54
|
|
|
@@ -149,7 +90,13 @@ export const CommentContainer = ({
|
|
|
149
90
|
}, [anchor, identity]);
|
|
150
91
|
|
|
151
92
|
return (
|
|
152
|
-
<Thread
|
|
93
|
+
<Thread.Root
|
|
94
|
+
id={fullyQualifiedId(thread)}
|
|
95
|
+
classNames='pbs-2 border-be border-subduedSeparator last:border-none'
|
|
96
|
+
current={current}
|
|
97
|
+
onClickCapture={handleAttend}
|
|
98
|
+
onFocusCapture={handleAttend}
|
|
99
|
+
>
|
|
153
100
|
<div
|
|
154
101
|
role='none'
|
|
155
102
|
className={mx(
|
|
@@ -160,21 +107,40 @@ export const CommentContainer = ({
|
|
|
160
107
|
>
|
|
161
108
|
{detached ? (
|
|
162
109
|
<Tooltip.Trigger asChild content={t('detached thread label')} side='top'>
|
|
163
|
-
<
|
|
110
|
+
<Thread.Header detached>{thread.name}</Thread.Header>
|
|
164
111
|
</Tooltip.Trigger>
|
|
165
112
|
) : (
|
|
166
|
-
<
|
|
113
|
+
<Thread.Header>{thread.name}</Thread.Header>
|
|
167
114
|
)}
|
|
168
|
-
<div className='flex flex-row items-center
|
|
115
|
+
<div className='flex flex-row items-center gap-0.5'>
|
|
169
116
|
{thread.status === 'staged' && <Tag palette='neutral'>{t('draft button')}</Tag>}
|
|
170
117
|
{onResolve && !(thread?.status === 'staged') && (
|
|
171
|
-
<
|
|
118
|
+
<IconButton
|
|
119
|
+
data-testid='thread.resolve'
|
|
120
|
+
variant='ghost'
|
|
121
|
+
icon={thread?.status === 'resolved' ? 'ph--check--fill' : 'ph--check--regular'}
|
|
122
|
+
iconOnly
|
|
123
|
+
label={t('resolve thread label')}
|
|
124
|
+
classNames={[commentControlClassNames, thread?.status !== 'resolved' && hoverableControlItem]}
|
|
125
|
+
onClick={handleResolve}
|
|
126
|
+
/>
|
|
127
|
+
)}
|
|
128
|
+
{onThreadDelete && (
|
|
129
|
+
<IconButton
|
|
130
|
+
data-testid='thread.delete'
|
|
131
|
+
variant='ghost'
|
|
132
|
+
icon='ph--x--regular'
|
|
133
|
+
iconOnly
|
|
134
|
+
label={t('delete thread label')}
|
|
135
|
+
classNames={[commentControlClassNames, hoverableControlItem]}
|
|
136
|
+
onClick={handleThreadDelete}
|
|
137
|
+
/>
|
|
172
138
|
)}
|
|
173
|
-
{onThreadDelete && <DeleteThreadButton onDelete={handleThreadDelete} />}
|
|
174
139
|
</div>
|
|
175
140
|
</div>
|
|
141
|
+
|
|
176
142
|
{/** TODO(dmaretskyi): How's `thread.messages` undefined? */}
|
|
177
|
-
{
|
|
143
|
+
{Ref.Array.targets(thread.messages?.filter(isNonNullable) ?? []).map((message) => (
|
|
178
144
|
<MessageContainer
|
|
179
145
|
key={message.id}
|
|
180
146
|
editable
|
|
@@ -183,6 +149,7 @@ export const CommentContainer = ({
|
|
|
183
149
|
onDelete={handleMessageDelete}
|
|
184
150
|
/>
|
|
185
151
|
))}
|
|
152
|
+
|
|
186
153
|
{/*
|
|
187
154
|
TODO(wittjosiah): Can't autofocus this generally.
|
|
188
155
|
There can be multiple threads with inputs and they can't all be focused.
|
|
@@ -190,9 +157,11 @@ export const CommentContainer = ({
|
|
|
190
157
|
Need to find a way to autofocus in one scenario only: when a new thread is created.
|
|
191
158
|
*/}
|
|
192
159
|
<MessageTextbox extensions={extensions} onSend={handleComment} {...textboxMetadata} />
|
|
193
|
-
|
|
160
|
+
|
|
161
|
+
<Thread.Status activity={activity}>{t('activity message')}</Thread.Status>
|
|
162
|
+
|
|
194
163
|
{/* NOTE(thure): This can’t also be the `overflow-anchor` because `ScrollArea` injects an interceding node that contains this necessary ref’d element. */}
|
|
195
164
|
<div role='none' className='bs-px -mbs-px' ref={threadScrollRef} />
|
|
196
|
-
</Thread>
|
|
165
|
+
</Thread.Root>
|
|
197
166
|
);
|
|
198
167
|
};
|
|
@@ -3,35 +3,25 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { EditorView } from '@codemirror/view';
|
|
6
|
-
import { Check, PencilSimple, X } from '@phosphor-icons/react';
|
|
7
6
|
import React, { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
|
|
8
7
|
|
|
9
8
|
import { Surface } from '@dxos/app-framework';
|
|
10
|
-
import { type Obj, type Type } from '@dxos/echo';
|
|
11
|
-
import { RefArray } from '@dxos/live-object';
|
|
9
|
+
import { type Obj, Ref, type Type } from '@dxos/echo';
|
|
12
10
|
import { PublicKey } from '@dxos/react-client';
|
|
13
11
|
import { type SpaceMember } from '@dxos/react-client/echo';
|
|
14
12
|
import { useIdentity, type Identity } from '@dxos/react-client/halo';
|
|
15
|
-
import {
|
|
13
|
+
import { IconButton, useOnTransition, useThemeContext, useTranslation } from '@dxos/react-ui';
|
|
16
14
|
import { createBasicExtensions, createThemeExtensions, useTextEditor } from '@dxos/react-ui-editor';
|
|
17
|
-
import {
|
|
18
|
-
getSize,
|
|
19
|
-
hoverableControlItem,
|
|
20
|
-
hoverableControls,
|
|
21
|
-
hoverableFocusedWithinControls,
|
|
22
|
-
mx,
|
|
23
|
-
} from '@dxos/react-ui-theme';
|
|
15
|
+
import { hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from '@dxos/react-ui-theme';
|
|
24
16
|
import { MessageHeading, MessageRoot } from '@dxos/react-ui-thread';
|
|
25
17
|
import { type DataType } from '@dxos/schema';
|
|
26
18
|
|
|
19
|
+
import { commentControlClassNames } from './CommentsThreadContainer';
|
|
27
20
|
import { command } from './command-extension';
|
|
28
21
|
import { useOnEditAnalytics } from '../hooks';
|
|
29
|
-
import {
|
|
22
|
+
import { meta } from '../meta';
|
|
30
23
|
import { getMessageMetadata } from '../util';
|
|
31
24
|
|
|
32
|
-
// TODO(thure): #8149
|
|
33
|
-
const messageControlClassNames = ['!p-1 !min-bs-0 transition-opacity', hoverableControlItem];
|
|
34
|
-
|
|
35
25
|
export type MessageContainerProps = {
|
|
36
26
|
message: DataType.Message;
|
|
37
27
|
members: SpaceMember[];
|
|
@@ -40,6 +30,7 @@ export type MessageContainerProps = {
|
|
|
40
30
|
};
|
|
41
31
|
|
|
42
32
|
export const MessageContainer = ({ message, members, editable = false, onDelete }: MessageContainerProps) => {
|
|
33
|
+
const { t } = useTranslation(meta.id);
|
|
43
34
|
const senderIdentity = members.find(
|
|
44
35
|
(member) =>
|
|
45
36
|
(message.sender.identityDid && member.identity.did === message.sender.identityDid) ||
|
|
@@ -49,48 +40,41 @@ export const MessageContainer = ({ message, members, editable = false, onDelete
|
|
|
49
40
|
const userIsAuthor = useIdentity()?.did === messageMetadata.authorId;
|
|
50
41
|
const [editing, setEditing] = useState(false);
|
|
51
42
|
const handleDelete = useCallback(() => onDelete?.(message.id), [message, onDelete]);
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const deleteLabel = t('delete message label');
|
|
55
|
-
const textBlock = message.blocks.find((block) => block.type === 'text');
|
|
56
|
-
const references = message.blocks.filter((block) => block.type === 'reference').map((block) => block.reference);
|
|
43
|
+
const textBlock = message.blocks.find((block) => block._tag === 'text');
|
|
44
|
+
const references = message.blocks.filter((block) => block._tag === 'reference').map((block) => block.reference);
|
|
57
45
|
|
|
58
46
|
useOnEditAnalytics(message, textBlock, !!editing);
|
|
59
47
|
|
|
60
48
|
return (
|
|
61
49
|
<MessageRoot {...messageMetadata} classNames={[hoverableControls, hoverableFocusedWithinControls]}>
|
|
62
50
|
<MessageHeading authorName={messageMetadata.authorName} timestamp={messageMetadata.timestamp}>
|
|
63
|
-
<
|
|
51
|
+
<div className='flex flex-row items-center gap-0.5'>
|
|
64
52
|
{userIsAuthor && editable && (
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
</Button>
|
|
75
|
-
</Tooltip.Trigger>
|
|
53
|
+
<IconButton
|
|
54
|
+
data-testid={editing ? 'thread.message.save' : 'thread.message.edit'}
|
|
55
|
+
variant='ghost'
|
|
56
|
+
icon={editing ? 'ph--check--regular' : 'ph--pencil-simple--regular'}
|
|
57
|
+
iconOnly
|
|
58
|
+
label={t(editing ? 'save message label' : 'edit message label')}
|
|
59
|
+
classNames={[commentControlClassNames, hoverableControlItem]}
|
|
60
|
+
onClick={() => setEditing((editing) => !editing)}
|
|
61
|
+
/>
|
|
76
62
|
)}
|
|
77
63
|
{onDelete && (
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
</Button>
|
|
88
|
-
</Tooltip.Trigger>
|
|
64
|
+
<IconButton
|
|
65
|
+
data-testid='thread.message.delete'
|
|
66
|
+
variant='ghost'
|
|
67
|
+
icon='ph--x--regular'
|
|
68
|
+
iconOnly
|
|
69
|
+
label={t('delete message label')}
|
|
70
|
+
classNames={[commentControlClassNames, hoverableControlItem]}
|
|
71
|
+
onClick={() => handleDelete()}
|
|
72
|
+
/>
|
|
89
73
|
)}
|
|
90
|
-
</
|
|
74
|
+
</div>
|
|
91
75
|
</MessageHeading>
|
|
92
76
|
{textBlock && <TextboxBlock block={textBlock} isAuthor={userIsAuthor} editing={editing} />}
|
|
93
|
-
{
|
|
77
|
+
{Ref.Array.targets(references).map((reference, index) => (
|
|
94
78
|
<MessagePart key={index} part={reference} />
|
|
95
79
|
))}
|
|
96
80
|
</MessageRoot>
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
|
-
import { type StoryObj, type Meta } from '@storybook/react';
|
|
7
|
+
import { type StoryObj, type Meta } from '@storybook/react-vite';
|
|
8
8
|
import React from 'react';
|
|
9
9
|
|
|
10
10
|
import { withTheme, withLayout } from '@dxos/storybook-utils';
|
|
11
11
|
|
|
12
12
|
import { ResponsiveContainer } from './ResponsiveContainer';
|
|
13
|
-
import translations from '../../translations';
|
|
13
|
+
import { translations } from '../../translations';
|
|
14
14
|
import { VideoObject as VideoObjectComponent } from '../Media';
|
|
15
15
|
|
|
16
16
|
const meta: Meta<typeof ResponsiveContainer> = {
|