@dxos/react-ui-thread 0.4.10-main.b3cf40d → 0.4.10-main.bf8d896

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.
@@ -1,6 +1,6 @@
1
1
  import '@dxosTheme';
2
2
  import React from 'react';
3
- import { TextObject } from '@dxos/echo-schema';
3
+ import { TextV0Type } from '@braneframe/types';
4
4
  import { type Range } from '@dxos/react-ui-editor';
5
5
  import { type MessageEntity } from '../types';
6
6
  type StoryCommentThread = {
@@ -9,7 +9,7 @@ type StoryCommentThread = {
9
9
  range?: Range;
10
10
  yPos?: number;
11
11
  messages: MessageEntity<{
12
- text: TextObject;
12
+ content?: TextV0Type;
13
13
  }>[];
14
14
  };
15
15
  type StoryProps = {
@@ -1 +1 @@
1
- {"version":3,"file":"Comments.stories.d.ts","sourceRoot":"","sources":["../../../../src/Thread/Comments.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AAGpB,OAAO,KAAwD,MAAM,OAAO,CAAC;AAE7E,OAAO,EAAkB,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAK/D,OAAO,EAML,KAAK,KAAK,EAMX,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAoE9C,KAAK,kBAAkB,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,CAAC,EAAE,CAAC;CACjD,CAAC;AAqIF,KAAK,UAAU,GAAG;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;;;;;;;;;;mBA+He,UAAU;;;;;;;;;;;;;;;;;;;;;AAJ3B,wBAME;AAWF,eAAO,MAAM,OAAO;;;;CAInB,CAAC"}
1
+ {"version":3,"file":"Comments.stories.d.ts","sourceRoot":"","sources":["../../../../src/Thread/Comments.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AAGpB,OAAO,KAAwD,MAAM,OAAO,CAAC;AAE7E,OAAO,EAAe,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAO5D,OAAO,EAML,KAAK,KAAK,EAMX,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAmE9C,KAAK,kBAAkB,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,CAAC;QAAE,OAAO,CAAC,EAAE,UAAU,CAAA;KAAE,CAAC,EAAE,CAAC;CACrD,CAAC;AA6IF,KAAK,UAAU,GAAG;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;;;;;;;;;;mBA+He,UAAU;;;;;;;;;;;;;;;;;;;;;AAJ3B,wBAME;AAWF,eAAO,MAAM,OAAO;;;;CAInB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Thread.stories.d.ts","sourceRoot":"","sources":["../../../../src/Thread/Thread.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AACpB,OAAO,KAA4B,MAAM,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;AAwEjD,wBAME;AAEF,eAAO,MAAM,OAAO,IAAK,CAAC"}
1
+ {"version":3,"file":"Thread.stories.d.ts","sourceRoot":"","sources":["../../../../src/Thread/Thread.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AACpB,OAAO,KAAoC,MAAM,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;AAwFzD,wBAME;AAEF,eAAO,MAAM,OAAO,IAAK,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-thread",
3
- "version": "0.4.10-main.b3cf40d",
3
+ "version": "0.4.10-main.bf8d896",
4
4
  "description": "A set of components to use with threads, including comments and messages.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -18,11 +18,11 @@
18
18
  "dependencies": {
19
19
  "@radix-ui/react-primitive": "^1.0.2",
20
20
  "date-fns": "^3.3.1",
21
- "@dxos/react-ui-editor": "0.4.10-main.b3cf40d",
22
- "@dxos/react-ui": "0.4.10-main.b3cf40d",
23
- "@dxos/react-ui-mosaic": "0.4.10-main.b3cf40d",
24
- "@dxos/react-ui-theme": "0.4.10-main.b3cf40d",
25
- "@dxos/util": "0.4.10-main.b3cf40d"
21
+ "@dxos/react-ui": "0.4.10-main.bf8d896",
22
+ "@dxos/react-ui-mosaic": "0.4.10-main.bf8d896",
23
+ "@dxos/util": "0.4.10-main.bf8d896",
24
+ "@dxos/react-ui-editor": "0.4.10-main.bf8d896",
25
+ "@dxos/react-ui-theme": "0.4.10-main.bf8d896"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@phosphor-icons/react": "^2.0.5",
@@ -30,13 +30,14 @@
30
30
  "@types/react-dom": "^18.0.6",
31
31
  "react": "^18.2.0",
32
32
  "react-dom": "^18.2.0",
33
- "vite": "^5.1.5",
33
+ "vite": "^5.1.7",
34
34
  "vite-plugin-turbosnap": "^1.0.2",
35
- "@dxos/echo-schema": "0.4.10-main.b3cf40d",
36
- "@dxos/random": "0.4.10-main.b3cf40d",
37
- "@dxos/storybook-utils": "0.4.10-main.b3cf40d",
38
- "@dxos/keys": "0.4.10-main.b3cf40d",
39
- "@dxos/log": "0.4.10-main.b3cf40d"
35
+ "@braneframe/types": "0.4.10-main.bf8d896",
36
+ "@dxos/echo-schema": "0.4.10-main.bf8d896",
37
+ "@dxos/keys": "0.4.10-main.bf8d896",
38
+ "@dxos/log": "0.4.10-main.bf8d896",
39
+ "@dxos/storybook-utils": "0.4.10-main.bf8d896",
40
+ "@dxos/random": "0.4.10-main.bf8d896"
40
41
  },
41
42
  "peerDependencies": {
42
43
  "@phosphor-icons/react": "^2.0.5",
@@ -7,7 +7,9 @@ import '@dxosTheme';
7
7
  import { Check, Trash } from '@phosphor-icons/react';
8
8
  import React, { type FC, useEffect, useMemo, useRef, useState } from 'react';
9
9
 
10
- import { getTextContent, TextObject } from '@dxos/echo-schema';
10
+ import { MessageType, TextV0Type } from '@braneframe/types';
11
+ import * as E from '@dxos/echo-schema';
12
+ import { createDocAccessor } from '@dxos/echo-schema';
11
13
  import { PublicKey } from '@dxos/keys';
12
14
  import { log } from '@dxos/log';
13
15
  import { faker } from '@dxos/random';
@@ -23,7 +25,7 @@ import {
23
25
  createBasicExtensions,
24
26
  createThemeExtensions,
25
27
  automerge,
26
- useDocAccessor,
28
+ listener,
27
29
  } from '@dxos/react-ui-editor';
28
30
  import { withTheme } from '@dxos/storybook-utils';
29
31
 
@@ -42,7 +44,7 @@ const authorId = PublicKey.random().toHex();
42
44
 
43
45
  const Editor: FC<{
44
46
  id?: string;
45
- item: { text: TextObject };
47
+ item: TextV0Type;
46
48
  comments: Comment[];
47
49
  selected?: string;
48
50
  onCreateComment: CommentsOptions['onCreate'];
@@ -62,15 +64,14 @@ const Editor: FC<{
62
64
  const [selected, setSelected] = useState<string>();
63
65
 
64
66
  const { themeMode } = useThemeContext();
65
- const { doc, accessor } = useDocAccessor(item.text);
66
67
  const { parentRef, view } = useTextEditor(
67
68
  () => ({
68
69
  id,
69
- doc,
70
+ doc: item.content,
70
71
  extensions: [
71
72
  createBasicExtensions(),
72
73
  createThemeExtensions({ themeMode }),
73
- automerge(accessor),
74
+ automerge(createDocAccessor(item, ['content'])),
74
75
  comments({
75
76
  onCreate: onCreateComment,
76
77
  onDelete: onDeleteComment,
@@ -79,7 +80,7 @@ const Editor: FC<{
79
80
  }),
80
81
  ],
81
82
  }),
82
- [doc, accessor, themeMode],
83
+ [id, item, themeMode],
83
84
  );
84
85
  useComments(view, id, commentRanges);
85
86
  useEffect(() => {
@@ -103,12 +104,13 @@ type StoryCommentThread = {
103
104
  cursor?: string;
104
105
  range?: Range;
105
106
  yPos?: number;
106
- messages: MessageEntity<{ text: TextObject }>[];
107
+ messages: MessageEntity<{ content?: TextV0Type }>[];
107
108
  };
108
109
 
109
- const StoryMessageBlock = (props: MessageBlockProps<{ text: TextObject }>) => {
110
+ const StoryMessageBlock = (props: MessageBlockProps<{ content?: TextV0Type }>) => {
110
111
  const { themeMode } = useThemeContext();
111
- const { doc, accessor } = useDocAccessor(props.block.text);
112
+ const doc = props.block.content?.content;
113
+ const accessor = E.createDocAccessor(props.block.content!, ['content']);
112
114
  const { parentRef } = useTextEditor(
113
115
  () => ({
114
116
  doc,
@@ -133,15 +135,17 @@ const StoryThread: FC<{
133
135
  }> = ({ thread, selected, onSelect, onResolve }) => {
134
136
  const containerRef = useRef<HTMLDivElement>(null);
135
137
  const { themeMode } = useThemeContext();
136
- const [item, setItem] = useState({ text: new TextObject() });
137
- const { doc, accessor } = useDocAccessor(item.text);
138
+ // TODO(wittjosiah): This is a hack to reset the editor after a message is sent.
139
+ const [_count, _setCount] = useState(0);
140
+ const rerenderEditor = () => _setCount((count) => count + 1);
141
+ const messageRef = useRef('');
138
142
  const extensions = useMemo(
139
143
  () => [
140
144
  createBasicExtensions({ placeholder: 'Enter comment' }),
141
145
  createThemeExtensions({ themeMode }),
142
- automerge(accessor),
146
+ listener({ onChange: (text) => (messageRef.current = text) }),
143
147
  ],
144
- [themeMode, accessor],
148
+ [themeMode, _count],
145
149
  );
146
150
 
147
151
  const [autoFocus, setAutoFocus] = useState(false);
@@ -156,15 +160,21 @@ const StoryThread: FC<{
156
160
  }, [selected]);
157
161
 
158
162
  const handleCreateMessage = () => {
159
- const text = getTextContent(item.text)?.trim();
160
- if (text?.length) {
161
- thread.messages.push({
162
- id: item.text.id,
163
- authorId,
164
- blocks: [{ text: item.text, timestamp: new Date().toISOString() }],
163
+ if (messageRef.current?.length) {
164
+ const message = E.object(MessageType, {
165
+ from: { identityKey: authorId },
166
+ blocks: [
167
+ {
168
+ timestamp: new Date().toISOString(),
169
+ content: E.object(TextV0Type, { content: messageRef.current }),
170
+ },
171
+ ],
165
172
  });
166
- setItem({ text: new TextObject() });
173
+ thread.messages.push(message);
174
+
175
+ messageRef.current = '';
167
176
  setAutoFocus(true);
177
+ rerenderEditor();
168
178
  }
169
179
  };
170
180
 
@@ -182,13 +192,12 @@ const StoryThread: FC<{
182
192
  </ThreadHeading>
183
193
 
184
194
  {thread.messages.map((message) => (
185
- <Message<{ text: TextObject }> key={message.id} {...message} MessageBlockComponent={StoryMessageBlock} />
195
+ <Message<{ content?: TextV0Type }> key={message.id} {...message} MessageBlockComponent={StoryMessageBlock} />
186
196
  ))}
187
197
 
188
198
  <div ref={containerRef} className='contents'>
189
199
  <MessageTextbox
190
- id={item.text.id}
191
- doc={doc}
200
+ id={thread.id}
192
201
  authorId={authorId}
193
202
  autoFocus={autoFocus}
194
203
  extensions={extensions}
@@ -243,7 +252,7 @@ type StoryProps = {
243
252
  };
244
253
 
245
254
  const Story = ({ text, autoCreate }: StoryProps) => {
246
- const [item] = useState({ text: new TextObject(text) });
255
+ const [item] = useState(E.object(TextV0Type, { content: text ?? '' }));
247
256
  const [threads, setThreads] = useState<StoryCommentThread[]>([]);
248
257
  const [selected, setSelected] = useState<string>();
249
258
 
@@ -269,7 +278,7 @@ const Story = ({ text, autoCreate }: StoryProps) => {
269
278
  blocks: [
270
279
  {
271
280
  timestamp: new Date().toISOString(),
272
- text: new TextObject(faker.lorem.sentence()),
281
+ content: E.object(TextV0Type, { content: faker.lorem.sentence() }),
273
282
  },
274
283
  ],
275
284
  }),
@@ -3,11 +3,10 @@
3
3
  //
4
4
 
5
5
  import '@dxosTheme';
6
- import React, { useMemo, useState } from 'react';
6
+ import React, { useMemo, useRef, useState } from 'react';
7
7
 
8
- import { setTextContent, TextObject } from '@dxos/echo-schema';
9
8
  import { PublicKey } from '@dxos/keys';
10
- import { automerge, createBasicExtensions, createThemeExtensions, useDocAccessor } from '@dxos/react-ui-editor';
9
+ import { createBasicExtensions, createThemeExtensions } from '@dxos/react-ui-editor';
11
10
  import { withTheme } from '@dxos/storybook-utils';
12
11
 
13
12
  import { Thread, ThreadFooter } from './Thread';
@@ -19,7 +18,7 @@ const Story = () => {
19
18
  const [pending, setPending] = useState(false);
20
19
  const [identityKey1] = useState(PublicKey.random());
21
20
  const [identityKey2] = useState(PublicKey.random());
22
- const [messages] = useState<MessageEntity<{ id: string; text: string }>[]>([
21
+ const [messages, setMesssages] = useState<MessageEntity<{ id: string; text: string }>[]>([
23
22
  {
24
23
  id: 'm1',
25
24
  authorId: identityKey1.toHex(),
@@ -44,17 +43,34 @@ const Story = () => {
44
43
  },
45
44
  ]);
46
45
 
47
- const [item] = useState(new TextObject());
48
- const { accessor } = useDocAccessor(item);
49
- const extensions = useMemo(() => [createBasicExtensions(), createThemeExtensions(), automerge(accessor)], [accessor]);
46
+ // TODO(wittjosiah): This is a hack to reset the editor after a message is sent.
47
+ const [_count, _setCount] = useState(3);
48
+ const rerenderEditor = () => _setCount((count) => count + 1);
49
+ const messageRef = useRef('');
50
+ const extensions = useMemo(() => [createBasicExtensions(), createThemeExtensions()], []);
50
51
 
51
52
  // TODO(thure): Why does pressing Enter clear the text content?
52
53
  // Something to do with the in-memory text model perhaps?
53
54
  const handleSend = () => {
54
55
  setPending(true);
55
56
  setTimeout(() => {
56
- setTextContent(item, '');
57
+ setMesssages((messages) => [
58
+ ...messages,
59
+ {
60
+ id: `m${_count}`,
61
+ authorId: identityKey1.toHex(),
62
+ blocks: [
63
+ {
64
+ id: `b${_count}`,
65
+ timestamp: new Date().toISOString(),
66
+ text: messageRef.current,
67
+ },
68
+ ],
69
+ },
70
+ ]);
71
+ messageRef.current = '';
57
72
  setPending(false);
73
+ rerenderEditor();
58
74
  }, 2_000);
59
75
  };
60
76
 
@@ -64,7 +80,7 @@ const Story = () => {
64
80
  <Message key={message.id} {...message} />
65
81
  ))}
66
82
  <MessageTextbox
67
- id={item.id}
83
+ id={String(_count)}
68
84
  authorId={identityKey1.toHex()}
69
85
  disabled={pending}
70
86
  extensions={extensions}