@dxos/plugin-thread 0.6.13-staging.1e988a3 → 0.6.14-main.1366248

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