@dxos/plugin-thread 0.6.12-staging.e11e696 → 0.6.12

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.
Files changed (81) hide show
  1. package/dist/lib/browser/{ThreadArticle-4VU752F4.mjs → ThreadArticle-O64ZECMF.mjs} +3 -3
  2. package/dist/lib/browser/{ThreadMain-ML3P4XSD.mjs → ThreadMain-ZDCRC6RG.mjs} +3 -3
  3. package/dist/lib/browser/{chunk-7NUYW5IW.mjs → chunk-5IBJO53M.mjs} +5 -2
  4. package/dist/lib/browser/chunk-5IBJO53M.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-GJRBBPXI.mjs → chunk-GKPZHUT3.mjs} +2 -2
  6. package/dist/lib/browser/{chunk-GJRBBPXI.mjs.map → chunk-GKPZHUT3.mjs.map} +1 -1
  7. package/dist/lib/browser/{chunk-XF5QKI75.mjs → chunk-P7ZE5N5M.mjs} +11 -13
  8. package/dist/lib/browser/chunk-P7ZE5N5M.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +234 -233
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/meta.mjs +1 -1
  13. package/dist/lib/browser/types.mjs +2 -2
  14. package/dist/lib/node/{ThreadArticle-ERUHPHVT.cjs → ThreadArticle-DO56JXBU.cjs} +7 -7
  15. package/dist/lib/node/{ThreadMain-6DN7FDNB.cjs → ThreadMain-XJX75GHG.cjs} +7 -7
  16. package/dist/lib/node/{chunk-PZVUW4W2.cjs → chunk-5PZNPPQF.cjs} +63 -65
  17. package/dist/lib/node/chunk-5PZNPPQF.cjs.map +7 -0
  18. package/dist/lib/node/{chunk-6EVXCSDS.cjs → chunk-BWBONZGU.cjs} +18 -5
  19. package/dist/lib/node/chunk-BWBONZGU.cjs.map +7 -0
  20. package/dist/lib/node/{chunk-FXD3DYMO.cjs → chunk-D5GOVXHS.cjs} +6 -6
  21. package/dist/lib/node/{chunk-FXD3DYMO.cjs.map → chunk-D5GOVXHS.cjs.map} +1 -1
  22. package/dist/lib/node/index.cjs +316 -313
  23. package/dist/lib/node/index.cjs.map +4 -4
  24. package/dist/lib/node/meta.cjs +4 -4
  25. package/dist/lib/node/meta.cjs.map +1 -1
  26. package/dist/lib/node/meta.json +1 -1
  27. package/dist/lib/node/types.cjs +3 -3
  28. package/dist/lib/node/types.cjs.map +1 -1
  29. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  30. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  31. package/dist/types/src/components/CommentContainer.d.ts +1 -1
  32. package/dist/types/src/components/CommentContainer.d.ts.map +1 -1
  33. package/dist/types/src/components/CommentsContainer.d.ts +5 -1
  34. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  35. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  36. package/dist/types/src/components/testing.d.ts +0 -2
  37. package/dist/types/src/components/testing.d.ts.map +1 -1
  38. package/dist/types/src/meta.d.ts +4 -1
  39. package/dist/types/src/meta.d.ts.map +1 -1
  40. package/dist/types/src/types.d.ts +1 -1
  41. package/dist/types/src/types.d.ts.map +1 -1
  42. package/dist/types/src/types.test.d.ts +2 -0
  43. package/dist/types/src/types.test.d.ts.map +1 -0
  44. package/package.json +37 -40
  45. package/src/ThreadPlugin.tsx +182 -70
  46. package/src/components/ChatContainer.tsx +8 -7
  47. package/src/components/CommentContainer.tsx +19 -18
  48. package/src/components/Comments.stories.tsx +2 -2
  49. package/src/components/CommentsContainer.tsx +31 -18
  50. package/src/components/MessageContainer.tsx +1 -2
  51. package/src/meta.tsx +5 -1
  52. package/src/types.test.ts +13 -0
  53. package/src/types.ts +1 -1
  54. package/dist/lib/browser/chunk-7NUYW5IW.mjs.map +0 -7
  55. package/dist/lib/browser/chunk-XF5QKI75.mjs.map +0 -7
  56. package/dist/lib/node/chunk-6EVXCSDS.cjs.map +0 -7
  57. package/dist/lib/node/chunk-PZVUW4W2.cjs.map +0 -7
  58. package/dist/lib/node-esm/ThreadArticle-NKI5F4W5.mjs +0 -19
  59. package/dist/lib/node-esm/ThreadArticle-NKI5F4W5.mjs.map +0 -7
  60. package/dist/lib/node-esm/ThreadMain-2A3VQLCW.mjs +0 -27
  61. package/dist/lib/node-esm/ThreadMain-2A3VQLCW.mjs.map +0 -7
  62. package/dist/lib/node-esm/chunk-A44C4MTQ.mjs +0 -413
  63. package/dist/lib/node-esm/chunk-A44C4MTQ.mjs.map +0 -7
  64. package/dist/lib/node-esm/chunk-Y475KZTX.mjs +0 -20
  65. package/dist/lib/node-esm/chunk-Y475KZTX.mjs.map +0 -7
  66. package/dist/lib/node-esm/chunk-YO46JGAE.mjs +0 -21
  67. package/dist/lib/node-esm/chunk-YO46JGAE.mjs.map +0 -7
  68. package/dist/lib/node-esm/index.mjs +0 -1102
  69. package/dist/lib/node-esm/index.mjs.map +0 -7
  70. package/dist/lib/node-esm/meta.json +0 -1
  71. package/dist/lib/node-esm/meta.mjs +0 -12
  72. package/dist/lib/node-esm/meta.mjs.map +0 -7
  73. package/dist/lib/node-esm/types.mjs +0 -9
  74. package/dist/lib/node-esm/types.mjs.map +0 -7
  75. package/dist/types/src/components/ThreadComplementary.d.ts +0 -10
  76. package/dist/types/src/components/ThreadComplementary.d.ts.map +0 -1
  77. package/src/components/ThreadComplementary.tsx +0 -113
  78. /package/dist/lib/browser/{ThreadArticle-4VU752F4.mjs.map → ThreadArticle-O64ZECMF.mjs.map} +0 -0
  79. /package/dist/lib/browser/{ThreadMain-ML3P4XSD.mjs.map → ThreadMain-ZDCRC6RG.mjs.map} +0 -0
  80. /package/dist/lib/node/{ThreadArticle-ERUHPHVT.cjs.map → ThreadArticle-DO56JXBU.cjs.map} +0 -0
  81. /package/dist/lib/node/{ThreadMain-6DN7FDNB.cjs.map → ThreadMain-XJX75GHG.cjs.map} +0 -0
@@ -28,75 +28,73 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var node_exports = {};
30
30
  __export(node_exports, {
31
- ThreadAction: () => import_chunk_FXD3DYMO.ThreadAction,
31
+ ThreadAction: () => import_chunk_D5GOVXHS.ThreadAction,
32
32
  ThreadPlugin: () => ThreadPlugin,
33
33
  default: () => src_default,
34
- useAnalyticsCallback: () => import_chunk_PZVUW4W2.useAnalyticsCallback,
35
- useOnEditAnalytics: () => import_chunk_PZVUW4W2.useOnEditAnalytics,
36
- useStatus: () => import_chunk_PZVUW4W2.useStatus
34
+ useAnalyticsCallback: () => import_chunk_5PZNPPQF.useAnalyticsCallback,
35
+ useOnEditAnalytics: () => import_chunk_5PZNPPQF.useOnEditAnalytics,
36
+ useStatus: () => import_chunk_5PZNPPQF.useStatus
37
37
  });
38
38
  module.exports = __toCommonJS(node_exports);
39
- var import_chunk_FXD3DYMO = require("./chunk-FXD3DYMO.cjs");
40
- var import_chunk_PZVUW4W2 = require("./chunk-PZVUW4W2.cjs");
41
- var import_chunk_6EVXCSDS = require("./chunk-6EVXCSDS.cjs");
39
+ var import_chunk_D5GOVXHS = require("./chunk-D5GOVXHS.cjs");
40
+ var import_chunk_5PZNPPQF = require("./chunk-5PZNPPQF.cjs");
41
+ var import_chunk_BWBONZGU = require("./chunk-BWBONZGU.cjs");
42
+ var import_react = require("@phosphor-icons/react");
42
43
  var import_signals_core = require("@preact/signals-core");
