@dxos/plugin-thread 0.8.4-staging.60fe92afc8 → 0.9.1-main.c7dcc2e112
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/neutral/ChannelArticle-CTYSCRTR.mjs +122 -0
- package/dist/lib/neutral/ChannelArticle-CTYSCRTR.mjs.map +7 -0
- package/dist/lib/neutral/ThreadPlugin.mjs +2 -2
- package/dist/lib/neutral/ThreadPlugin.mjs.map +4 -4
- package/dist/lib/neutral/{app-graph-builder-OLKN3VTB.mjs → app-graph-builder-U4ZDM6GK.mjs} +41 -5
- package/dist/lib/neutral/app-graph-builder-U4ZDM6GK.mjs.map +7 -0
- package/dist/lib/neutral/{append-channel-message-J6DXDPBH.mjs → append-channel-message-2OZYIIFL.mjs} +2 -2
- package/dist/lib/neutral/capabilities/index.mjs +5 -5
- package/dist/lib/neutral/{channel-backend-feed-FCXGAIEC.mjs → channel-backend-feed-ALIPAEPT.mjs} +3 -3
- package/dist/lib/neutral/{channel-backend-feed-FCXGAIEC.mjs.map → channel-backend-feed-ALIPAEPT.mjs.map} +2 -2
- package/dist/lib/neutral/chunk-A5JYVGL2.mjs +45 -0
- package/dist/lib/neutral/chunk-A5JYVGL2.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-AWAQTEU6.mjs → chunk-DM2T6BH5.mjs} +3 -3
- package/dist/lib/neutral/chunk-DM2T6BH5.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-P4RSGFS4.mjs → chunk-GQCMB5ZC.mjs} +2 -2
- package/dist/lib/neutral/{chunk-SZXFLBZL.mjs → chunk-KUO5HUCH.mjs} +2 -2
- package/dist/lib/neutral/{chunk-HJHK5O6F.mjs → chunk-UYINIL64.mjs} +4 -4
- package/dist/lib/neutral/{chunk-HJHK5O6F.mjs.map → chunk-UYINIL64.mjs.map} +3 -3
- package/dist/lib/neutral/components/index.mjs +7 -4
- package/dist/lib/neutral/components/index.mjs.map +3 -3
- package/dist/lib/neutral/containers/index.mjs +1 -1
- package/dist/lib/neutral/{create-channel-UW2LSL4G.mjs → create-channel-Y6D7YGVX.mjs} +2 -2
- package/dist/lib/neutral/{create-object-RLCOUVAW.mjs → create-object-LOZBRZAF.mjs} +3 -3
- package/dist/lib/neutral/hooks/index.mjs +2 -2
- package/dist/lib/neutral/index.mjs +7 -7
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/meta.mjs +1 -1
- package/dist/lib/neutral/{navigation-resolver-4X4HCQYX.mjs → navigation-resolver-VNFRIC7W.mjs} +3 -3
- package/dist/lib/neutral/navigation-resolver-VNFRIC7W.mjs.map +7 -0
- package/dist/lib/neutral/operations/index.mjs +1 -1
- package/dist/lib/neutral/plugin.mjs +2 -2
- package/dist/lib/neutral/{react-surface-G6KT7TSU.mjs → react-surface-H2EKIMSK.mjs} +3 -2
- package/dist/lib/neutral/{react-surface-G6KT7TSU.mjs.map → react-surface-H2EKIMSK.mjs.map} +3 -3
- package/dist/lib/neutral/translations.mjs +1 -1
- package/dist/lib/neutral/translations.mjs.map +3 -3
- package/dist/lib/neutral/types/index.mjs +1 -1
- package/dist/types/dx.config.d.ts +28 -0
- package/dist/types/dx.config.d.ts.map +1 -0
- 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/index.d.ts +5 -10
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/navigation-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts +6 -6
- package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts.map +1 -1
- package/dist/types/src/containers/ChannelArticle/ChannelArticle.stories.d.ts +1 -1
- package/dist/types/src/containers/ChannelArticle/ChannelArticle.stories.d.ts.map +1 -1
- package/dist/types/src/containers/ThreadArticle/ThreadArticle.stories.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +28 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/paths.d.ts.map +1 -1
- package/dist/types/src/types/ThreadCapabilities.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dx.config.ts +33 -0
- package/package.json +32 -26
- package/src/ThreadPlugin.test.ts +1 -1
- package/src/ThreadPlugin.tsx +1 -1
- package/src/capabilities/app-graph-builder.ts +37 -3
- package/src/capabilities/channel-backend-feed.ts +1 -1
- package/src/capabilities/navigation-resolver.ts +2 -2
- package/src/capabilities/react-surface.tsx +1 -1
- package/src/components/Chat/Chat.tsx +4 -4
- package/src/containers/ChannelArticle/ChannelArticle.stories.tsx +5 -2
- package/src/containers/ChannelArticle/ChannelArticle.tsx +72 -20
- package/src/containers/ThreadArticle/ThreadArticle.stories.tsx +2 -1
- package/src/meta.ts +3 -27
- package/src/paths.ts +4 -2
- package/src/translations.ts +1 -1
- package/src/types/ThreadCapabilities.ts +1 -1
- package/src/types/ThreadOperation.ts +2 -2
- package/dist/lib/neutral/ChannelArticle-H633OM3U.mjs +0 -57
- package/dist/lib/neutral/ChannelArticle-H633OM3U.mjs.map +0 -7
- package/dist/lib/neutral/app-graph-builder-OLKN3VTB.mjs.map +0 -7
- package/dist/lib/neutral/chunk-AWAQTEU6.mjs.map +0 -7
- package/dist/lib/neutral/chunk-OOC6EQ7X.mjs +0 -36
- package/dist/lib/neutral/chunk-OOC6EQ7X.mjs.map +0 -7
- package/dist/lib/neutral/navigation-resolver-4X4HCQYX.mjs.map +0 -7
- /package/dist/lib/neutral/{append-channel-message-J6DXDPBH.mjs.map → append-channel-message-2OZYIIFL.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-P4RSGFS4.mjs.map → chunk-GQCMB5ZC.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-SZXFLBZL.mjs.map → chunk-KUO5HUCH.mjs.map} +0 -0
- /package/dist/lib/neutral/{create-channel-UW2LSL4G.mjs.map → create-channel-Y6D7YGVX.mjs.map} +0 -0
- /package/dist/lib/neutral/{create-object-RLCOUVAW.mjs.map → create-object-LOZBRZAF.mjs.map} +0 -0
package/dx.config.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Config2 } from '@dxos/app-framework/config';
|
|
6
|
+
import { trim } from '@dxos/util';
|
|
7
|
+
|
|
8
|
+
export default Config2.make({
|
|
9
|
+
plugin: {
|
|
10
|
+
key: 'org.dxos.plugin.thread',
|
|
11
|
+
name: 'Threads',
|
|
12
|
+
author: 'DXOS',
|
|
13
|
+
description: trim`
|
|
14
|
+
ThreadPlugin provides chat: channels backed by an ECHO feed and free-standing
|
|
15
|
+
message threads. It renders the channel article and companion surfaces plus a
|
|
16
|
+
thread surface, and contributes the operations that create a default channel on
|
|
17
|
+
space creation, create new channels, and append messages.
|
|
18
|
+
|
|
19
|
+
Channel messages are stored in the channel's feed queue and rendered newest-last
|
|
20
|
+
with a pinned composer; externally-synced channels (carrying foreign-key
|
|
21
|
+
metadata, e.g. Slack/Discord-sourced rooms) render read-only because there is no
|
|
22
|
+
local-write path back to the source. Free-standing threads render their messages
|
|
23
|
+
and append by pushing onto the thread's message list.
|
|
24
|
+
|
|
25
|
+
The shared message and thread UI comes from @dxos/react-ui-thread; the Channel,
|
|
26
|
+
Message, and Thread schema come from @dxos/types. Document comments and the
|
|
27
|
+
comment-thread AI agent live in the @dxos/plugin-comments plugin.
|
|
28
|
+
`,
|
|
29
|
+
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-thread',
|
|
30
|
+
icon: { key: 'ph--video-conference--regular', hue: 'rose' },
|
|
31
|
+
spec: 'PLUGIN.mdl',
|
|
32
|
+
},
|
|
33
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-thread",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1-main.c7dcc2e112",
|
|
4
4
|
"description": "DXOS Threads Surface plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -91,28 +91,31 @@
|
|
|
91
91
|
"types": "dist/types/src/index.d.ts",
|
|
92
92
|
"files": [
|
|
93
93
|
"dist",
|
|
94
|
+
"dx.config.ts",
|
|
94
95
|
"src",
|
|
95
96
|
"PLUGIN.mdl"
|
|
96
97
|
],
|
|
97
98
|
"dependencies": {
|
|
98
|
-
"@
|
|
99
|
-
"@dxos/app-
|
|
100
|
-
"@dxos/
|
|
101
|
-
"@dxos/
|
|
102
|
-
"@dxos/client": "0.
|
|
103
|
-
"@dxos/
|
|
104
|
-
"@dxos/echo": "0.
|
|
105
|
-
"@dxos/
|
|
106
|
-
"@dxos/
|
|
107
|
-
"@dxos/
|
|
108
|
-
"@dxos/plugin-
|
|
109
|
-
"@dxos/plugin-
|
|
110
|
-
"@dxos/
|
|
111
|
-
"@dxos/
|
|
112
|
-
"@dxos/react-
|
|
113
|
-
"@dxos/
|
|
114
|
-
"@dxos/
|
|
115
|
-
"@dxos/
|
|
99
|
+
"@effect-atom/atom-react": "^0.5.0",
|
|
100
|
+
"@dxos/app-framework": "0.9.1-main.c7dcc2e112",
|
|
101
|
+
"@dxos/client": "0.9.1-main.c7dcc2e112",
|
|
102
|
+
"@dxos/app-toolkit": "0.9.1-main.c7dcc2e112",
|
|
103
|
+
"@dxos/client-protocol": "0.9.1-main.c7dcc2e112",
|
|
104
|
+
"@dxos/display-name": "0.9.1-main.c7dcc2e112",
|
|
105
|
+
"@dxos/echo": "0.9.1-main.c7dcc2e112",
|
|
106
|
+
"@dxos/echo-client": "0.9.1-main.c7dcc2e112",
|
|
107
|
+
"@dxos/keys": "0.9.1-main.c7dcc2e112",
|
|
108
|
+
"@dxos/invariant": "0.9.1-main.c7dcc2e112",
|
|
109
|
+
"@dxos/plugin-calls": "0.9.1-main.c7dcc2e112",
|
|
110
|
+
"@dxos/plugin-client": "0.9.1-main.c7dcc2e112",
|
|
111
|
+
"@dxos/plugin-space": "0.9.1-main.c7dcc2e112",
|
|
112
|
+
"@dxos/random": "0.9.1-main.c7dcc2e112",
|
|
113
|
+
"@dxos/react-client": "0.9.1-main.c7dcc2e112",
|
|
114
|
+
"@dxos/plugin-graph": "0.9.1-main.c7dcc2e112",
|
|
115
|
+
"@dxos/react-ui-thread": "0.9.1-main.c7dcc2e112",
|
|
116
|
+
"@dxos/util": "0.9.1-main.c7dcc2e112",
|
|
117
|
+
"@dxos/types": "0.9.1-main.c7dcc2e112",
|
|
118
|
+
"@dxos/compute": "0.9.1-main.c7dcc2e112"
|
|
116
119
|
},
|
|
117
120
|
"devDependencies": {
|
|
118
121
|
"@types/react": "~19.2.7",
|
|
@@ -121,18 +124,21 @@
|
|
|
121
124
|
"react": "~19.2.3",
|
|
122
125
|
"react-dom": "~19.2.3",
|
|
123
126
|
"vite": "^8.0.16",
|
|
124
|
-
"@dxos/plugin-testing": "0.
|
|
125
|
-
"@dxos/react-ui": "0.
|
|
126
|
-
"@dxos/react-ui-form": "0.
|
|
127
|
-
"@dxos/ui-
|
|
127
|
+
"@dxos/plugin-testing": "0.9.1-main.c7dcc2e112",
|
|
128
|
+
"@dxos/react-ui": "0.9.1-main.c7dcc2e112",
|
|
129
|
+
"@dxos/react-ui-form": "0.9.1-main.c7dcc2e112",
|
|
130
|
+
"@dxos/react-ui-menu": "0.9.1-main.c7dcc2e112",
|
|
131
|
+
"@dxos/ui-theme": "0.9.1-main.c7dcc2e112"
|
|
128
132
|
},
|
|
129
133
|
"peerDependencies": {
|
|
134
|
+
"@effect-atom/atom-react": "^0.5.0",
|
|
130
135
|
"effect": "3.21.3",
|
|
131
136
|
"react": "~19.2.3",
|
|
132
137
|
"react-dom": "~19.2.3",
|
|
133
|
-
"@dxos/ui-
|
|
134
|
-
"@dxos/react-ui": "0.
|
|
135
|
-
"@dxos/react-ui
|
|
138
|
+
"@dxos/react-ui-menu": "0.9.1-main.c7dcc2e112",
|
|
139
|
+
"@dxos/react-ui-form": "0.9.1-main.c7dcc2e112",
|
|
140
|
+
"@dxos/react-ui": "0.9.1-main.c7dcc2e112",
|
|
141
|
+
"@dxos/ui-theme": "0.9.1-main.c7dcc2e112"
|
|
136
142
|
},
|
|
137
143
|
"publishConfig": {
|
|
138
144
|
"access": "public"
|
package/src/ThreadPlugin.test.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { ThreadPlugin } from '#plugin';
|
|
|
11
11
|
|
|
12
12
|
import { meta } from './meta';
|
|
13
13
|
|
|
14
|
-
const moduleId = (name: string) => `${meta.
|
|
14
|
+
const moduleId = (name: string) => `${meta.profile.key}.module.${name}`;
|
|
15
15
|
|
|
16
16
|
describe('ThreadPlugin', () => {
|
|
17
17
|
test('modules activate on the expected events', async ({ expect }) => {
|
package/src/ThreadPlugin.tsx
CHANGED
|
@@ -41,7 +41,7 @@ export const ThreadPlugin = Plugin.define(meta).pipe(
|
|
|
41
41
|
activate: ChannelBackendFeed,
|
|
42
42
|
}),
|
|
43
43
|
AppPlugin.addPluginAssetModule({
|
|
44
|
-
asset: { pluginId: meta.
|
|
44
|
+
asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },
|
|
45
45
|
}),
|
|
46
46
|
Plugin.make,
|
|
47
47
|
);
|
|
@@ -6,20 +6,53 @@ import * as Effect from 'effect/Effect';
|
|
|
6
6
|
import * as Option from 'effect/Option';
|
|
7
7
|
|
|
8
8
|
import { Capability } from '@dxos/app-framework';
|
|
9
|
-
import { AppCapabilities,
|
|
9
|
+
import { AppCapabilities, AppNode, TypeSection } from '@dxos/app-toolkit';
|
|
10
10
|
import { isSpace } from '@dxos/client/echo';
|
|
11
11
|
import { Operation } from '@dxos/compute';
|
|
12
|
-
import { Type } from '@dxos/echo';
|
|
12
|
+
import { Obj, Type } from '@dxos/echo';
|
|
13
|
+
import { CallsCapabilities } from '@dxos/plugin-calls/types';
|
|
13
14
|
import { GraphBuilder, Node } from '@dxos/plugin-graph';
|
|
14
15
|
import { SpaceOperation } from '@dxos/plugin-space';
|
|
15
16
|
import { Channel } from '@dxos/types';
|
|
16
17
|
|
|
18
|
+
import { meta } from '#meta';
|
|
19
|
+
|
|
20
|
+
import { getChannelsPath } from '../paths';
|
|
21
|
+
|
|
17
22
|
const channelTypename = Type.getTypename(Channel.Channel);
|
|
18
23
|
|
|
19
24
|
export default Capability.makeModule(
|
|
20
25
|
Effect.fnUntraced(function* () {
|
|
26
|
+
const capabilities = yield* Capability.Service;
|
|
27
|
+
|
|
21
28
|
const extensions = yield* Effect.all([
|
|
22
|
-
createTypeSectionExtension(Channel.Channel),
|
|
29
|
+
TypeSection.createTypeSectionExtension(Channel.Channel),
|
|
30
|
+
|
|
31
|
+
GraphBuilder.createTypeExtension({
|
|
32
|
+
id: 'channelChatCompanion',
|
|
33
|
+
type: Channel.Channel,
|
|
34
|
+
connector: (channel, get) => {
|
|
35
|
+
const [callManager] = get(capabilities.atom(CallsCapabilities.Manager));
|
|
36
|
+
if (!callManager) {
|
|
37
|
+
return Effect.succeed([]);
|
|
38
|
+
}
|
|
39
|
+
const joined = get(callManager.joinedAtom);
|
|
40
|
+
const roomId = get(callManager.roomIdAtom);
|
|
41
|
+
if (!joined || roomId !== Obj.getURI(channel)) {
|
|
42
|
+
return Effect.succeed([]);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return Effect.succeed([
|
|
46
|
+
AppNode.makeCompanion({
|
|
47
|
+
id: 'chat',
|
|
48
|
+
label: ['channel-companion.label', { ns: meta.profile.key }],
|
|
49
|
+
icon: 'ph--hash--regular',
|
|
50
|
+
data: 'chat',
|
|
51
|
+
position: 'first',
|
|
52
|
+
}),
|
|
53
|
+
]);
|
|
54
|
+
},
|
|
55
|
+
}),
|
|
23
56
|
|
|
24
57
|
GraphBuilder.createExtension({
|
|
25
58
|
id: 'channelsSectionActions',
|
|
@@ -35,6 +68,7 @@ export default Capability.makeModule(
|
|
|
35
68
|
Operation.invoke(SpaceOperation.OpenCreateObject, {
|
|
36
69
|
target: space.db,
|
|
37
70
|
typename: channelTypename,
|
|
71
|
+
targetNodeId: getChannelsPath(space.db.spaceId),
|
|
38
72
|
}),
|
|
39
73
|
properties: {
|
|
40
74
|
label: ['add-object.label', { ns: channelTypename }],
|
|
@@ -45,7 +45,7 @@ export const feedChannelBackend: ThreadCapabilities.ChannelBackendProvider = {
|
|
|
45
45
|
invariant(space, 'Space not found');
|
|
46
46
|
const feed = Channel.getFeed(channel);
|
|
47
47
|
invariant(feed, 'Channel is not feed-backed');
|
|
48
|
-
yield* Feed.append(feed, [message]).pipe(Effect.provide(createFeedServiceLayer(space.
|
|
48
|
+
yield* Feed.append(feed, [message]).pipe(Effect.provide(createFeedServiceLayer(space.db)));
|
|
49
49
|
}),
|
|
50
50
|
readOnly: (channel) => Obj.getMeta(channel).keys.length > 0,
|
|
51
51
|
};
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
7
|
import { Capability } from '@dxos/app-framework';
|
|
8
|
-
import { AppCapabilities,
|
|
8
|
+
import { AppCapabilities, TypeSection } from '@dxos/app-toolkit';
|
|
9
9
|
import { Channel } from '@dxos/types';
|
|
10
10
|
|
|
11
11
|
export default Capability.makeModule(
|
|
12
12
|
Effect.fnUntraced(function* () {
|
|
13
13
|
return Capability.contributes(
|
|
14
14
|
AppCapabilities.NavigationPathResolver,
|
|
15
|
-
createTypeSectionPathResolver(Channel.Channel),
|
|
15
|
+
TypeSection.createTypeSectionPathResolver(Channel.Channel),
|
|
16
16
|
);
|
|
17
17
|
}),
|
|
18
18
|
);
|
|
@@ -29,7 +29,7 @@ export default Capability.makeModule(() =>
|
|
|
29
29
|
AppSurface.literal(AppSurface.Article, 'chat'),
|
|
30
30
|
AppSurface.companion(AppSurface.Article, Channel.Channel),
|
|
31
31
|
),
|
|
32
|
-
component: ({ data: { companionTo: channel } }) => <ChannelArticle subject={channel} />,
|
|
32
|
+
component: ({ data: { companionTo: channel } }) => <ChannelArticle subject={channel} chatOnly />,
|
|
33
33
|
}),
|
|
34
34
|
// TODO(burdon): Disambiguate with Channel.
|
|
35
35
|
Surface.create({
|
|
@@ -54,8 +54,8 @@ export type ChatProps = ThemedClassName<{
|
|
|
54
54
|
* `ChannelArticle` and `ThreadArticle`.
|
|
55
55
|
*/
|
|
56
56
|
export const Chat = composable<HTMLDivElement, ChatProps>(
|
|
57
|
-
({ id, identity, members, messages, activity, onSend, autoFocus, current, readOnly }, forwardedRef) => {
|
|
58
|
-
const { t } = useTranslation(meta.
|
|
57
|
+
({ id, identity, members, messages, activity, onSend, autoFocus, current, readOnly, classNames }, forwardedRef) => {
|
|
58
|
+
const { t } = useTranslation(meta.profile.key);
|
|
59
59
|
|
|
60
60
|
const components = useMemo(() => ({ Object: ObjectTile }), []);
|
|
61
61
|
|
|
@@ -80,7 +80,7 @@ export const Chat = composable<HTMLDivElement, ChatProps>(
|
|
|
80
80
|
|
|
81
81
|
return (
|
|
82
82
|
<Thread.Root getMetadata={getMetadata} components={components} identityDid={identity?.did} editable={false}>
|
|
83
|
-
<Thread.Content id={id} current={current} classNames='dx-container' ref={forwardedRef}>
|
|
83
|
+
<Thread.Content id={id} current={current} classNames={['dx-container', classNames]} ref={forwardedRef}>
|
|
84
84
|
<Thread.Messages messages={messages} />
|
|
85
85
|
{!readOnly && (
|
|
86
86
|
<>
|
|
@@ -109,7 +109,7 @@ const ObjectTile: ObjectTileComponent = ({ subject }) => {
|
|
|
109
109
|
return (
|
|
110
110
|
<Card.Root className={mx('grid col-span-3 py-1 pr-4', hoverableControls, hoverableFocusedWithinControls)}>
|
|
111
111
|
<Surface.Surface
|
|
112
|
-
type={AppSurface.
|
|
112
|
+
type={AppSurface.CardContent}
|
|
113
113
|
limit={1}
|
|
114
114
|
data={{ subject } satisfies AppSurface.ObjectCardData}
|
|
115
115
|
fallback={Fallback}
|
|
@@ -9,9 +9,11 @@ import React from 'react';
|
|
|
9
9
|
import { Capability } from '@dxos/app-framework';
|
|
10
10
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
11
11
|
import { AppCapabilities } from '@dxos/app-toolkit';
|
|
12
|
+
import { AppSurface } from '@dxos/app-toolkit/ui';
|
|
12
13
|
import { Feed, Query } from '@dxos/echo';
|
|
13
14
|
import { createFeedServiceLayer } from '@dxos/echo-client';
|
|
14
15
|
import { invariant } from '@dxos/invariant';
|
|
16
|
+
import { CallsPlugin } from '@dxos/plugin-calls/plugin';
|
|
15
17
|
import { ClientPlugin } from '@dxos/plugin-client/testing';
|
|
16
18
|
import { initializeIdentity } from '@dxos/plugin-client/testing';
|
|
17
19
|
import { SpacePlugin } from '@dxos/plugin-space/testing';
|
|
@@ -80,11 +82,12 @@ const meta = {
|
|
|
80
82
|
blocks: [{ _tag: 'text', text: 'Messages are stored in the feed.' }],
|
|
81
83
|
}),
|
|
82
84
|
];
|
|
83
|
-
yield* Feed.append(feed, seed).pipe(Effect.provide(createFeedServiceLayer(personalSpace.
|
|
85
|
+
yield* Feed.append(feed, seed).pipe(Effect.provide(createFeedServiceLayer(personalSpace.db)));
|
|
84
86
|
}),
|
|
85
87
|
}),
|
|
86
88
|
SpacePlugin({}),
|
|
87
89
|
ThreadPlugin(),
|
|
90
|
+
CallsPlugin(),
|
|
88
91
|
],
|
|
89
92
|
}),
|
|
90
93
|
],
|
|
@@ -102,7 +105,7 @@ export const Default: Story = {
|
|
|
102
105
|
// Fixed room for testing.
|
|
103
106
|
subject: undefined,
|
|
104
107
|
attendableId: 'story',
|
|
105
|
-
role:
|
|
108
|
+
role: AppSurface.Article.role,
|
|
106
109
|
roomId: '04a1d1911703b8e929d0649021a965',
|
|
107
110
|
},
|
|
108
111
|
};
|
|
@@ -2,25 +2,35 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import { Atom, useAtomValue } from '@effect-atom/atom-react';
|
|
6
|
+
import React, { useCallback } from 'react';
|
|
6
7
|
|
|
7
|
-
import { useCapabilities, useOperationInvoker } from '@dxos/app-framework/ui';
|
|
8
|
-
import {
|
|
8
|
+
import { Surface, useCapabilities, useOperationInvoker } from '@dxos/app-framework/ui';
|
|
9
|
+
import { AppSurface } from '@dxos/app-toolkit/ui';
|
|
9
10
|
import { Obj } from '@dxos/echo';
|
|
11
|
+
import { CallsCapabilities } from '@dxos/plugin-calls/types';
|
|
10
12
|
import { getSpace, useMembers } from '@dxos/react-client/echo';
|
|
11
13
|
import { useIdentity } from '@dxos/react-client/halo';
|
|
12
14
|
import { Panel } from '@dxos/react-ui';
|
|
15
|
+
import { Menu, MenuBuilder, useMenuBuilder } from '@dxos/react-ui-menu';
|
|
13
16
|
import { type Channel } from '@dxos/types';
|
|
14
17
|
|
|
15
18
|
import { Chat } from '#components';
|
|
16
19
|
import { useMessages, useStatus } from '#hooks';
|
|
20
|
+
import { meta } from '#meta';
|
|
17
21
|
import { ThreadCapabilities, ThreadOperation, resolveProvider } from '#types';
|
|
18
22
|
|
|
23
|
+
// Stable fallbacks so `useAtomValue` always receives an atom when plugin-calls isn't present.
|
|
24
|
+
const NOT_JOINED = Atom.make(false);
|
|
25
|
+
const NO_ROOM = Atom.make<string | undefined>(undefined);
|
|
26
|
+
|
|
19
27
|
export type ChannelArticleProps = AppSurface.ObjectArticleProps<
|
|
20
28
|
Channel.Channel | undefined,
|
|
21
29
|
{
|
|
22
30
|
roomId?: string;
|
|
23
31
|
fullscreen?: boolean;
|
|
32
|
+
/** Always render the chat, even while in this channel's call (used by the in-call chat companion). */
|
|
33
|
+
chatOnly?: boolean;
|
|
24
34
|
}
|
|
25
35
|
>;
|
|
26
36
|
|
|
@@ -29,12 +39,10 @@ export type ChannelArticleProps = AppSurface.ObjectArticleProps<
|
|
|
29
39
|
* are read and written through the channel's backend provider (resolved by
|
|
30
40
|
* `channel.backend.kind`), so the container is agnostic to where messages are
|
|
31
41
|
* stored. Read-only state defaults to the provider's policy, or to "channel
|
|
32
|
-
* carries foreign-key `Obj.Meta`" when the provider has none.
|
|
33
|
-
*
|
|
34
|
-
* The "Start video call" action and the in-call surface are contributed by
|
|
35
|
-
* plugin-calls — this container is call-agnostic.
|
|
42
|
+
* carries foreign-key `Obj.Meta`" when the provider has none. When plugin-calls is present, a
|
|
43
|
+
* "Start video call" action switches the article to the call surface and the chat moves to a companion.
|
|
36
44
|
*/
|
|
37
|
-
export const ChannelArticle = ({ subject: channel }: ChannelArticleProps) => {
|
|
45
|
+
export const ChannelArticle = ({ role, subject: channel, attendableId, chatOnly }: ChannelArticleProps) => {
|
|
38
46
|
const identity = useIdentity();
|
|
39
47
|
const space = channel ? getSpace(channel) : undefined;
|
|
40
48
|
const members = useMembers(space?.id);
|
|
@@ -47,6 +55,36 @@ export const ChannelArticle = ({ subject: channel }: ChannelArticleProps) => {
|
|
|
47
55
|
const messages = useMessages(channel);
|
|
48
56
|
const readOnly = channel ? (provider?.readOnly?.(channel) ?? Obj.getMeta(channel).keys.length > 0) : false;
|
|
49
57
|
|
|
58
|
+
const callProvider = useCapabilities(CallsCapabilities.CallTransportProvider)[0];
|
|
59
|
+
const callManager = useCapabilities(CallsCapabilities.Manager)[0];
|
|
60
|
+
const joined = useAtomValue(callManager?.joinedAtom ?? NOT_JOINED);
|
|
61
|
+
const currentRoomId = useAtomValue(callManager?.roomIdAtom ?? NO_ROOM);
|
|
62
|
+
// `chatOnly` (the in-call chat companion) keeps showing messages so the call lives only in the primary.
|
|
63
|
+
const inThisCall = !!id && joined && currentRoomId === id;
|
|
64
|
+
const showCall = inThisCall && !chatOnly;
|
|
65
|
+
const canStartCall = !!callProvider && !inThisCall;
|
|
66
|
+
|
|
67
|
+
const handleStartCall = useCallback(async () => {
|
|
68
|
+
if (!callProvider || !id) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
await callProvider.join(id);
|
|
72
|
+
}, [callProvider, id]);
|
|
73
|
+
|
|
74
|
+
const menuActions = useMenuBuilder(() => {
|
|
75
|
+
const builder = MenuBuilder.make().root({ label: ['channel-toolbar.title', { ns: meta.profile.key }] });
|
|
76
|
+
if (canStartCall) {
|
|
77
|
+
builder.action(
|
|
78
|
+
'start-video-call',
|
|
79
|
+
{ label: ['start-video-call.menu', { ns: meta.profile.key }], icon: 'ph--video-camera--regular' },
|
|
80
|
+
() => {
|
|
81
|
+
void handleStartCall();
|
|
82
|
+
},
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return builder.build();
|
|
86
|
+
}, [canStartCall, handleStartCall]);
|
|
87
|
+
|
|
50
88
|
const handleSend = (text: string) => {
|
|
51
89
|
if (!channel || !identity || readOnly) {
|
|
52
90
|
return false;
|
|
@@ -66,18 +104,32 @@ export const ChannelArticle = ({ subject: channel }: ChannelArticleProps) => {
|
|
|
66
104
|
}
|
|
67
105
|
|
|
68
106
|
return (
|
|
69
|
-
<Panel.Root
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
107
|
+
<Panel.Root role={role}>
|
|
108
|
+
{canStartCall && (
|
|
109
|
+
<Menu.Root {...menuActions} attendableId={attendableId}>
|
|
110
|
+
<Panel.Toolbar asChild>
|
|
111
|
+
<Menu.Toolbar />
|
|
112
|
+
</Panel.Toolbar>
|
|
113
|
+
</Menu.Root>
|
|
114
|
+
)}
|
|
115
|
+
{showCall ? (
|
|
116
|
+
<Panel.Content>
|
|
117
|
+
<Surface.Surface type={AppSurface.Article} data={{ subject: { roomId: id }, attendableId }} limit={1} />
|
|
118
|
+
</Panel.Content>
|
|
119
|
+
) : (
|
|
120
|
+
<Panel.Content asChild>
|
|
121
|
+
<Chat
|
|
122
|
+
id={id}
|
|
123
|
+
classNames='dx-document'
|
|
124
|
+
identity={identity ?? undefined}
|
|
125
|
+
members={members}
|
|
126
|
+
messages={messages}
|
|
127
|
+
activity={activity}
|
|
128
|
+
onSend={handleSend}
|
|
129
|
+
readOnly={readOnly}
|
|
130
|
+
/>
|
|
131
|
+
</Panel.Content>
|
|
132
|
+
)}
|
|
81
133
|
</Panel.Root>
|
|
82
134
|
);
|
|
83
135
|
};
|
|
@@ -8,6 +8,7 @@ import React, { useState } from 'react';
|
|
|
8
8
|
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
9
9
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
10
10
|
import { Surface } from '@dxos/app-framework/ui';
|
|
11
|
+
import { AppSurface } from '@dxos/app-toolkit/ui';
|
|
11
12
|
import { corePlugins } from '@dxos/plugin-testing';
|
|
12
13
|
import { random } from '@dxos/random';
|
|
13
14
|
import { useClient } from '@dxos/react-client';
|
|
@@ -62,7 +63,7 @@ const meta = {
|
|
|
62
63
|
Capabilities.ReactSurface,
|
|
63
64
|
Surface.create({
|
|
64
65
|
id: 'test',
|
|
65
|
-
|
|
66
|
+
filter: Surface.makeFilter(AppSurface.CardContent),
|
|
66
67
|
component: ({ role }) => <span>{JSON.stringify({ role })}</span>,
|
|
67
68
|
}),
|
|
68
69
|
),
|
package/src/meta.ts
CHANGED
|
@@ -3,33 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Plugin } from '@dxos/app-framework';
|
|
6
|
-
import { DXN } from '@dxos/keys';
|
|
7
|
-
import { trim } from '@dxos/util';
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
key: DXN.make('org.dxos.plugin.thread'),
|
|
11
|
-
name: 'Threads',
|
|
12
|
-
author: 'DXOS',
|
|
13
|
-
description: trim`
|
|
14
|
-
ThreadPlugin provides chat: channels backed by an ECHO feed and free-standing
|
|
15
|
-
message threads. It renders the channel article and companion surfaces plus a
|
|
16
|
-
thread surface, and contributes the operations that create a default channel on
|
|
17
|
-
space creation, create new channels, and append messages.
|
|
7
|
+
import config from '../dx.config';
|
|
18
8
|
|
|
19
|
-
|
|
20
|
-
with a pinned composer; externally-synced channels (carrying foreign-key
|
|
21
|
-
metadata, e.g. Slack/Discord-sourced rooms) render read-only because there is no
|
|
22
|
-
local-write path back to the source. Free-standing threads render their messages
|
|
23
|
-
and append by pushing onto the thread's message list.
|
|
9
|
+
export const meta = Plugin.getMetaFromConfig(config);
|
|
24
10
|
|
|
25
|
-
|
|
26
|
-
Message, and Thread schema come from @dxos/types. Document comments and the
|
|
27
|
-
comment-thread AI agent live in the @dxos/plugin-comments plugin.
|
|
28
|
-
`,
|
|
29
|
-
icon: 'ph--video-conference--regular',
|
|
30
|
-
iconHue: 'rose',
|
|
31
|
-
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-thread',
|
|
32
|
-
spec: 'PLUGIN.mdl',
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
export const THREAD_ITEM = `${meta.id}.item`;
|
|
11
|
+
export const THREAD_ITEM = `${meta.profile.key}.item`;
|
package/src/paths.ts
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Paths } from '@dxos/app-toolkit';
|
|
6
6
|
import { Channel } from '@dxos/types';
|
|
7
7
|
|
|
8
|
-
const { getSectionPath: getChannelsPath, getObjectPath: getChannelPath } = createTypeSectionPaths(
|
|
8
|
+
const { getSectionPath: getChannelsPath, getObjectPath: getChannelPath } = Paths.createTypeSectionPaths(
|
|
9
|
+
Channel.Channel,
|
|
10
|
+
);
|
|
9
11
|
|
|
10
12
|
export { getChannelsPath, getChannelPath };
|
package/src/translations.ts
CHANGED
|
@@ -23,7 +23,7 @@ export const translations = [
|
|
|
23
23
|
'delete-object.label': 'Delete channel',
|
|
24
24
|
'object-deleted.label': 'Channel deleted',
|
|
25
25
|
},
|
|
26
|
-
[meta.
|
|
26
|
+
[meta.profile.key]: {
|
|
27
27
|
'plugin.name': 'Chat',
|
|
28
28
|
'channel-title.label': 'Title',
|
|
29
29
|
'message.placeholder': 'Reply…',
|
|
@@ -44,4 +44,4 @@ export interface ChannelBackendProvider {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/** Registry of channel-message backends. Collect with `Capability.getAll`. */
|
|
47
|
-
export const ChannelBackend = Capability.make<ChannelBackendProvider>(`${meta.
|
|
47
|
+
export const ChannelBackend = Capability.make<ChannelBackendProvider>(`${meta.profile.key}.capability.channel-backend`);
|
|
@@ -13,7 +13,7 @@ import { Actor, Channel } from '@dxos/types';
|
|
|
13
13
|
|
|
14
14
|
import { meta } from '#meta';
|
|
15
15
|
|
|
16
|
-
const makeKey = (name: string) => DXN.make(`${meta.
|
|
16
|
+
const makeKey = (name: string) => DXN.make(`${meta.profile.key}.operation.${name}`);
|
|
17
17
|
|
|
18
18
|
export const CreateChannel = Operation.make({
|
|
19
19
|
meta: { key: makeKey('createChannel'), name: 'Create Channel', icon: 'ph--hash--regular' },
|
|
@@ -37,7 +37,7 @@ export const AppendChannelMessage = Operation.make({
|
|
|
37
37
|
name: 'Append Channel Message',
|
|
38
38
|
icon: 'ph--chat-text--regular',
|
|
39
39
|
},
|
|
40
|
-
// Note: Feed.FeedService is provided inside the handler from space.
|
|
40
|
+
// Note: Feed.FeedService is provided inside the handler from space.db, not at the
|
|
41
41
|
// operation level — the runtime can't fulfill it without a space context.
|
|
42
42
|
services: [Capability.Service],
|
|
43
43
|
input: Schema.Struct({
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import "./chunk-J5LGTIGS.mjs";
|
|
2
|
-
|
|
3
|
-
// src/containers/ChannelArticle/ChannelArticle.tsx
|
|
4
|
-
import React from "react";
|
|
5
|
-
import { useCapabilities, useOperationInvoker } from "@dxos/app-framework/ui";
|
|
6
|
-
import { Obj } from "@dxos/echo";
|
|
7
|
-
import { getSpace, useMembers } from "@dxos/react-client/echo";
|
|
8
|
-
import { useIdentity } from "@dxos/react-client/halo";
|
|
9
|
-
import { Panel } from "@dxos/react-ui";
|
|
10
|
-
import { Chat } from "#components";
|
|
11
|
-
import { useMessages, useStatus } from "#hooks";
|
|
12
|
-
import { ThreadCapabilities, ThreadOperation, resolveProvider } from "#types";
|
|
13
|
-
var ChannelArticle = ({ subject: channel }) => {
|
|
14
|
-
const identity = useIdentity();
|
|
15
|
-
const space = channel ? getSpace(channel) : void 0;
|
|
16
|
-
const members = useMembers(space?.id);
|
|
17
|
-
const id = channel ? Obj.getURI(channel) : void 0;
|
|
18
|
-
const activity = useStatus(space, id);
|
|
19
|
-
const { invokePromise } = useOperationInvoker();
|
|
20
|
-
const providers = useCapabilities(ThreadCapabilities.ChannelBackend);
|
|
21
|
-
const provider = channel ? resolveProvider(providers, channel.backend.kind) : void 0;
|
|
22
|
-
const messages = useMessages(channel);
|
|
23
|
-
const readOnly = channel ? provider?.readOnly?.(channel) ?? Obj.getMeta(channel).keys.length > 0 : false;
|
|
24
|
-
const handleSend = (text) => {
|
|
25
|
-
if (!channel || !identity || readOnly) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
void invokePromise(ThreadOperation.AppendChannelMessage, {
|
|
29
|
-
channel,
|
|
30
|
-
sender: {
|
|
31
|
-
identityDid: identity.did
|
|
32
|
-
},
|
|
33
|
-
text
|
|
34
|
-
});
|
|
35
|
-
return true;
|
|
36
|
-
};
|
|
37
|
-
if (!space || !channel || !id) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
return /* @__PURE__ */ React.createElement(Panel.Root, {
|
|
41
|
-
classNames: "dx-document"
|
|
42
|
-
}, /* @__PURE__ */ React.createElement(Panel.Content, {
|
|
43
|
-
asChild: true
|
|
44
|
-
}, /* @__PURE__ */ React.createElement(Chat, {
|
|
45
|
-
id,
|
|
46
|
-
identity: identity ?? void 0,
|
|
47
|
-
members,
|
|
48
|
-
messages,
|
|
49
|
-
activity,
|
|
50
|
-
onSend: handleSend,
|
|
51
|
-
readOnly
|
|
52
|
-
})));
|
|
53
|
-
};
|
|
54
|
-
export {
|
|
55
|
-
ChannelArticle as default
|
|
56
|
-
};
|
|
57
|
-
//# sourceMappingURL=ChannelArticle-H633OM3U.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/containers/ChannelArticle/ChannelArticle.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { useCapabilities, useOperationInvoker } from '@dxos/app-framework/ui';\nimport { type AppSurface } from '@dxos/app-toolkit/ui';\nimport { Obj } from '@dxos/echo';\nimport { getSpace, useMembers } from '@dxos/react-client/echo';\nimport { useIdentity } from '@dxos/react-client/halo';\nimport { Panel } from '@dxos/react-ui';\nimport { type Channel } from '@dxos/types';\n\nimport { Chat } from '#components';\nimport { useMessages, useStatus } from '#hooks';\nimport { ThreadCapabilities, ThreadOperation, resolveProvider } from '#types';\n\nexport type ChannelArticleProps = AppSurface.ObjectArticleProps<\n Channel.Channel | undefined,\n {\n roomId?: string;\n fullscreen?: boolean;\n }\n>;\n\n/**\n * Channel article: renders the channel chat inside a document panel. Messages\n * are read and written through the channel's backend provider (resolved by\n * `channel.backend.kind`), so the container is agnostic to where messages are\n * stored. Read-only state defaults to the provider's policy, or to \"channel\n * carries foreign-key `Obj.Meta`\" when the provider has none.\n *\n * The \"Start video call\" action and the in-call surface are contributed by\n * plugin-calls — this container is call-agnostic.\n */\nexport const ChannelArticle = ({ subject: channel }: ChannelArticleProps) => {\n const identity = useIdentity();\n const space = channel ? getSpace(channel) : undefined;\n const members = useMembers(space?.id);\n const id = channel ? Obj.getURI(channel) : undefined;\n const activity = useStatus(space, id);\n const { invokePromise } = useOperationInvoker();\n\n const providers = useCapabilities(ThreadCapabilities.ChannelBackend);\n const provider = channel ? resolveProvider(providers, channel.backend.kind) : undefined;\n const messages = useMessages(channel);\n const readOnly = channel ? (provider?.readOnly?.(channel) ?? Obj.getMeta(channel).keys.length > 0) : false;\n\n const handleSend = (text: string) => {\n if (!channel || !identity || readOnly) {\n return false;\n }\n\n void invokePromise(ThreadOperation.AppendChannelMessage, {\n channel,\n sender: { identityDid: identity.did },\n text,\n });\n\n return true;\n };\n\n if (!space || !channel || !id) {\n return null;\n }\n\n return (\n <Panel.Root classNames='dx-document'>\n <Panel.Content asChild>\n <Chat\n id={id}\n identity={identity ?? undefined}\n members={members}\n messages={messages}\n activity={activity}\n onSend={handleSend}\n readOnly={readOnly}\n />\n </Panel.Content>\n </Panel.Root>\n );\n};\n"],
|
|
5
|
-
"mappings": ";;;AAIA,OAAOA,WAAW;AAElB,SAASC,iBAAiBC,2BAA2B;AAErD,SAASC,WAAW;AACpB,SAASC,UAAUC,kBAAkB;AACrC,SAASC,mBAAmB;AAC5B,SAASC,aAAa;AAGtB,SAASC,YAAY;AACrB,SAASC,aAAaC,iBAAiB;AACvC,SAASC,oBAAoBC,iBAAiBC,uBAAuB;AAoB9D,IAAMC,iBAAiB,CAAC,EAAEC,SAASC,QAAO,MAAuB;AACtE,QAAMC,WAAWX,YAAAA;AACjB,QAAMY,QAAQF,UAAUZ,SAASY,OAAAA,IAAWG;AAC5C,QAAMC,UAAUf,WAAWa,OAAOG,EAAAA;AAClC,QAAMA,KAAKL,UAAUb,IAAImB,OAAON,OAAAA,IAAWG;AAC3C,QAAMI,WAAWb,UAAUQ,OAAOG,EAAAA;AAClC,QAAM,EAAEG,cAAa,IAAKtB,oBAAAA;AAE1B,QAAMuB,YAAYxB,gBAAgBU,mBAAmBe,cAAc;AACnE,QAAMC,WAAWX,UAAUH,gBAAgBY,WAAWT,QAAQY,QAAQC,IAAI,IAAIV;AAC9E,QAAMW,WAAWrB,YAAYO,OAAAA;AAC7B,QAAMe,WAAWf,UAAWW,UAAUI,WAAWf,OAAAA,KAAYb,IAAI6B,QAAQhB,OAAAA,EAASiB,KAAKC,SAAS,IAAK;AAErG,QAAMC,aAAa,CAACC,SAAAA;AAClB,QAAI,CAACpB,WAAW,CAACC,YAAYc,UAAU;AACrC,aAAO;IACT;AAEA,SAAKP,cAAcZ,gBAAgByB,sBAAsB;MACvDrB;MACAsB,QAAQ;QAAEC,aAAatB,SAASuB;MAAI;MACpCJ;IACF,CAAA;AAEA,WAAO;EACT;AAEA,MAAI,CAAClB,SAAS,CAACF,WAAW,CAACK,IAAI;AAC7B,WAAO;EACT;AAEA,SACE,sBAAA,cAACd,MAAMkC,MAAI;IAACC,YAAW;KACrB,sBAAA,cAACnC,MAAMoC,SAAO;IAACC,SAAAA;KACb,sBAAA,cAACpC,MAAAA;IACCa;IACAJ,UAAUA,YAAYE;IACtBC;IACAU;IACAP;IACAsB,QAAQV;IACRJ;;AAKV;",
|
|
6
|
-
"names": ["React", "useCapabilities", "useOperationInvoker", "Obj", "getSpace", "useMembers", "useIdentity", "Panel", "Chat", "useMessages", "useStatus", "ThreadCapabilities", "ThreadOperation", "resolveProvider", "ChannelArticle", "subject", "channel", "identity", "space", "undefined", "members", "id", "getURI", "activity", "invokePromise", "providers", "ChannelBackend", "provider", "backend", "kind", "messages", "readOnly", "getMeta", "keys", "length", "handleSend", "text", "AppendChannelMessage", "sender", "identityDid", "did", "Root", "classNames", "Content", "asChild", "onSend"]
|
|
7
|
-
}
|