@dxos/plugin-thread 0.6.13 → 0.6.14-main.69511f5

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