43
- var import_react = __toESM(require("react"));
44
+ var import_react2 = __toESM(require("react"));
44
45
  var import_app_framework = require("@dxos/app-framework");
45
46
  var import_echo_schema = require("@dxos/echo-schema");
46
47
  var import_echo_schema2 = require("@dxos/echo-schema");
47
48
  var import_local_storage = require("@dxos/local-storage");
48
- var import_log = require("@dxos/log");
49
+ var import_plugin_attention = require("@dxos/plugin-attention");
49
50
  var import_plugin_client = require("@dxos/plugin-client");
50
51
  var import_plugin_graph = require("@dxos/plugin-graph");
52
+ var import_types = require("@dxos/plugin-markdown/types");
51
53
  var import_meta = require("@dxos/plugin-observability/meta");
52
54
  var import_plugin_space = require("@dxos/plugin-space");
53
- var import_types = require("@dxos/plugin-space/types");
55
+ var import_types2 = require("@dxos/plugin-space/types");
54
56
  var import_echo = require("@dxos/react-client/echo");
57
+ var import_react_ui = require("@dxos/react-ui");
58
+ var import_react_ui_attention = require("@dxos/react-ui-attention");
55
59
  var import_react_ui_editor = require("@dxos/react-ui-editor");
56
60
  var import_react_ui_thread = require("@dxos/react-ui-thread");
57
61
  var import_util = require("@dxos/util");
58
- var import_react2 = __toESM(require("react"));
59
62
  var import_react3 = __toESM(require("react"));
63
+ var import_react4 = __toESM(require("react"));
60
64
  var import_plugin_settings = require("@dxos/plugin-settings");
61
- var import_react_ui = require("@dxos/react-ui");
62
- var import_react4 = require("@phosphor-icons/react");
63
- var import_react5 = __toESM(require("react"));
65
+ var import_react_ui2 = require("@dxos/react-ui");
66
+ var import_react5 = require("@phosphor-icons/react");
67
+ var import_react6 = __toESM(require("react"));
64
68
  var import_echo_schema3 = require("@dxos/echo-schema");
65
- var import_types2 = require("@dxos/plugin-space/types");
69
+ var import_types3 = require("@dxos/plugin-space/types");
66
70
  var import_echo2 = require("@dxos/react-client/echo");
67
71
  var import_halo = require("@dxos/react-client/halo");
68
- var import_react_ui2 = require("@dxos/react-ui");
72
+ var import_react_ui3 = require("@dxos/react-ui");
69
73
  var import_react_ui_editor2 = require("@dxos/react-ui-editor");
70
74
  var import_react_ui_theme = require("@dxos/react-ui-theme");
71
75
  var import_react_ui_thread2 = require("@dxos/react-ui-thread");
72
76
  var import_util2 = require("@dxos/util");
73
- var import_react6 = require("@phosphor-icons/react");
74
- var import_react7 = __toESM(require("react"));
75
- var import_echo3 = require("@dxos/react-client/echo");
76
- var import_react_ui3 = require("@dxos/react-ui");
77
- var import_react_ui_theme2 = require("@dxos/react-ui-theme");
77
+ var import_react7 = require("@phosphor-icons/react");
78
78
  var import_react8 = __toESM(require("react"));
79
- var import_app_framework2 = require("@dxos/app-framework");
80
- var import_echo4 = require("@dxos/react-client/echo");
81
79
  var import_react_ui4 = require("@dxos/react-ui");
82
- var import_react_ui_attention = require("@dxos/react-ui-attention");
83
- var import_util3 = require("@dxos/util");
80
+ var import_react_ui_deck = require("@dxos/react-ui-deck");
81
+ var import_react_ui_theme2 = require("@dxos/react-ui-theme");
84
82
  var ThreadSettings = ({ settings }) => {
85
- const { t } = (0, import_react_ui.useTranslation)(import_chunk_6EVXCSDS.THREAD_PLUGIN);
86
- return /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement(import_plugin_settings.SettingsValue, {
83
+ const { t } = (0, import_react_ui2.useTranslation)(import_chunk_BWBONZGU.THREAD_PLUGIN);
84
+ return /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(import_plugin_settings.SettingsValue, {
87
85
  label: t("settings standalone label")
88
- }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui.Input.Switch, {
86
+ }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui2.Input.Switch, {
89
87
  checked: settings.standalone,
90
88
  onCheckedChange: (checked) => settings.standalone = !!checked
91
89
  })));
92
90
  };
93
91
  var sizeClass = (0, import_react_ui_theme.getSize)(4);
94
92
  var ToggleResolvedButton = ({ isResolved, onResolve }) => {
95
- const { t } = (0, import_react_ui2.useTranslation)(import_chunk_6EVXCSDS.THREAD_PLUGIN);
93
+ const { t } = (0, import_react_ui3.useTranslation)(import_chunk_BWBONZGU.THREAD_PLUGIN);
96
94
  const label = t(isResolved ? "mark as unresolved label" : "mark as resolved label");
97
- return /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Root, null, /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Trigger, {
95
+ return /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Root, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Trigger, {
98
96
  asChild: true
99
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Button, {
97
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Button, {
100
98
  variant: "ghost",
101
99
  "data-testid": "thread.toggle-resolved",
102
100
  onClick: onResolve,
@@ -104,23 +102,23 @@ var ToggleResolvedButton = ({ isResolved, onResolve }) => {
104
102
  "min-bs-0 p-1",
105
103
  !isResolved && import_react_ui_theme.hoverableControlItem
106
104
  ]
107
- }, /* @__PURE__ */ import_react5.default.createElement("span", {
105
+ }, /* @__PURE__ */ import_react6.default.createElement("span", {
108
106
  className: "sr-only"
109
- }, label), isResolved ? /* @__PURE__ */ import_react5.default.createElement(import_react4.CheckCircle, {
107
+ }, label), isResolved ? /* @__PURE__ */ import_react6.default.createElement(import_react5.CheckCircle, {
110
108
  className: sizeClass,
111
109
  weight: "fill"
112
- }) : /* @__PURE__ */ import_react5.default.createElement(import_react4.CheckCircle, {
110
+ }) : /* @__PURE__ */ import_react6.default.createElement(import_react5.CheckCircle, {
113
111
  className: sizeClass
114
- }))), /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Portal, null, /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Content, {
112
+ }))), /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Portal, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Content, {
115
113
  classNames: "z-[21]"
116
- }, label, /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Arrow, null))));
114
+ }, label, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Arrow, null))));
117
115
  };
118
116
  var DeleteThreadButton = ({ onDelete }) => {
119
- const { t } = (0, import_react_ui2.useTranslation)(import_chunk_6EVXCSDS.THREAD_PLUGIN);
117
+ const { t } = (0, import_react_ui3.useTranslation)(import_chunk_BWBONZGU.THREAD_PLUGIN);
120
118
  const label = t("delete thread label");
121
- return /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Root, null, /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Trigger, {
119
+ return /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Root, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Trigger, {
122
120
  asChild: true
123
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Button, {
121
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Button, {
124
122
  variant: "ghost",
125
123
  "data-testid": "thread.delete",
126
124
  onClick: onDelete,
@@ -128,27 +126,28 @@ var DeleteThreadButton = ({ onDelete }) => {
128
126
  "min-bs-0 p-1",
129
127
  import_react_ui_theme.hoverableControlItem
130
128
  ]
131
- }, /* @__PURE__ */ import_react5.default.createElement("span", {
129
+ }, /* @__PURE__ */ import_react6.default.createElement("span", {
132
130
  className: "sr-only"
133
- }, label), /* @__PURE__ */ import_react5.default.createElement(import_react4.X, {
131
+ }, label), /* @__PURE__ */ import_react6.default.createElement(import_react5.X, {
134
132
  className: sizeClass
135
- }))), /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Portal, null, /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Content, {
133
+ }))), /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Portal, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Content, {
136
134
  classNames: "z-[21]"
137
- }, label, /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Arrow, null))));
135
+ }, label, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Arrow, null))));
138
136
  };
139
- var CommentContainer = ({ thread, detached, context, current, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
137
+ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
140
138
  const identity = (0, import_halo.useIdentity)();
141
139
  const space = (0, import_echo2.getSpace)(thread);
142
140
  const members = (0, import_echo2.useMembers)(space?.key);
143
- const activity = (0, import_chunk_PZVUW4W2.useStatus)(space, (0, import_echo2.fullyQualifiedId)(thread));
144
- const { t } = (0, import_react_ui2.useTranslation)(import_chunk_6EVXCSDS.THREAD_PLUGIN);
145
- const threadScrollRef = (0, import_react5.useRef)(null);
146
- const { themeMode } = (0, import_react_ui2.useThemeContext)();
147
- const textboxMetadata = (0, import_chunk_PZVUW4W2.getMessageMetadata)((0, import_echo2.fullyQualifiedId)(thread), identity);
148
- const [_count, _setCount] = (0, import_react5.useState)(0);
141
+ const activity = (0, import_chunk_5PZNPPQF.useStatus)(space, thread.id);
142
+ const { t } = (0, import_react_ui3.useTranslation)(import_chunk_BWBONZGU.THREAD_PLUGIN);
143
+ const threadScrollRef = (0, import_react6.useRef)(null);
144
+ const [autoFocus, setAutoFocus] = (0, import_react6.useState)(!!autoFocusTextbox);
145
+ const { themeMode } = (0, import_react_ui3.useThemeContext)();
146
+ const textboxMetadata = (0, import_chunk_5PZNPPQF.getMessageMetadata)(thread.id, identity);
147
+ const [_count, _setCount] = (0, import_react6.useState)(0);
149
148
  const rerenderEditor = () => _setCount((count) => count + 1);
150
- const messageRef = (0, import_react5.useRef)("");
151
- const extensions = (0, import_react5.useMemo)(() => [
149
+ const messageRef = (0, import_react6.useRef)("");
150
+ const extensions = (0, import_react6.useMemo)(() => [
152
151
  (0, import_react_ui_editor2.createBasicExtensions)({
153
152
  placeholder: t("message placeholder")
154
153
  }),
@@ -158,19 +157,24 @@ var CommentContainer = ({ thread, detached, context, current, onAttend, onThread
158
157
  (0, import_react_ui_editor2.listener)({
159
158
  onChange: (text) => messageRef.current = text
160
159
  }),
161
- import_chunk_PZVUW4W2.command
160
+ import_chunk_5PZNPPQF.command
162
161
  ], [
163
162
  _count
164
163
  ]);
164
+ (0, import_react6.useEffect)(() => {
165
+ setAutoFocus(!!autoFocusTextbox);
166
+ }, [
167
+ autoFocusTextbox
168
+ ]);
165
169
  const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
166
170
  behavior,
167
171
  block: "end"
168
172
  }), 10);
169
- const handleCreate = (0, import_react5.useCallback)(() => {
173
+ const handleCreate = (0, import_react6.useCallback)(() => {
170
174
  if (!messageRef.current) {
171
175
  return false;
172
176
  }
173
- thread.messages.push((0, import_echo_schema3.create)(import_types2.MessageType, {
177
+ thread.messages.push((0, import_echo_schema3.create)(import_types3.MessageType, {
174
178
  sender: {
175
179
  identityKey: identity.identityKey.toHex()
176
180
  },
@@ -180,6 +184,7 @@ var CommentContainer = ({ thread, detached, context, current, onAttend, onThread
180
184
  }));
181
185
  onComment?.(thread);
182
186
  messageRef.current = "";
187
+ setAutoFocus(true);
183
188
  scrollToEnd("instant");
184
189
  rerenderEditor();
185
190
  return true;
@@ -187,51 +192,64 @@ var CommentContainer = ({ thread, detached, context, current, onAttend, onThread
187
192
  thread,
188
193
  identity
189
194
  ]);
190
- return /* @__PURE__ */ import_react5.default.createElement(import_react_ui_thread2.Thread, {
195
+ const handleDeleteMessage = (id) => onMessageDelete?.(id);
196
+ return /* @__PURE__ */ import_react6.default.createElement(import_react_ui_thread2.Thread, {
191
197
  onClickCapture: onAttend,
192
198
  onFocusCapture: onAttend,
193
199
  current,
194
- id: (0, import_echo2.fullyQualifiedId)(thread)
195
- }, /* @__PURE__ */ import_react5.default.createElement("div", {
200
+ id: thread.id
201
+ }, /* @__PURE__ */ import_react6.default.createElement("div", {
196
202
  role: "none",
197
203
  className: (0, import_react_ui_theme.mx)("col-span-2 grid grid-cols-[var(--rail-size)_1fr_min-content]", import_react_ui_theme.hoverableControls, import_react_ui_theme.hoverableFocusedWithinControls)
198
- }, detached ? /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Root, null, /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Trigger, {
204
+ }, detached ? /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Root, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Trigger, {
199
205
  asChild: true
200
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui_thread2.ThreadHeading, {
206
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui_thread2.ThreadHeading, {
201
207
  detached: true
202
- }, thread.name ?? t("thread title placeholder"))), /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Portal, null, /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Content, {
208
+ }, thread.name ?? t("thread title placeholder"))), /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Portal, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Content, {
203
209
  classNames: "z-[21]",
204
210
  side: "top"
205
- }, t("detached thread label"), /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tooltip.Arrow, null)))) : /* @__PURE__ */ import_react5.default.createElement(import_react_ui_thread2.ThreadHeading, null, thread.name ?? t("thread title placeholder")), /* @__PURE__ */ import_react5.default.createElement("div", {
211
+ }, t("detached thread label"), /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Arrow, null)))) : /* @__PURE__ */ import_react6.default.createElement(import_react_ui_thread2.ThreadHeading, null, thread.name ?? t("thread title placeholder")), /* @__PURE__ */ import_react6.default.createElement("div", {
206
212
  className: "flex flex-row items-center pli-1"
207
- }, thread.status === "staged" && /* @__PURE__ */ import_react5.default.createElement(import_react_ui2.Tag, {
213
+ }, thread.status === "staged" && /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tag, {
208
214
  palette: "neutral"
209
- }, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */ import_react5.default.createElement(ToggleResolvedButton, {
215
+ }, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */ import_react6.default.createElement(ToggleResolvedButton, {
210
216
  isResolved: thread?.status === "resolved",
211
217
  onResolve
212
- }), onThreadDelete && /* @__PURE__ */ import_react5.default.createElement(DeleteThreadButton, {
218
+ }), onThreadDelete && /* @__PURE__ */ import_react6.default.createElement(DeleteThreadButton, {
213
219
  onDelete: onThreadDelete
214
- }))), thread.messages.filter(import_util2.nonNullable).map((message) => /* @__PURE__ */ import_react5.default.createElement(import_chunk_PZVUW4W2.MessageContainer, {
220
+ }))), thread.messages.filter(import_util2.nonNullable).map((message) => /* @__PURE__ */ import_react6.default.createElement(import_chunk_5PZNPPQF.MessageContainer, {
215
221
  key: message.id,
216
222
  message,
217
223
  members,
218
- onDelete: (id) => onMessageDelete?.(id)
219
- })), /* @__PURE__ */ import_react5.default.createElement(import_react_ui_thread2.MessageTextbox, {
224
+ onDelete: handleDeleteMessage
225
+ })), /* @__PURE__ */ import_react6.default.createElement(import_react_ui_thread2.MessageTextbox, {
220
226
  extensions,
227
+ autoFocus,
221
228
  onSend: handleCreate,
222
229
  ...textboxMetadata
223
- }), /* @__PURE__ */ import_react5.default.createElement(import_react_ui_thread2.ThreadFooter, {
230
+ }), /* @__PURE__ */ import_react6.default.createElement(import_react_ui_thread2.ThreadFooter, {
224
231
  activity
225
- }, t("activity message")), /* @__PURE__ */ import_react5.default.createElement("div", {
232
+ }, t("activity message")), /* @__PURE__ */ import_react6.default.createElement("div", {
226
233
  role: "none",
227
234
  className: "bs-px -mbs-px",
228
235
  ref: threadScrollRef
229
236
  }));
230
237
  };
231
- var CommentsContainer = ({ threads, detached = [], currentId, showResolvedThreads, onThreadAttend, onThreadDelete, onMessageDelete, onThreadToggleResolved, ...props }) => {
232
- const { t } = (0, import_react_ui3.useTranslation)(import_chunk_6EVXCSDS.THREAD_PLUGIN);
238
+ var CommentsHeading = ({ attendableId }) => {
239
+ const { t } = (0, import_react_ui4.useTranslation)(import_chunk_BWBONZGU.THREAD_PLUGIN);
240
+ return /* @__PURE__ */ import_react8.default.createElement("div", {
241
+ role: "none",
242
+ className: "flex items-center"
243
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui_deck.PlankHeading.Button, {
244
+ attendableId
245
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react7.Quotes, import_react_ui_deck.plankHeadingIconProps)), /* @__PURE__ */ import_react8.default.createElement(import_react_ui_deck.PlankHeading.Label, {
246
+ attendableId
247
+ }, t("comments heading")));
248
+ };
249
+ var CommentsContainer = ({ threads, detached = [], currentId, autoFocusCurrentTextbox, showResolvedThreads, onThreadAttend, onThreadDelete, onMessageDelete, onThreadToggleResolved, ...props }) => {
250
+ const { t } = (0, import_react_ui4.useTranslation)(import_chunk_BWBONZGU.THREAD_PLUGIN);
233
251
  const filteredThreads = showResolvedThreads ? threads : threads.filter((thread) => !(thread?.status === "resolved"));
234
- (0, import_react7.useEffect)(() => {
252
+ (0, import_react8.useEffect)(() => {
235
253
  if (currentId) {
236
254
  document.getElementById(currentId)?.scrollIntoView({
237
255
  behavior: "smooth",
@@ -241,151 +259,46 @@ var CommentsContainer = ({ threads, detached = [], currentId, showResolvedThread
241
259
  }, [
242
260
  currentId
243
261
  ]);
244
- return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, filteredThreads.length > 0 ? filteredThreads.map((thread) => {
245
- const threadId = (0, import_echo3.fullyQualifiedId)(thread);
246
- return /* @__PURE__ */ import_react7.default.createElement(CommentContainer, {
247
- key: threadId,
248
- thread,
249
- current: currentId === threadId,
250
- detached: detached.includes(threadId),
251
- ...onThreadAttend && {
252
- onAttend: () => onThreadAttend(thread)
253
- },
254
- ...onThreadDelete && {
255
- onThreadDelete: () => onThreadDelete(thread)
256
- },
257
- ...onMessageDelete && {
258
- onMessageDelete: (messageId) => onMessageDelete(thread, messageId)
259
- },
260
- ...onThreadToggleResolved && {
261
- onResolve: () => onThreadToggleResolved(thread)
262
- },
263
- ...props
264
- });
265
- }) : /* @__PURE__ */ import_react7.default.createElement("div", {
262
+ return /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null, filteredThreads.length > 0 ? filteredThreads.map((thread) => /* @__PURE__ */ import_react8.default.createElement(CommentContainer, {
263
+ key: thread.id,
264
+ thread,
265
+ current: currentId === thread.id,
266
+ detached: detached.includes(thread.id),
267
+ autoFocusTextbox: autoFocusCurrentTextbox && currentId === thread.id,
268
+ ...onThreadAttend && {
269
+ onAttend: () => onThreadAttend(thread)
270
+ },
271
+ ...onThreadDelete && {
272
+ onThreadDelete: () => onThreadDelete(thread)
273
+ },
274
+ ...onMessageDelete && {
275
+ onMessageDelete: (messageId) => onMessageDelete(thread, messageId)
276
+ },
277
+ ...onThreadToggleResolved && {
278
+ onResolve: () => onThreadToggleResolved(thread)
279
+ },
280
+ ...props
281
+ })) : /* @__PURE__ */ import_react8.default.createElement("div", {
266
282
  role: "alert",
267
283
  className: (0, import_react_ui_theme2.mx)(import_react_ui_theme2.descriptionText, "place-self-center border border-dashed border-neutral-400/50 rounded-lg text-center p-4 m-4")
268
- }, /* @__PURE__ */ import_react7.default.createElement("h2", {
284
+ }, /* @__PURE__ */ import_react8.default.createElement("h2", {
269
285
  className: "mbe-2 font-medium text-baseText"
270
- }, t("no comments title")), /* @__PURE__ */ import_react7.default.createElement("p", null, /* @__PURE__ */ import_react7.default.createElement(import_react_ui3.Trans, {
286
+ }, t("no comments title")), /* @__PURE__ */ import_react8.default.createElement("p", null, /* @__PURE__ */ import_react8.default.createElement(import_react_ui4.Trans, {
271
287
  t,
272
288
  i18nKey: "no comments message",
273
289
  components: {
274
- commentIcon: /* @__PURE__ */ import_react7.default.createElement(import_react6.ChatText, {
290
+ commentIcon: /* @__PURE__ */ import_react8.default.createElement(import_react7.ChatText, {
275
291
  className: "inline-block"
276
292
  })
277
293
  }
278
294
  }))));
279
295
  };
280
- var ThreadMain = import_react2.default.lazy(() => import("./ThreadMain-6DN7FDNB.cjs"));
281
- var ThreadArticle = import_react2.default.lazy(() => import("./ThreadArticle-ERUHPHVT.cjs"));
282
- var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
283
- var ThreadComplementary = ({ role, subject, stagedThreads, current, showResolvedThreads }) => {
284
- const dispatch = (0, import_app_framework2.useIntentDispatcher)();
285
- const threadsIntegrators = (0, import_app_framework2.useResolvePlugins)(providesThreadsConfig);
286
- const threadProvides = (0, import_react8.useMemo)(() => threadsIntegrators.map((p) => p.provides.thread), [
287
- threadsIntegrators
288
- ]);
289
- const createSort = (0, import_react8.useMemo)(() => threadProvides.find((p) => p.predicate(subject))?.createSort, [
290
- threadProvides,
291
- subject
292
- ]);
293
- const sort = (0, import_react8.useMemo)(() => createSort?.(subject), [
294
- createSort,
295
- subject
296
- ]);
297
- const threads = (0, import_react8.useMemo)(() => {
298
- return subject.threads.concat(stagedThreads ?? []).filter(import_util3.nonNullable);
299
- }, [
300
- JSON.stringify(subject.threads),
301
- JSON.stringify(stagedThreads)
302
- ]);
303
- const detachedIds = (0, import_react8.useMemo)(() => {
304
- return threads.filter(({ anchor }) => !anchor).map((thread) => (0, import_echo4.fullyQualifiedId)(thread));
305
- }, [
306
- threads
307
- ]);
308
- (0, import_react8.useEffect)(() => {
309
- if (!sort) {
310
- return;
311
- }
312
- threads.sort((a, b) => sort(a?.anchor, b?.anchor));
313
- }, [
314
- sort,
315
- threads
316
- ]);
317
- const attended = (0, import_react_ui_attention.useAttended)();
318
- const qualifiedSubjectId = (0, import_echo4.fullyQualifiedId)(subject);
319
- return /* @__PURE__ */ import_react8.default.createElement("div", {
320
- role: "none",
321
- className: "contents"
322
- }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui4.ScrollArea.Root, {
323
- classNames: "row-span-2"
324
- }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui4.ScrollArea.Viewport, null, /* @__PURE__ */ import_react8.default.createElement(CommentsContainer, {
325
- threads,
326
- detached: detachedIds,
327
- currentId: attended.includes(qualifiedSubjectId) ? current : void 0,
328
- showResolvedThreads,
329
- onThreadAttend: (thread) => {
330
- const threadId = (0, import_echo4.fullyQualifiedId)(thread);
331
- if (current !== threadId) {
332
- current = threadId;
333
- void dispatch?.([
334
- {
335
- action: import_app_framework2.LayoutAction.SCROLL_INTO_VIEW,
336
- data: {
337
- id: (0, import_echo4.fullyQualifiedId)(subject),
338
- thread: threadId,
339
- cursor: thread.anchor
340
- }
341
- }
342
- ]);
343
- }
344
- },
345
- onThreadDelete: (thread) => {
346
- return dispatch({
347
- plugin: import_chunk_6EVXCSDS.THREAD_PLUGIN,
348
- action: import_chunk_FXD3DYMO.ThreadAction.DELETE,
349
- data: {
350
- subject,
351
- thread
352
- }
353
- });
354
- },
355
- onMessageDelete: (thread, messageId) => dispatch({
356
- plugin: import_chunk_6EVXCSDS.THREAD_PLUGIN,
357
- action: import_chunk_FXD3DYMO.ThreadAction.DELETE_MESSAGE,
358
- data: {
359
- subject,
360
- thread,
361
- messageId
362
- }
363
- }),
364
- onThreadToggleResolved: (thread) => dispatch({
365
- plugin: import_chunk_6EVXCSDS.THREAD_PLUGIN,
366
- action: import_chunk_FXD3DYMO.ThreadAction.TOGGLE_RESOLVED,
367
- data: {
368
- thread
369
- }
370
- }),
371
- onComment: (thread) => {
372
- void dispatch({
373
- action: import_chunk_FXD3DYMO.ThreadAction.ON_MESSAGE_ADD,
374
- data: {
375
- thread,
376
- subject
377
- }
378
- });
379
- }
380
- }), /* @__PURE__ */ import_react8.default.createElement("div", {
381
- role: "none",
382
- className: "bs-10"
383
- }), /* @__PURE__ */ import_react8.default.createElement(import_react_ui4.ScrollArea.Scrollbar, null, /* @__PURE__ */ import_react8.default.createElement(import_react_ui4.ScrollArea.Thumb, null)))));
384
- };
296
+ var ThreadMain = import_react3.default.lazy(() => import("./ThreadMain-XJX75GHG.cjs"));
297
+ var ThreadArticle = import_react3.default.lazy(() => import("./ThreadArticle-DO56JXBU.cjs"));
385
298
  var translations_default = [
386
299
  {
387
300
  "en-US": {
388
- [import_chunk_6EVXCSDS.THREAD_PLUGIN]: {
301
+ [import_chunk_BWBONZGU.THREAD_PLUGIN]: {
389
302
  "plugin name": "Threads",
390
303
  "channel name placeholder": "New channel",
391
304
  "channel title label": "Title",
@@ -416,12 +329,12 @@ var translations_default = [
416
329
  }
417
330
  }
418
331
  ];
419
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/ThreadPlugin.tsx";
420
332
  var initialViewState = {
421
333
  showResolvedThreads: false
422
334
  };
335
+ var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
423
336
  var ThreadPlugin = () => {
424
- const settings = new import_local_storage.LocalStorageStore(import_chunk_6EVXCSDS.THREAD_PLUGIN);
337
+ const settings = new import_local_storage.LocalStorageStore(import_chunk_BWBONZGU.THREAD_PLUGIN);
425
338
  const state = (0, import_echo_schema2.create)({
426
339
  staging: {}
427
340
  });
@@ -434,11 +347,13 @@ var ThreadPlugin = () => {
434
347
  }
435
348
  return viewStore[subjectId];
436
349
  };
350
+ let attentionPlugin;
437
351
  let navigationPlugin;
438
352
  let intentPlugin;
353
+ let dispatch;
439
354
  const unsubscribeCallbacks = [];
440
355
  return {
441
- meta: import_chunk_6EVXCSDS.meta_default,
356
+ meta: import_chunk_BWBONZGU.meta_default,
442
357
  ready: async (plugins) => {
443
358
  settings.prop({
444
359
  key: "standalone",
@@ -446,8 +361,36 @@ var ThreadPlugin = () => {
446
361
  allowUndefined: true
447
362
  })
448
363
  });
364
+ attentionPlugin = (0, import_app_framework.resolvePlugin)(plugins, import_plugin_attention.parseAttentionPlugin);
449
365
  navigationPlugin = (0, import_app_framework.resolvePlugin)(plugins, import_app_framework.parseNavigationPlugin);
450
366
  intentPlugin = (0, import_app_framework.resolvePlugin)(plugins, import_app_framework.parseIntentPlugin);
367
+ dispatch = intentPlugin?.provides.intent.dispatch;
368
+ const graphPlugin = (0, import_app_framework.resolvePlugin)(plugins, import_app_framework.parseGraphPlugin);
369
+ const client = (0, import_app_framework.resolvePlugin)(plugins, import_plugin_client.parseClientPlugin)?.provides.client;
370
+ if (!client) {
371
+ return;
372
+ }
373
+ const channelsQuery = client.spaces.query(import_echo.Filter.schema(import_types2.ChannelType));
374
+ const queryUnsubscribe = channelsQuery.subscribe();
375
+ const unsubscribe = (0, import_signals_core.effect)(() => {
376
+ const attention = attentionPlugin?.provides.attention;
377
+ if (!attention?.attended) {
378
+ return;
379
+ }
380
+ const firstAttendedNodeWithComments = Array.from(attention.attended).map((id) => graphPlugin?.provides.graph.findNode(id)).find((node) => node?.data instanceof import_types.DocumentType && (node.data.threads?.length ?? 0) > 0);
381
+ if (firstAttendedNodeWithComments) {
382
+ void intentPlugin?.provides.intent.dispatch({
383
+ action: import_app_framework.NavigationAction.OPEN,
384
+ data: {
385
+ activeParts: {
386
+ complementary: `${firstAttendedNodeWithComments.id}${import_app_framework.SLUG_PATH_SEPARATOR}comments`
387
+ }
388
+ }
389
+ });
390
+ }
391
+ });
392
+ unsubscribeCallbacks.push(queryUnsubscribe);
393
+ unsubscribeCallbacks.push(unsubscribe);
451
394
  },
452
395
  unload: async () => {
453
396
  unsubscribeCallbacks.forEach((unsubscribe) => unsubscribe());
@@ -456,26 +399,27 @@ var ThreadPlugin = () => {
456
399
  settings: settings.values,
457
400
  metadata: {
458
401
  records: {
459
- [import_types.ChannelType.typename]: {
402
+ [import_types2.ChannelType.typename]: {
460
403
  placeholder: [
461
404
  "channel title placeholder",
462
405
  {
463
- ns: import_chunk_6EVXCSDS.THREAD_PLUGIN
406
+ ns: import_chunk_BWBONZGU.THREAD_PLUGIN
464
407
  }
465
408
  ],
466
- icon: "ph--chat--regular",
409
+ icon: (props) => /* @__PURE__ */ import_react2.default.createElement(import_react.Chat, props),
410
+ iconSymbol: "ph--chat--regular",
467
411
  // TODO(wittjosiah): Move out of metadata.
468
412
  loadReferences: (channel) => (0, import_echo.loadObjectReferences)(channel, (channel2) => channel2.threads)
469
413
  },
470
- [import_types.ThreadType.typename]: {
414
+ [import_types2.ThreadType.typename]: {
471
415
  // TODO(wittjosiah): Move out of metadata.
472
416
  loadReferences: (thread) => (0, import_echo.loadObjectReferences)(thread, (thread2) => thread2.messages)
473
417
  },
474
- [import_types.MessageType.typename]: {
418
+ [import_types2.MessageType.typename]: {
475
419
  // TODO(wittjosiah): Move out of metadata.
476
420
  loadReferences: (message) => []
477
421
  },
478
- [import_chunk_6EVXCSDS.THREAD_ITEM]: {
422
+ [import_chunk_BWBONZGU.THREAD_ITEM]: {
479
423
  parse: (item, type) => {
480
424
  switch (type) {
481
425
  case "node":
@@ -502,56 +446,49 @@ var ThreadPlugin = () => {
502
446
  ],
503
447
  echo: {
504
448
  schema: [
505
- import_types.ChannelType,
506
- import_types.ThreadType,
507
- import_types.MessageType
449
+ import_types2.ChannelType,
450
+ import_types2.ThreadType,
451
+ import_types2.MessageType
508
452
  ]
509
453
  },
510
454
  graph: {
511
455
  builder: (plugins) => {
512
456
  const client = (0, import_app_framework.resolvePlugin)(plugins, import_plugin_client.parseClientPlugin)?.provides.client;
513
- const dispatch = (0, import_app_framework.resolvePlugin)(plugins, import_app_framework.parseIntentPlugin)?.provides.intent.dispatch;
457
+ const dispatch2 = (0, import_app_framework.resolvePlugin)(plugins, import_app_framework.parseIntentPlugin)?.provides.intent.dispatch;
514
458
  const metadataResolver = (0, import_app_framework.resolvePlugin)(plugins, import_app_framework.parseMetadataResolverPlugin)?.provides.metadata.resolver;
515
- if (!client || !dispatch || !metadataResolver) {
459
+ if (!client || !dispatch2 || !metadataResolver) {
516
460
  return [];
517
461
  }
518
462
  return [
519
463
  (0, import_plugin_graph.createExtension)({
520
- id: `${import_chunk_6EVXCSDS.THREAD_PLUGIN}/comments-for-subject`,
464
+ id: `${import_chunk_BWBONZGU.THREAD_PLUGIN}/comments-for-subject`,
521
465
  resolver: ({ id }) => {
522
466
  if (!id.endsWith("~comments")) {
523
467
  return;
524
468
  }
525
- const subjectId = id.split("~").at(0);
526
- const [spaceId, objectId] = subjectId?.split(":") ?? [];
469
+ const docId = id.split("~").at(0);
470
+ const [spaceId, objectId] = docId?.split(":") ?? [];
527
471
  const space = client.spaces.get().find((space2) => space2.id === spaceId);
528
- const object = (0, import_plugin_graph.toSignal)((onChange) => {
529
- const timeout = setTimeout(async () => {
530
- await space?.db.loadObjectById(objectId);
531
- onChange();
532
- });
533
- return () => clearTimeout(timeout);
534
- }, () => space?.db.getObjectById(objectId), subjectId);
535
- if (!object || !subjectId) {
472
+ const doc = space?.db.getObjectById(objectId);
473
+ if (!doc || !docId) {
536
474
  return;
537
475
  }
538
- const meta = metadataResolver((0, import_echo_schema.getTypename)(object) ?? "");
539
- const label = meta.label?.(object) || object.name || meta.placeholder || [
476
+ const docMeta = metadataResolver((0, import_echo_schema.getTypename)(doc) ?? "");
477
+ const label = docMeta.label?.(doc) || doc.name || docMeta.placeholder || [
540
478
  "unnamed object threads label",
541
479
  {
542
- ns: import_chunk_6EVXCSDS.THREAD_PLUGIN
480
+ ns: import_chunk_BWBONZGU.THREAD_PLUGIN
543
481
  }
544
482
  ];
545
- const viewState = getViewState(subjectId);
483
+ const viewState = getViewState(docId);
546
484
  return {
547
485
  id,
548
486
  type: "orphan-comments-for-subject",
549
- data: null,
487
+ data: doc,
550
488
  properties: {
551
- icon: "ph--chat-text--regular",
489
+ icon: import_chunk_BWBONZGU.meta_default.iconComponent,
552
490
  label,
553
- showResolvedThreads: viewState.showResolvedThreads,
554
- object
491
+ showResolvedThreads: viewState.showResolvedThreads
555
492
  }
556
493
  };
557
494
  },
@@ -565,7 +502,7 @@ var ThreadPlugin = () => {
565
502
  const toggle = () => {
566
503
  const newToggleState = !viewState.showResolvedThreads;
567
504
  viewState.showResolvedThreads = newToggleState;
568
- void dispatch({
505
+ void dispatch2({
569
506
  action: import_meta.ObservabilityAction.SEND_EVENT,
570
507
  data: {
571
508
  name: "threads.toggle-show-resolved",
@@ -579,26 +516,25 @@ var ThreadPlugin = () => {
579
516
  };
580
517
  return [
581
518
  {
582
- id: `${import_chunk_6EVXCSDS.THREAD_PLUGIN}/toggle-show-resolved/${node.id}`,
519
+ id: `${import_chunk_BWBONZGU.THREAD_PLUGIN}/toggle-show-resolved/${node.id}`,
583
520
  data: toggle,
584
521
  properties: {
585
522
  label: [
586
523
  "toggle show resolved",
587
524
  {
588
- ns: import_chunk_6EVXCSDS.THREAD_PLUGIN
525
+ ns: import_chunk_BWBONZGU.THREAD_PLUGIN
589
526
  }
590
527
  ],
591
528
  menuItemType: "toggle",
592
529
  isChecked: viewState.showResolvedThreads,
593
- testId: "threadPlugin.toggleShowResolved",
594
- icon: viewState.showResolvedThreads ? "ph--eye-slash--regular" : "ph--eye--regular"
530
+ testId: "threadPlugin.toggleShowResolved"
595
531
  }
596
532
  }
597
533
  ];
598
534
  }
599
535
  }),
600
536
  (0, import_plugin_graph.createExtension)({
601
- id: import_chunk_FXD3DYMO.ThreadAction.CREATE,
537
+ id: import_chunk_D5GOVXHS.ThreadAction.CREATE,
602
538
  filter: (node) => !!settings.values.standalone && (0, import_plugin_graph.isActionGroup)(node) && node.id.startsWith(import_plugin_space.SpaceAction.ADD_OBJECT),
603
539
  actions: ({ node }) => {
604
540
  const id = node.id.split("/").at(-1);
@@ -611,12 +547,12 @@ var ThreadPlugin = () => {
611
547
  }
612
548
  return [
613
549
  {
614
- id: `${import_chunk_6EVXCSDS.THREAD_PLUGIN}/create/${node.id}`,
550
+ id: `${import_chunk_BWBONZGU.THREAD_PLUGIN}/create/${node.id}`,
615
551
  data: async () => {
616
- await dispatch([
552
+ await dispatch2([
617
553
  {
618
- plugin: import_chunk_6EVXCSDS.THREAD_PLUGIN,
619
- action: import_chunk_FXD3DYMO.ThreadAction.CREATE
554
+ plugin: import_chunk_BWBONZGU.THREAD_PLUGIN,
555
+ action: import_chunk_D5GOVXHS.ThreadAction.CREATE
620
556
  },
621
557
  {
622
558
  action: import_plugin_space.SpaceAction.ADD_OBJECT,
@@ -633,10 +569,11 @@ var ThreadPlugin = () => {
633
569
  label: [
634
570
  "create channel label",
635
571
  {
636
- ns: import_chunk_6EVXCSDS.THREAD_PLUGIN
572
+ ns: import_chunk_BWBONZGU.THREAD_PLUGIN
637
573
  }
638
574
  ],
639
- icon: "ph--chat--regular",
575
+ icon: (props) => /* @__PURE__ */ import_react2.default.createElement(import_react.Chat, props),
576
+ iconSymbol: "ph--chat--regular",
640
577
  testId: "threadPlugin.createObject"
641
578
  }
642
579
  }
@@ -650,19 +587,21 @@ var ThreadPlugin = () => {
650
587
  component: ({ data, role }) => {
651
588
  switch (role) {
652
589
  case "main": {
653
- return data.active instanceof import_types.ChannelType && data.active.threads[0] ? /* @__PURE__ */ import_react.default.createElement(ThreadMain, {
590
+ return data.active instanceof import_types2.ChannelType && data.active.threads[0] ? /* @__PURE__ */ import_react2.default.createElement(ThreadMain, {
654
591
  thread: data.active.threads[0]
655
592
  }) : null;
656
593
  }
657
594
  case "settings": {
658
- return data.plugin === import_chunk_6EVXCSDS.meta_default.id ? /* @__PURE__ */ import_react.default.createElement(ThreadSettings, {
595
+ return data.plugin === import_chunk_BWBONZGU.meta_default.id ? /* @__PURE__ */ import_react2.default.createElement(ThreadSettings, {
659
596
  settings: settings.values
660
597
  }) : null;
661
598
  }
662
599
  case "article":
663
600
  case "complementary": {
664
601
  const location = navigationPlugin?.provides.location;
665
- if (data.object instanceof import_types.ChannelType && data.object.threads[0]) {
602
+ const threadsIntegrators = (0, import_app_framework.useResolvePlugins)(providesThreadsConfig);
603
+ const threadProvides = threadsIntegrators.map((p) => p.provides.thread);
604
+ if (data.object instanceof import_types2.ChannelType && data.object.threads[0]) {
666
605
  const channel = data.object;
667
606
  if ((0, import_app_framework.isLayoutParts)(location?.active) && location.active.main) {
668
607
  const layoutEntries = location.active.main;
@@ -670,32 +609,101 @@ var ThreadPlugin = () => {
670
609
  if (currentPosition > 0) {
671
610
  const objectToTheLeft = layoutEntries[currentPosition - 1];
672
611
  const context = (0, import_echo.getSpace)(data.object)?.db.getObjectById(objectToTheLeft.id);
673
- return /* @__PURE__ */ import_react.default.createElement(ThreadArticle, {
612
+ return /* @__PURE__ */ import_react2.default.createElement(ThreadArticle, {
674
613
  thread: data.object.threads[0],
675
614
  context
676
615
  });
677
616
  }
678
617
  }
679
- return /* @__PURE__ */ import_react.default.createElement(ThreadArticle, {
618
+ return /* @__PURE__ */ import_react2.default.createElement(ThreadArticle, {
680
619
  thread: data.object.threads[0]
681
620
  });
682
621
  }
683
- if (data.subject instanceof import_types.ThreadType) {
684
- return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(import_chunk_PZVUW4W2.ChatHeading, {
622
+ if (data.subject instanceof import_types2.ThreadType) {
623
+ return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_chunk_5PZNPPQF.ChatHeading, {
685
624
  attendableId: data.subject.id
686
- }), /* @__PURE__ */ import_react.default.createElement(import_chunk_PZVUW4W2.ChatContainer, {
625
+ }), /* @__PURE__ */ import_react2.default.createElement(import_chunk_5PZNPPQF.ChatContainer, {
687
626
  thread: data.subject
688
627
  }));
689
628
  }
690
629
  if (data.subject && typeof data.subject === "object" && "threads" in data.subject && Array.isArray(data.subject.threads)) {
691
- const { showResolvedThreads } = getViewState((0, import_echo.fullyQualifiedId)(data.subject));
692
- return /* @__PURE__ */ import_react.default.createElement(ThreadComplementary, {
693
- role,
694
- subject: data.subject,
695
- stagedThreads: state.staging[(0, import_echo.fullyQualifiedId)(data.subject)],
696
- current: state.current,
697
- showResolvedThreads
698
- });
630
+ const threads = data.subject.threads.concat(state.staging[(0, import_echo.fullyQualifiedId)(data.subject)]).filter(import_util.nonNullable);
631
+ const createSort = threadProvides.find((p) => p.predicate(data.subject))?.createSort;
632
+ if (createSort) {
633
+ const sort = createSort(data.subject);
634
+ threads.sort((a, b) => sort(a.anchor, b.anchor));
635
+ }
636
+ const detached = data.subject.threads.filter(import_util.nonNullable).filter(({ anchor }) => !anchor).map((thread) => thread.id);
637
+ const qualifiedSubjectId = (0, import_echo.fullyQualifiedId)(data.subject);
638
+ const attention = attentionPlugin?.provides.attention?.attended ?? /* @__PURE__ */ new Set([
639
+ qualifiedSubjectId
640
+ ]);
641
+ const attendableAttrs = (0, import_react_ui_attention.createAttendableAttributes)(qualifiedSubjectId);
642
+ const { showResolvedThreads } = getViewState(qualifiedSubjectId);
643
+ return /* @__PURE__ */ import_react2.default.createElement("div", {
644
+ role: "none",
645
+ className: "contents group/attention",
646
+ ...attendableAttrs
647
+ }, role === "complementary" && /* @__PURE__ */ import_react2.default.createElement(CommentsHeading, {
648
+ attendableId: qualifiedSubjectId
649
+ }), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.ScrollArea.Root, {
650
+ classNames: "row-span-2"
651
+ }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.ScrollArea.Viewport, null, /* @__PURE__ */ import_react2.default.createElement(CommentsContainer, {
652
+ threads,
653
+ detached,
654
+ currentId: attention.has(qualifiedSubjectId) ? state.current : void 0,
655
+ autoFocusCurrentTextbox: state.focus,
656
+ showResolvedThreads,
657
+ onThreadAttend: (thread) => {
658
+ if (state.current !== thread.id) {
659
+ state.current = thread.id;
660
+ void dispatch?.({
661
+ action: import_app_framework.LayoutAction.SCROLL_INTO_VIEW,
662
+ data: {
663
+ id: (0, import_echo.fullyQualifiedId)(data.subject),
664
+ thread: (0, import_echo.fullyQualifiedId)(thread),
665
+ cursor: thread.anchor
666
+ }
667
+ });
668
+ }
669
+ },
670
+ onThreadDelete: (thread) => dispatch?.({
671
+ plugin: import_chunk_BWBONZGU.THREAD_PLUGIN,
672
+ action: import_chunk_D5GOVXHS.ThreadAction.DELETE,
673
+ data: {
674
+ subject: data.subject,
675
+ thread
676
+ }
677
+ }),
678
+ onMessageDelete: (thread, messageId) => dispatch?.({
679
+ plugin: import_chunk_BWBONZGU.THREAD_PLUGIN,
680
+ action: import_chunk_D5GOVXHS.ThreadAction.DELETE_MESSAGE,
681
+ data: {
682
+ subject: data.subject,
683
+ thread,
684
+ messageId
685
+ }
686
+ }),
687
+ onThreadToggleResolved: (thread) => dispatch?.({
688
+ plugin: import_chunk_BWBONZGU.THREAD_PLUGIN,
689
+ action: import_chunk_D5GOVXHS.ThreadAction.TOGGLE_RESOLVED,
690
+ data: {
691
+ thread
692
+ }
693
+ }),
694
+ onComment: (thread) => {
695
+ void intentPlugin?.provides.intent.dispatch({
696
+ action: import_chunk_D5GOVXHS.ThreadAction.ON_MESSAGE_ADD,
697
+ data: {
698
+ thread,
699
+ subject: data.subject
700
+ }
701
+ });
702
+ }
703
+ }), /* @__PURE__ */ import_react2.default.createElement("div", {
704
+ role: "none",
705
+ className: "bs-10"
706
+ }), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.ScrollArea.Scrollbar, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.ScrollArea.Thumb, null)))));
699
707
  }
700
708
  }
701
709
  }
@@ -705,24 +713,11 @@ var ThreadPlugin = () => {
705
713
  intent: {
706
714
  resolver: async (intent) => {
707
715
  switch (intent.action) {
708
- case import_chunk_FXD3DYMO.ThreadAction.CREATE: {
716
+ case import_chunk_D5GOVXHS.ThreadAction.CREATE: {
709
717
  if (intent.data && intent.data.cursor !== void 0) {
710
718
  const { cursor, name, subject } = intent.data;
711
- if (subject?.threads === void 0) {
712
- try {
713
- subject.threads = [];
714
- } catch (e) {
715
- import_log.log.error("Subject does not support threads array", subject?.typename, {
716
- F: __dxlog_file,
717
- L: 331,
718
- S: void 0,
719
- C: (f, a) => f(...a)
720
- });
721
- return;
722
- }
723
- }
724
719
  const subjectId = (0, import_echo.fullyQualifiedId)(subject);
725
- const thread = (0, import_echo_schema2.create)(import_types.ThreadType, {
720
+ const thread = (0, import_echo_schema2.create)(import_types2.ThreadType, {
726
721
  name,
727
722
  anchor: cursor,
728
723
  messages: [],
@@ -741,9 +736,18 @@ var ThreadPlugin = () => {
741
736
  intents: [
742
737
  [
743
738
  {
744
- action: import_chunk_FXD3DYMO.ThreadAction.SELECT,
739
+ action: import_app_framework.NavigationAction.OPEN,
740
+ data: {
741
+ activeParts: {
742
+ complementary: `${subjectId}${import_app_framework.SLUG_PATH_SEPARATOR}comments${import_app_framework.SLUG_COLLECTION_INDICATOR}`
743
+ }
744
+ }
745
+ },
746
+ {
747
+ action: import_chunk_D5GOVXHS.ThreadAction.SELECT,
745
748
  data: {
746
- current: (0, import_echo.fullyQualifiedId)(thread)
749
+ current: thread.id,
750
+ focus: true
747
751
  }
748
752
  },
749
753
  {
@@ -759,9 +763,9 @@ var ThreadPlugin = () => {
759
763
  };
760
764
  } else {
761
765
  return {
762
- data: (0, import_echo_schema2.create)(import_types.ChannelType, {
766
+ data: (0, import_echo_schema2.create)(import_types2.ChannelType, {
763
767
  threads: [
764
- (0, import_echo_schema2.create)(import_types.ThreadType, {
768
+ (0, import_echo_schema2.create)(import_types2.ThreadType, {
765
769
  messages: []
766
770
  })
767
771
  ]
@@ -769,15 +773,16 @@ var ThreadPlugin = () => {
769
773
  };
770
774
  }
771
775
  }
772
- case import_chunk_FXD3DYMO.ThreadAction.SELECT: {
776
+ case import_chunk_D5GOVXHS.ThreadAction.SELECT: {
777
+ state.focus = intent.data?.current === state.current ? state.focus : intent.data?.focus;
773
778
  state.current = intent.data?.current;
774
779
  return {
775
780
  data: true
776
781
  };
777
782
  }
778
- case import_chunk_FXD3DYMO.ThreadAction.TOGGLE_RESOLVED: {
783
+ case import_chunk_D5GOVXHS.ThreadAction.TOGGLE_RESOLVED: {
779
784
  const { thread } = intent.data ?? {};
780
- if (!(thread instanceof import_types.ThreadType)) {
785
+ if (!(thread instanceof import_types2.ThreadType)) {
781
786
  return;
782
787
  }
783
788
  if (thread.status === "active" || thread.status === void 0) {
@@ -804,9 +809,9 @@ var ThreadPlugin = () => {
804
809
  ]
805
810
  };
806
811
  }
807
- case import_chunk_FXD3DYMO.ThreadAction.DELETE: {
812
+ case import_chunk_D5GOVXHS.ThreadAction.DELETE: {
808
813
  const { subject, thread } = intent.data ?? {};
809
- if (!(thread instanceof import_types.ThreadType) || !(subject && typeof subject === "object" && "threads" in subject)) {
814
+ if (!(subject instanceof import_types.DocumentType) || !(thread instanceof import_types2.ThreadType)) {
810
815
  return;
811
816
  }
812
817
  const subjectId = (0, import_echo.fullyQualifiedId)(subject);
@@ -815,9 +820,7 @@ var ThreadPlugin = () => {
815
820
  const index = stagingArea.findIndex((t) => t.id === thread.id);
816
821
  if (index !== -1) {
817
822
  stagingArea.splice(index, 1);
818
- return {
819
- data: true
820
- };
823
+ return;
821
824
  }
822
825
  }
823
826
  const space = (0, import_echo.getSpace)(thread);
@@ -833,7 +836,7 @@ var ThreadPlugin = () => {
833
836
  space.db.remove(thread);
834
837
  return {
835
838
  undoable: {
836
- message: translations_default[0]["en-US"][import_chunk_6EVXCSDS.THREAD_PLUGIN]["thread deleted label"],
839
+ message: translations_default[0]["en-US"][import_chunk_BWBONZGU.THREAD_PLUGIN]["thread deleted label"],
837
840
  data: {
838
841
  cursor
839
842
  }
@@ -876,9 +879,9 @@ var ThreadPlugin = () => {
876
879
  }
877
880
  break;
878
881
  }
879
- case import_chunk_FXD3DYMO.ThreadAction.ON_MESSAGE_ADD: {
882
+ case import_chunk_D5GOVXHS.ThreadAction.ON_MESSAGE_ADD: {
880
883
  const { thread, subject } = intent.data ?? {};
881
- if (!(thread instanceof import_types.ThreadType) || !(subject && typeof subject === "object" && "threads" in subject && Array.isArray(subject.threads))) {
884
+ if (!(thread instanceof import_types2.ThreadType) || !(subject && typeof subject === "object" && "threads" in subject)) {
882
885
  return;
883
886
  }
884
887
  const subjectId = (0, import_echo.fullyQualifiedId)(subject);
@@ -919,10 +922,10 @@ var ThreadPlugin = () => {
919
922
  ]
920
923
  };
921
924
  }
922
- case import_chunk_FXD3DYMO.ThreadAction.DELETE_MESSAGE: {
925
+ case import_chunk_D5GOVXHS.ThreadAction.DELETE_MESSAGE: {
923
926
  const { subject, thread, messageId } = intent.data ?? {};
924
927
  const space = (0, import_echo.getSpace)(subject);
925
- if (!(thread instanceof import_types.ThreadType) || !(subject && typeof subject === "object" && "threads" in subject)) {
928
+ if (!(subject instanceof import_types.DocumentType) || !(thread instanceof import_types2.ThreadType) || !space) {
926
929
  return;
927
930
  }
928
931
  if (!intent.undo) {
@@ -936,7 +939,7 @@ var ThreadPlugin = () => {
936
939
  intents: [
937
940
  [
938
941
  {
939
- action: import_chunk_FXD3DYMO.ThreadAction.DELETE,
942
+ action: import_chunk_D5GOVXHS.ThreadAction.DELETE,
940
943
  data: {
941
944
  subject,
942
945
  thread
@@ -950,7 +953,7 @@ var ThreadPlugin = () => {
950
953
  }
951
954
  return {
952
955
  undoable: {
953
- message: translations_default[0]["en-US"][import_chunk_6EVXCSDS.THREAD_PLUGIN]["message deleted label"],
956
+ message: translations_default[0]["en-US"][import_chunk_BWBONZGU.THREAD_PLUGIN]["message deleted label"],
954
957
  data: {
955
958
  message,
956
959
  messageIndex
@@ -964,7 +967,7 @@ var ThreadPlugin = () => {
964
967
  name: "threads.message.delete",
965
968
  properties: {
966
969
  threadId: thread.id,
967
- spaceId: space?.id
970
+ spaceId: space.id
968
971
  }
969
972
  }
970
973
  }
@@ -974,7 +977,7 @@ var ThreadPlugin = () => {
974
977
  } else if (intent.undo) {
975
978
  const message = intent.data?.message;
976
979
  const messageIndex = intent.data?.messageIndex;
977
- if (!(message instanceof import_types.MessageType) || !(typeof messageIndex === "number")) {
980
+ if (!(message instanceof import_types2.MessageType) || !(typeof messageIndex === "number")) {
978
981
  return;
979
982
  }
980
983
  thread.messages.splice(messageIndex, 0, message);
@@ -988,7 +991,7 @@ var ThreadPlugin = () => {
988
991
  name: "threads.message.undo-delete",
989
992
  properties: {
990
993
  threadId: thread.id,
991
- spaceId: space?.id
994
+ spaceId: space.id
992
995
  }
993
996
  }
994
997
  }
@@ -1029,19 +1032,19 @@ var ThreadPlugin = () => {
1029
1032
  });
1030
1033
  }
1031
1034
  }),
1032
- (0, import_react_ui_editor.createExternalCommentSync)((0, import_echo.fullyQualifiedId)(doc), (sink) => (0, import_signals_core.effect)(() => sink()), () => threads.value.filter((thread) => thread?.anchor).map((thread) => ({
1033
- id: (0, import_echo.fullyQualifiedId)(thread),
1035
+ (0, import_react_ui_editor.createExternalCommentSync)(doc.id, (sink) => (0, import_signals_core.effect)(() => sink()), () => threads.value.filter((thread) => thread?.anchor).map((thread) => ({
1036
+ id: thread.id,
1034
1037
  cursor: thread.anchor
1035
1038
  }))),
1036
1039
  (0, import_react_ui_editor.comments)({
1037
- id: (0, import_echo.fullyQualifiedId)(doc),
1040
+ id: doc.id,
1038
1041
  onCreate: ({ cursor }) => {
1039
1042
  const [start, end] = cursor.split(":");
1040
1043
  const name = doc.content && (0, import_echo.getTextInRange)((0, import_echo.createDocAccessor)(doc.content, [
1041
1044
  "content"
1042
1045
  ]), start, end);
1043
1046
  void intentPlugin?.provides.intent.dispatch({
1044
- action: import_chunk_FXD3DYMO.ThreadAction.CREATE,
1047
+ action: import_chunk_D5GOVXHS.ThreadAction.CREATE,
1045
1048
  data: {
1046
1049
  cursor,
1047
1050
  name,
@@ -1052,7 +1055,7 @@ var ThreadPlugin = () => {
1052
1055
  onDelete: ({ id }) => {
1053
1056
  const stagingArea = state.staging[(0, import_echo.fullyQualifiedId)(doc)];
1054
1057
  if (stagingArea) {
1055
- const index = stagingArea.findIndex((thread2) => (0, import_echo.fullyQualifiedId)(thread2) === id);
1058
+ const index = stagingArea.findIndex((thread2) => thread2.id === id);
1056
1059
  if (index !== -1) {
1057
1060
  stagingArea.splice(index, 1);
1058
1061
  }
@@ -1063,8 +1066,8 @@ var ThreadPlugin = () => {
1063
1066
  }
1064
1067
  },
1065
1068
  onUpdate: ({ id, cursor }) => {
1066
- const thread = state.staging[(0, import_echo.fullyQualifiedId)(doc)]?.find((thread2) => (0, import_echo.fullyQualifiedId)(thread2) === id) ?? doc.threads.find((thread2) => thread2?.id === id);
1067
- if (thread instanceof import_types.ThreadType && thread.anchor) {
1069
+ const thread = state.staging[(0, import_echo.fullyQualifiedId)(doc)]?.find((thread2) => thread2.id === id) ?? doc.threads.find((thread2) => thread2?.id === id);
1070
+ if (thread instanceof import_types2.ThreadType && thread.anchor) {
1068
1071
  const [start, end] = thread.anchor.split(":");
1069
1072
  thread.name = doc.content && (0, import_echo.getTextInRange)((0, import_echo.createDocAccessor)(doc.content, [
1070
1073
  "content"
@@ -1073,11 +1076,11 @@ var ThreadPlugin = () => {
1073
1076
  }
1074
1077
  },
1075
1078
  onSelect: ({ selection: { current, closest } }) => {
1076
- const dispatch = intentPlugin?.provides.intent.dispatch;
1077
- if (dispatch) {
1078
- void dispatch([
1079
+ const dispatch2 = intentPlugin?.provides.intent.dispatch;
1080
+ if (dispatch2) {
1081
+ void dispatch2([
1079
1082
  {
1080
- action: import_chunk_FXD3DYMO.ThreadAction.SELECT,
1083
+ action: import_chunk_D5GOVXHS.ThreadAction.SELECT,
1081
1084
  data: {
1082
1085
  current: current ?? closest
1083
1086
  }