@dxos/plugin-thread 0.6.8-main.046e6cf
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +8 -0
- package/README.md +15 -0
- package/dist/lib/browser/ThreadArticle-J4VCLPMS.mjs +18 -0
- package/dist/lib/browser/ThreadArticle-J4VCLPMS.mjs.map +7 -0
- package/dist/lib/browser/ThreadMain-VV7MGQZJ.mjs +26 -0
- package/dist/lib/browser/ThreadMain-VV7MGQZJ.mjs.map +7 -0
- package/dist/lib/browser/chunk-5IBJO53M.mjs +21 -0
- package/dist/lib/browser/chunk-5IBJO53M.mjs.map +7 -0
- package/dist/lib/browser/chunk-CQ2RYETH.mjs +410 -0
- package/dist/lib/browser/chunk-CQ2RYETH.mjs.map +7 -0
- package/dist/lib/browser/chunk-TL3JITN7.mjs +19 -0
- package/dist/lib/browser/chunk-TL3JITN7.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1062 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/browser/meta.mjs +11 -0
- package/dist/lib/browser/meta.mjs.map +7 -0
- package/dist/lib/browser/types.mjs +8 -0
- package/dist/lib/browser/types.mjs.map +7 -0
- package/dist/lib/node/ThreadArticle-CSENFNNT.cjs +44 -0
- package/dist/lib/node/ThreadArticle-CSENFNNT.cjs.map +7 -0
- package/dist/lib/node/ThreadMain-XP4YSF7U.cjs +52 -0
- package/dist/lib/node/ThreadMain-XP4YSF7U.cjs.map +7 -0
- package/dist/lib/node/chunk-3VAAUEU5.cjs +431 -0
- package/dist/lib/node/chunk-3VAAUEU5.cjs.map +7 -0
- package/dist/lib/node/chunk-BWBONZGU.cjs +55 -0
- package/dist/lib/node/chunk-BWBONZGU.cjs.map +7 -0
- package/dist/lib/node/chunk-WPPLQNMJ.cjs +38 -0
- package/dist/lib/node/chunk-WPPLQNMJ.cjs.map +7 -0
- package/dist/lib/node/index.cjs +1067 -0
- package/dist/lib/node/index.cjs.map +7 -0
- package/dist/lib/node/meta.cjs +32 -0
- package/dist/lib/node/meta.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -0
- package/dist/lib/node/types.cjs +30 -0
- package/dist/lib/node/types.cjs.map +7 -0
- package/dist/types/src/ThreadPlugin.d.ts +4 -0
- package/dist/types/src/ThreadPlugin.d.ts.map +1 -0
- package/dist/types/src/components/Chat.stories.d.ts +46 -0
- package/dist/types/src/components/Chat.stories.d.ts.map +1 -0
- package/dist/types/src/components/ChatContainer.d.ts +7 -0
- package/dist/types/src/components/ChatContainer.d.ts.map +1 -0
- package/dist/types/src/components/CommentContainer.d.ts +4 -0
- package/dist/types/src/components/CommentContainer.d.ts.map +1 -0
- package/dist/types/src/components/Comments.stories.d.ts +44 -0
- package/dist/types/src/components/Comments.stories.d.ts.map +1 -0
- package/dist/types/src/components/CommentsContainer.d.ts +26 -0
- package/dist/types/src/components/CommentsContainer.d.ts.map +1 -0
- package/dist/types/src/components/MessageContainer.d.ts +9 -0
- package/dist/types/src/components/MessageContainer.d.ts.map +1 -0
- package/dist/types/src/components/ThreadArticle.d.ts +5 -0
- package/dist/types/src/components/ThreadArticle.d.ts.map +1 -0
- package/dist/types/src/components/ThreadMain.d.ts +7 -0
- package/dist/types/src/components/ThreadMain.d.ts.map +1 -0
- package/dist/types/src/components/ThreadSettings.d.ts +6 -0
- package/dist/types/src/components/ThreadSettings.d.ts.map +1 -0
- package/dist/types/src/components/command-extension.d.ts +3 -0
- package/dist/types/src/components/command-extension.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +22 -0
- package/dist/types/src/components/index.d.ts.map +1 -0
- package/dist/types/src/components/testing.d.ts +67 -0
- package/dist/types/src/components/testing.d.ts.map +1 -0
- package/dist/types/src/components/types.d.ts +28 -0
- package/dist/types/src/components/types.d.ts.map +1 -0
- package/dist/types/src/hooks/analytics.d.ts +4 -0
- package/dist/types/src/hooks/analytics.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +3 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useStatus.d.ts +3 -0
- package/dist/types/src/hooks/useStatus.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +6 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +16 -0
- package/dist/types/src/meta.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +34 -0
- package/dist/types/src/translations.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +19 -0
- package/dist/types/src/types.d.ts.map +1 -0
- package/dist/types/src/types.test.d.ts +2 -0
- package/dist/types/src/types.test.d.ts.map +1 -0
- package/dist/types/src/util.d.ts +6 -0
- package/dist/types/src/util.d.ts.map +1 -0
- package/package.json +99 -0
- package/src/ThreadPlugin.tsx +744 -0
- package/src/components/Chat.stories.tsx +76 -0
- package/src/components/ChatContainer.tsx +127 -0
- package/src/components/CommentContainer.tsx +206 -0
- package/src/components/Comments.stories.tsx +66 -0
- package/src/components/CommentsContainer.tsx +114 -0
- package/src/components/MessageContainer.tsx +200 -0
- package/src/components/ThreadArticle.tsx +18 -0
- package/src/components/ThreadMain.tsx +27 -0
- package/src/components/ThreadSettings.tsx +23 -0
- package/src/components/command-extension.ts +36 -0
- package/src/components/index.ts +16 -0
- package/src/components/testing.ts +46 -0
- package/src/components/types.ts +32 -0
- package/src/hooks/analytics.ts +39 -0
- package/src/hooks/index.ts +6 -0
- package/src/hooks/useStatus.ts +39 -0
- package/src/index.ts +12 -0
- package/src/meta.tsx +20 -0
- package/src/translations.ts +41 -0
- package/src/types.test.ts +13 -0
- package/src/types.ts +41 -0
- package/src/util.ts +26 -0
|
@@ -0,0 +1,1067 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var node_exports = {};
|
|
30
|
+
__export(node_exports, {
|
|
31
|
+
ThreadAction: () => import_chunk_WPPLQNMJ.ThreadAction,
|
|
32
|
+
ThreadPlugin: () => ThreadPlugin,
|
|
33
|
+
default: () => src_default,
|
|
34
|
+
useAnalyticsCallback: () => import_chunk_3VAAUEU5.useAnalyticsCallback,
|
|
35
|
+
useOnEditAnalytics: () => import_chunk_3VAAUEU5.useOnEditAnalytics,
|
|
36
|
+
useStatus: () => import_chunk_3VAAUEU5.useStatus
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(node_exports);
|
|
39
|
+
var import_chunk_WPPLQNMJ = require("./chunk-WPPLQNMJ.cjs");
|
|
40
|
+
var import_chunk_3VAAUEU5 = require("./chunk-3VAAUEU5.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"));
|
|
45
|
+
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
|
+
var import_local_storage = require("@dxos/local-storage");
|
|
49
|
+
var import_plugin_attention = require("@dxos/plugin-attention");
|
|
50
|
+
var import_plugin_client = require("@dxos/plugin-client");
|
|
51
|
+
var import_plugin_graph = require("@dxos/plugin-graph");
|
|
52
|
+
var import_types = require("@dxos/plugin-markdown/types");
|
|
53
|
+
var import_meta = require("@dxos/plugin-observability/meta");
|
|
54
|
+
var import_plugin_space = require("@dxos/plugin-space");
|
|
55
|
+
var import_types2 = require("@dxos/plugin-space/types");
|
|
56
|
+
var import_echo = require("@dxos/react-client/echo");
|
|
57
|
+
var import_react_ui = require("@dxos/react-ui");
|
|
58
|
+
var import_react_ui_attention = require("@dxos/react-ui-attention");
|
|
59
|
+
var import_react_ui_editor = require("@dxos/react-ui-editor");
|
|
60
|
+
var import_react_ui_thread = require("@dxos/react-ui-thread");
|
|
61
|
+
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
|
+
var import_react5 = require("@phosphor-icons/react");
|
|
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");
|
|
72
|
+
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");
|
|
76
|
+
var import_util2 = require("@dxos/util");
|
|
77
|
+
var import_react7 = require("@phosphor-icons/react");
|
|
78
|
+
var import_react8 = __toESM(require("react"));
|
|
79
|
+
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
|
+
};
|
|
91
|
+
var sizeClass = (0, import_react_ui_theme.getSize)(4);
|
|
92
|
+
var ToggleResolvedButton = ({ isResolved, onResolve }) => {
|
|
93
|
+
const { t } = (0, import_react_ui3.useTranslation)(import_chunk_BWBONZGU.THREAD_PLUGIN);
|
|
94
|
+
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, {
|
|
96
|
+
asChild: true
|
|
97
|
+
}, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Button, {
|
|
98
|
+
variant: "ghost",
|
|
99
|
+
"data-testid": "thread.toggle-resolved",
|
|
100
|
+
onClick: onResolve,
|
|
101
|
+
classNames: [
|
|
102
|
+
"min-bs-0 p-1",
|
|
103
|
+
!isResolved && import_react_ui_theme.hoverableControlItem
|
|
104
|
+
]
|
|
105
|
+
}, /* @__PURE__ */ import_react6.default.createElement("span", {
|
|
106
|
+
className: "sr-only"
|
|
107
|
+
}, label), isResolved ? /* @__PURE__ */ import_react6.default.createElement(import_react5.CheckCircle, {
|
|
108
|
+
className: sizeClass,
|
|
109
|
+
weight: "fill"
|
|
110
|
+
}) : /* @__PURE__ */ import_react6.default.createElement(import_react5.CheckCircle, {
|
|
111
|
+
className: sizeClass
|
|
112
|
+
}))), /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Portal, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Content, {
|
|
113
|
+
classNames: "z-[21]"
|
|
114
|
+
}, label, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Arrow, null))));
|
|
115
|
+
};
|
|
116
|
+
var DeleteThreadButton = ({ onDelete }) => {
|
|
117
|
+
const { t } = (0, import_react_ui3.useTranslation)(import_chunk_BWBONZGU.THREAD_PLUGIN);
|
|
118
|
+
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, {
|
|
120
|
+
asChild: true
|
|
121
|
+
}, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Button, {
|
|
122
|
+
variant: "ghost",
|
|
123
|
+
"data-testid": "thread.delete",
|
|
124
|
+
onClick: onDelete,
|
|
125
|
+
classNames: [
|
|
126
|
+
"min-bs-0 p-1",
|
|
127
|
+
import_react_ui_theme.hoverableControlItem
|
|
128
|
+
]
|
|
129
|
+
}, /* @__PURE__ */ import_react6.default.createElement("span", {
|
|
130
|
+
className: "sr-only"
|
|
131
|
+
}, label), /* @__PURE__ */ import_react6.default.createElement(import_react5.X, {
|
|
132
|
+
className: sizeClass
|
|
133
|
+
}))), /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Portal, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Content, {
|
|
134
|
+
classNames: "z-[21]"
|
|
135
|
+
}, label, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Arrow, null))));
|
|
136
|
+
};
|
|
137
|
+
var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
|
|
138
|
+
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_3VAAUEU5.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_3VAAUEU5.getMessageMetadata)(thread.id, identity);
|
|
147
|
+
const [_count, _setCount] = (0, import_react6.useState)(0);
|
|
148
|
+
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)({
|
|
152
|
+
placeholder: t("message placeholder")
|
|
153
|
+
}),
|
|
154
|
+
(0, import_react_ui_editor2.createThemeExtensions)({
|
|
155
|
+
themeMode
|
|
156
|
+
}),
|
|
157
|
+
(0, import_react_ui_editor2.listener)({
|
|
158
|
+
onChange: (text) => messageRef.current = text
|
|
159
|
+
}),
|
|
160
|
+
import_chunk_3VAAUEU5.command
|
|
161
|
+
], [
|
|
162
|
+
_count
|
|
163
|
+
]);
|
|
164
|
+
(0, import_react6.useEffect)(() => {
|
|
165
|
+
setAutoFocus(!!autoFocusTextbox);
|
|
166
|
+
}, [
|
|
167
|
+
autoFocusTextbox
|
|
168
|
+
]);
|
|
169
|
+
const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
|
|
170
|
+
behavior,
|
|
171
|
+
block: "end"
|
|
172
|
+
}), 10);
|
|
173
|
+
const handleCreate = (0, import_react6.useCallback)(() => {
|
|
174
|
+
if (!messageRef.current) {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
thread.messages.push((0, import_echo_schema3.create)(import_types3.MessageType, {
|
|
178
|
+
sender: {
|
|
179
|
+
identityKey: identity.identityKey.toHex()
|
|
180
|
+
},
|
|
181
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
182
|
+
text: messageRef.current,
|
|
183
|
+
context
|
|
184
|
+
}));
|
|
185
|
+
onComment?.(thread);
|
|
186
|
+
messageRef.current = "";
|
|
187
|
+
setAutoFocus(true);
|
|
188
|
+
scrollToEnd("instant");
|
|
189
|
+
rerenderEditor();
|
|
190
|
+
return true;
|
|
191
|
+
}, [
|
|
192
|
+
thread,
|
|
193
|
+
identity
|
|
194
|
+
]);
|
|
195
|
+
const handleDeleteMessage = (id) => onMessageDelete?.(id);
|
|
196
|
+
return /* @__PURE__ */ import_react6.default.createElement(import_react_ui_thread2.Thread, {
|
|
197
|
+
onClickCapture: onAttend,
|
|
198
|
+
onFocusCapture: onAttend,
|
|
199
|
+
current,
|
|
200
|
+
id: thread.id
|
|
201
|
+
}, /* @__PURE__ */ import_react6.default.createElement("div", {
|
|
202
|
+
role: "none",
|
|
203
|
+
className: (0, import_react_ui_theme.mx)("col-span-2 grid grid-cols-[var(--rail-size)_1fr_min-content]", import_react_ui_theme.hoverableControls, import_react_ui_theme.hoverableFocusedWithinControls)
|
|
204
|
+
}, detached ? /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Root, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tooltip.Trigger, {
|
|
205
|
+
asChild: true
|
|
206
|
+
}, /* @__PURE__ */ import_react6.default.createElement(import_react_ui_thread2.ThreadHeading, {
|
|
207
|
+
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, {
|
|
209
|
+
classNames: "z-[21]",
|
|
210
|
+
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", {
|
|
212
|
+
className: "flex flex-row items-center pli-1"
|
|
213
|
+
}, thread.status === "staged" && /* @__PURE__ */ import_react6.default.createElement(import_react_ui3.Tag, {
|
|
214
|
+
palette: "neutral"
|
|
215
|
+
}, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */ import_react6.default.createElement(ToggleResolvedButton, {
|
|
216
|
+
isResolved: thread?.status === "resolved",
|
|
217
|
+
onResolve
|
|
218
|
+
}), onThreadDelete && /* @__PURE__ */ import_react6.default.createElement(DeleteThreadButton, {
|
|
219
|
+
onDelete: onThreadDelete
|
|
220
|
+
}))), thread.messages.filter(import_util2.nonNullable).map((message) => /* @__PURE__ */ import_react6.default.createElement(import_chunk_3VAAUEU5.MessageContainer, {
|
|
221
|
+
key: message.id,
|
|
222
|
+
message,
|
|
223
|
+
members,
|
|
224
|
+
onDelete: handleDeleteMessage
|
|
225
|
+
})), /* @__PURE__ */ import_react6.default.createElement(import_react_ui_thread2.MessageTextbox, {
|
|
226
|
+
extensions,
|
|
227
|
+
autoFocus,
|
|
228
|
+
onSend: handleCreate,
|
|
229
|
+
...textboxMetadata
|
|
230
|
+
}), /* @__PURE__ */ import_react6.default.createElement(import_react_ui_thread2.ThreadFooter, {
|
|
231
|
+
activity
|
|
232
|
+
}, t("activity message")), /* @__PURE__ */ import_react6.default.createElement("div", {
|
|
233
|
+
role: "none",
|
|
234
|
+
className: "bs-px -mbs-px",
|
|
235
|
+
ref: threadScrollRef
|
|
236
|
+
}));
|
|
237
|
+
};
|
|
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)(() => {
|
|
253
|
+
if (currentId) {
|
|
254
|
+
document.getElementById(currentId)?.scrollIntoView({
|
|
255
|
+
behavior: "smooth",
|
|
256
|
+
block: "end"
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}, [
|
|
260
|
+
currentId
|
|
261
|
+
]);
|
|
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", {
|
|
282
|
+
role: "alert",
|
|
283
|
+
className: (0, import_react_ui_theme2.mx)(import_react_ui_theme2.descriptionText, "place-self-center border border-dashed border-neutral-400/50 rounded-lg text-center p-4 m-4")
|
|
284
|
+
}, /* @__PURE__ */ import_react8.default.createElement("h2", {
|
|
285
|
+
className: "mbe-2 font-medium text-base"
|
|
286
|
+
}, t("no comments title")), /* @__PURE__ */ import_react8.default.createElement("p", null, /* @__PURE__ */ import_react8.default.createElement(import_react_ui4.Trans, {
|
|
287
|
+
t,
|
|
288
|
+
i18nKey: "no comments message",
|
|
289
|
+
components: {
|
|
290
|
+
commentIcon: /* @__PURE__ */ import_react8.default.createElement(import_react7.ChatText, {
|
|
291
|
+
className: "inline-block"
|
|
292
|
+
})
|
|
293
|
+
}
|
|
294
|
+
}))));
|
|
295
|
+
};
|
|
296
|
+
var ThreadMain = import_react3.default.lazy(() => import("./ThreadMain-XP4YSF7U.cjs"));
|
|
297
|
+
var ThreadArticle = import_react3.default.lazy(() => import("./ThreadArticle-CSENFNNT.cjs"));
|
|
298
|
+
var translations_default = [
|
|
299
|
+
{
|
|
300
|
+
"en-US": {
|
|
301
|
+
[import_chunk_BWBONZGU.THREAD_PLUGIN]: {
|
|
302
|
+
"plugin name": "Threads",
|
|
303
|
+
"channel name placeholder": "New channel",
|
|
304
|
+
"channel title label": "Title",
|
|
305
|
+
"delete channel label": "Delete channel",
|
|
306
|
+
"create channel label": "Create channel",
|
|
307
|
+
"message placeholder": "Reply\u2026",
|
|
308
|
+
"settings standalone label": "Enable channel creation (experimental)",
|
|
309
|
+
"activity message": "Processing\u2026",
|
|
310
|
+
"anonymous label": "Anonymous",
|
|
311
|
+
"delete message block label": "Delete message block",
|
|
312
|
+
"detached thread label": "Referenced content was removed",
|
|
313
|
+
"delete thread label": "Delete thread",
|
|
314
|
+
"thread deleted label": "You deleted a thread.",
|
|
315
|
+
"message deleted label": "You deleted a message.",
|
|
316
|
+
"comments heading": "Comments",
|
|
317
|
+
"chat heading": "Chat",
|
|
318
|
+
"draft button": "DRAFT",
|
|
319
|
+
"no comments title": "No comments (yet)",
|
|
320
|
+
"no comments message": "To start a comment thread, select a range of text in a document and click the <commentIcon></commentIcon> Create comment button in the toolbar.",
|
|
321
|
+
"toggle show resolved": "Show resolved",
|
|
322
|
+
"unnamed object threads label": "Threads",
|
|
323
|
+
"mark as resolved label": "Mark as resolved",
|
|
324
|
+
"mark as unresolved label": "Mark as unresolved",
|
|
325
|
+
"save message label": "Save",
|
|
326
|
+
"edit message label": "Edit",
|
|
327
|
+
"delete message label": "Delete message"
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
];
|
|
332
|
+
var initialViewState = {
|
|
333
|
+
showResolvedThreads: false
|
|
334
|
+
};
|
|
335
|
+
var ThreadPlugin = () => {
|
|
336
|
+
const settings = new import_local_storage.LocalStorageStore(import_chunk_BWBONZGU.THREAD_PLUGIN);
|
|
337
|
+
const state = (0, import_echo_schema2.create)({
|
|
338
|
+
staging: {}
|
|
339
|
+
});
|
|
340
|
+
const viewStore = (0, import_echo_schema2.create)({});
|
|
341
|
+
const getViewState = (subjectId) => {
|
|
342
|
+
if (!viewStore[subjectId]) {
|
|
343
|
+
viewStore[subjectId] = {
|
|
344
|
+
...initialViewState
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
return viewStore[subjectId];
|
|
348
|
+
};
|
|
349
|
+
let attentionPlugin;
|
|
350
|
+
let navigationPlugin;
|
|
351
|
+
let intentPlugin;
|
|
352
|
+
let dispatch;
|
|
353
|
+
const unsubscribeCallbacks = [];
|
|
354
|
+
return {
|
|
355
|
+
meta: import_chunk_BWBONZGU.meta_default,
|
|
356
|
+
ready: async (plugins) => {
|
|
357
|
+
settings.prop({
|
|
358
|
+
key: "standalone",
|
|
359
|
+
type: import_local_storage.LocalStorageStore.bool({
|
|
360
|
+
allowUndefined: true
|
|
361
|
+
})
|
|
362
|
+
});
|
|
363
|
+
attentionPlugin = (0, import_app_framework.resolvePlugin)(plugins, import_plugin_attention.parseAttentionPlugin);
|
|
364
|
+
navigationPlugin = (0, import_app_framework.resolvePlugin)(plugins, import_app_framework.parseNavigationPlugin);
|
|
365
|
+
intentPlugin = (0, import_app_framework.resolvePlugin)(plugins, import_app_framework.parseIntentPlugin);
|
|
366
|
+
dispatch = intentPlugin?.provides.intent.dispatch;
|
|
367
|
+
const graphPlugin = (0, import_app_framework.resolvePlugin)(plugins, import_app_framework.parseGraphPlugin);
|
|
368
|
+
const client = (0, import_app_framework.resolvePlugin)(plugins, import_plugin_client.parseClientPlugin)?.provides.client;
|
|
369
|
+
if (!client) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const channelsQuery = client.spaces.query(import_echo.Filter.schema(import_types2.ChannelType));
|
|
373
|
+
const queryUnsubscribe = channelsQuery.subscribe();
|
|
374
|
+
const unsubscribe = (0, import_signals_core.effect)(() => {
|
|
375
|
+
const attention = attentionPlugin?.provides.attention;
|
|
376
|
+
if (!attention?.attended) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
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);
|
|
380
|
+
if (firstAttendedNodeWithComments) {
|
|
381
|
+
void intentPlugin?.provides.intent.dispatch({
|
|
382
|
+
action: import_app_framework.NavigationAction.OPEN,
|
|
383
|
+
data: {
|
|
384
|
+
activeParts: {
|
|
385
|
+
complementary: `${firstAttendedNodeWithComments.id}${import_app_framework.SLUG_PATH_SEPARATOR}comments`
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
unsubscribeCallbacks.push(queryUnsubscribe);
|
|
392
|
+
unsubscribeCallbacks.push(unsubscribe);
|
|
393
|
+
},
|
|
394
|
+
unload: async () => {
|
|
395
|
+
unsubscribeCallbacks.forEach((unsubscribe) => unsubscribe());
|
|
396
|
+
},
|
|
397
|
+
provides: {
|
|
398
|
+
settings: settings.values,
|
|
399
|
+
metadata: {
|
|
400
|
+
records: {
|
|
401
|
+
[import_types2.ChannelType.typename]: {
|
|
402
|
+
placeholder: [
|
|
403
|
+
"channel title placeholder",
|
|
404
|
+
{
|
|
405
|
+
ns: import_chunk_BWBONZGU.THREAD_PLUGIN
|
|
406
|
+
}
|
|
407
|
+
],
|
|
408
|
+
icon: (props) => /* @__PURE__ */ import_react2.default.createElement(import_react.Chat, props),
|
|
409
|
+
iconSymbol: "ph--chat--regular",
|
|
410
|
+
// TODO(wittjosiah): Move out of metadata.
|
|
411
|
+
loadReferences: (channel) => (0, import_echo.loadObjectReferences)(channel, (channel2) => channel2.threads)
|
|
412
|
+
},
|
|
413
|
+
[import_types2.ThreadType.typename]: {
|
|
414
|
+
// TODO(wittjosiah): Move out of metadata.
|
|
415
|
+
loadReferences: (thread) => (0, import_echo.loadObjectReferences)(thread, (thread2) => thread2.messages)
|
|
416
|
+
},
|
|
417
|
+
[import_types2.MessageType.typename]: {
|
|
418
|
+
// TODO(wittjosiah): Move out of metadata.
|
|
419
|
+
loadReferences: (message) => []
|
|
420
|
+
},
|
|
421
|
+
[import_chunk_BWBONZGU.THREAD_ITEM]: {
|
|
422
|
+
parse: (item, type) => {
|
|
423
|
+
switch (type) {
|
|
424
|
+
case "node":
|
|
425
|
+
return {
|
|
426
|
+
id: item.id,
|
|
427
|
+
label: item.title,
|
|
428
|
+
data: item
|
|
429
|
+
};
|
|
430
|
+
case "object":
|
|
431
|
+
return item;
|
|
432
|
+
case "view-object":
|
|
433
|
+
return {
|
|
434
|
+
id: `${item.id}-view`,
|
|
435
|
+
object: item
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
translations: [
|
|
443
|
+
...translations_default,
|
|
444
|
+
...import_react_ui_thread.translations
|
|
445
|
+
],
|
|
446
|
+
echo: {
|
|
447
|
+
schema: [
|
|
448
|
+
import_types2.ChannelType,
|
|
449
|
+
import_types2.ThreadType,
|
|
450
|
+
import_types2.MessageType
|
|
451
|
+
]
|
|
452
|
+
},
|
|
453
|
+
graph: {
|
|
454
|
+
builder: (plugins) => {
|
|
455
|
+
const client = (0, import_app_framework.resolvePlugin)(plugins, import_plugin_client.parseClientPlugin)?.provides.client;
|
|
456
|
+
const dispatch2 = (0, import_app_framework.resolvePlugin)(plugins, import_app_framework.parseIntentPlugin)?.provides.intent.dispatch;
|
|
457
|
+
const metadataResolver = (0, import_app_framework.resolvePlugin)(plugins, import_app_framework.parseMetadataResolverPlugin)?.provides.metadata.resolver;
|
|
458
|
+
if (!client || !dispatch2 || !metadataResolver) {
|
|
459
|
+
return [];
|
|
460
|
+
}
|
|
461
|
+
return [
|
|
462
|
+
(0, import_plugin_graph.createExtension)({
|
|
463
|
+
id: `${import_chunk_BWBONZGU.THREAD_PLUGIN}/comments-for-subject`,
|
|
464
|
+
resolver: ({ id }) => {
|
|
465
|
+
if (!id.endsWith("~comments")) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
const docId = id.split("~").at(0);
|
|
469
|
+
const [spaceId, objectId] = docId?.split(":") ?? [];
|
|
470
|
+
const space = client.spaces.get().find((space2) => space2.id === spaceId);
|
|
471
|
+
const doc = space?.db.getObjectById(objectId);
|
|
472
|
+
if (!doc || !docId) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const docMeta = metadataResolver((0, import_echo_schema.getTypename)(doc) ?? "");
|
|
476
|
+
const label = docMeta.label?.(doc) || doc.name || docMeta.placeholder || [
|
|
477
|
+
"unnamed object threads label",
|
|
478
|
+
{
|
|
479
|
+
ns: import_chunk_BWBONZGU.THREAD_PLUGIN
|
|
480
|
+
}
|
|
481
|
+
];
|
|
482
|
+
const viewState = getViewState(docId);
|
|
483
|
+
return {
|
|
484
|
+
id,
|
|
485
|
+
type: "orphan-comments-for-subject",
|
|
486
|
+
data: doc,
|
|
487
|
+
properties: {
|
|
488
|
+
icon: import_chunk_BWBONZGU.meta_default.iconComponent,
|
|
489
|
+
label,
|
|
490
|
+
showResolvedThreads: viewState.showResolvedThreads
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
},
|
|
494
|
+
actions: ({ node }) => {
|
|
495
|
+
const dataId = node.id.split("~").at(0);
|
|
496
|
+
if (!node.id.endsWith("~comments") || !dataId) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
const [spaceId, objectId] = dataId.split(":");
|
|
500
|
+
const viewState = getViewState(dataId);
|
|
501
|
+
const toggle = () => {
|
|
502
|
+
const newToggleState = !viewState.showResolvedThreads;
|
|
503
|
+
viewState.showResolvedThreads = newToggleState;
|
|
504
|
+
void dispatch2({
|
|
505
|
+
action: import_meta.ObservabilityAction.SEND_EVENT,
|
|
506
|
+
data: {
|
|
507
|
+
name: "threads.toggle-show-resolved",
|
|
508
|
+
properties: {
|
|
509
|
+
spaceId,
|
|
510
|
+
threadId: objectId,
|
|
511
|
+
showResolved: newToggleState
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
};
|
|
516
|
+
return [
|
|
517
|
+
{
|
|
518
|
+
id: `${import_chunk_BWBONZGU.THREAD_PLUGIN}/toggle-show-resolved/${node.id}`,
|
|
519
|
+
data: toggle,
|
|
520
|
+
properties: {
|
|
521
|
+
label: [
|
|
522
|
+
"toggle show resolved",
|
|
523
|
+
{
|
|
524
|
+
ns: import_chunk_BWBONZGU.THREAD_PLUGIN
|
|
525
|
+
}
|
|
526
|
+
],
|
|
527
|
+
menuItemType: "toggle",
|
|
528
|
+
isChecked: viewState.showResolvedThreads,
|
|
529
|
+
testId: "threadPlugin.toggleShowResolved"
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
];
|
|
533
|
+
}
|
|
534
|
+
}),
|
|
535
|
+
(0, import_plugin_graph.createExtension)({
|
|
536
|
+
id: import_chunk_WPPLQNMJ.ThreadAction.CREATE,
|
|
537
|
+
filter: (node) => !!settings.values.standalone && (0, import_plugin_graph.isActionGroup)(node) && node.id.startsWith(import_plugin_space.SpaceAction.ADD_OBJECT),
|
|
538
|
+
actions: ({ node }) => {
|
|
539
|
+
const id = node.id.split("/").at(-1);
|
|
540
|
+
const [spaceId, objectId] = id?.split(":") ?? [];
|
|
541
|
+
const space = client.spaces.get().find((space2) => space2.id === spaceId);
|
|
542
|
+
const object = objectId && space?.db.getObjectById(objectId);
|
|
543
|
+
const target = objectId ? object : space;
|
|
544
|
+
if (!target) {
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
return [
|
|
548
|
+
{
|
|
549
|
+
id: `${import_chunk_BWBONZGU.THREAD_PLUGIN}/create/${node.id}`,
|
|
550
|
+
data: async () => {
|
|
551
|
+
await dispatch2([
|
|
552
|
+
{
|
|
553
|
+
plugin: import_chunk_BWBONZGU.THREAD_PLUGIN,
|
|
554
|
+
action: import_chunk_WPPLQNMJ.ThreadAction.CREATE
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
action: import_plugin_space.SpaceAction.ADD_OBJECT,
|
|
558
|
+
data: {
|
|
559
|
+
target
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
action: import_app_framework.NavigationAction.OPEN
|
|
564
|
+
}
|
|
565
|
+
]);
|
|
566
|
+
},
|
|
567
|
+
properties: {
|
|
568
|
+
label: [
|
|
569
|
+
"create channel label",
|
|
570
|
+
{
|
|
571
|
+
ns: import_chunk_BWBONZGU.THREAD_PLUGIN
|
|
572
|
+
}
|
|
573
|
+
],
|
|
574
|
+
icon: (props) => /* @__PURE__ */ import_react2.default.createElement(import_react.Chat, props),
|
|
575
|
+
iconSymbol: "ph--chat--regular",
|
|
576
|
+
testId: "threadPlugin.createObject"
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
];
|
|
580
|
+
}
|
|
581
|
+
})
|
|
582
|
+
];
|
|
583
|
+
}
|
|
584
|
+
},
|
|
585
|
+
surface: {
|
|
586
|
+
component: ({ data, role }) => {
|
|
587
|
+
switch (role) {
|
|
588
|
+
case "main": {
|
|
589
|
+
return data.active instanceof import_types2.ChannelType && data.active.threads[0] ? /* @__PURE__ */ import_react2.default.createElement(ThreadMain, {
|
|
590
|
+
thread: data.active.threads[0]
|
|
591
|
+
}) : null;
|
|
592
|
+
}
|
|
593
|
+
case "settings": {
|
|
594
|
+
return data.plugin === import_chunk_BWBONZGU.meta_default.id ? /* @__PURE__ */ import_react2.default.createElement(ThreadSettings, {
|
|
595
|
+
settings: settings.values
|
|
596
|
+
}) : null;
|
|
597
|
+
}
|
|
598
|
+
case "article":
|
|
599
|
+
case "complementary": {
|
|
600
|
+
const location = navigationPlugin?.provides.location;
|
|
601
|
+
if (data.object instanceof import_types2.ChannelType && data.object.threads[0]) {
|
|
602
|
+
const channel = data.object;
|
|
603
|
+
if ((0, import_app_framework.isLayoutParts)(location?.active) && location.active.main) {
|
|
604
|
+
const layoutEntries = location.active.main;
|
|
605
|
+
const currentPosition = layoutEntries.findIndex((entry) => channel.id === entry.id);
|
|
606
|
+
if (currentPosition > 0) {
|
|
607
|
+
const objectToTheLeft = layoutEntries[currentPosition - 1];
|
|
608
|
+
const context = (0, import_echo.getSpace)(data.object)?.db.getObjectById(objectToTheLeft.id);
|
|
609
|
+
return /* @__PURE__ */ import_react2.default.createElement(ThreadArticle, {
|
|
610
|
+
thread: data.object.threads[0],
|
|
611
|
+
context
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
return /* @__PURE__ */ import_react2.default.createElement(ThreadArticle, {
|
|
616
|
+
thread: data.object.threads[0]
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
if (data.subject instanceof import_types.DocumentType) {
|
|
620
|
+
const doc = data.subject;
|
|
621
|
+
const accessor = doc.content ? (0, import_echo.createDocAccessor)(doc.content, [
|
|
622
|
+
"content"
|
|
623
|
+
]) : void 0;
|
|
624
|
+
if (!accessor) {
|
|
625
|
+
return null;
|
|
626
|
+
}
|
|
627
|
+
const getStartPosition = (cursor) => {
|
|
628
|
+
const range = cursor ? (0, import_echo.getRangeFromCursor)(accessor, cursor) : void 0;
|
|
629
|
+
return range?.start ?? Number.MAX_SAFE_INTEGER;
|
|
630
|
+
};
|
|
631
|
+
const threads = doc.threads.concat(state.staging[data.subject.id]).filter(import_util.nonNullable).sort((a, b) => getStartPosition(a.anchor) - getStartPosition(b.anchor));
|
|
632
|
+
const detached = data.subject.threads.filter(import_util.nonNullable).filter(({ anchor }) => !anchor).map((thread) => thread.id);
|
|
633
|
+
const qualifiedSubjectId = (0, import_echo.fullyQualifiedId)(doc);
|
|
634
|
+
const attention = attentionPlugin?.provides.attention?.attended ?? /* @__PURE__ */ new Set([
|
|
635
|
+
qualifiedSubjectId
|
|
636
|
+
]);
|
|
637
|
+
const attendableAttrs = (0, import_react_ui_attention.createAttendableAttributes)(qualifiedSubjectId);
|
|
638
|
+
const space = (0, import_echo.getSpace)(doc);
|
|
639
|
+
const { showResolvedThreads } = getViewState(qualifiedSubjectId);
|
|
640
|
+
const dispatchAnalytic = (name, meta) => {
|
|
641
|
+
void dispatch?.({
|
|
642
|
+
action: import_meta.ObservabilityAction.SEND_EVENT,
|
|
643
|
+
data: {
|
|
644
|
+
name,
|
|
645
|
+
properties: {
|
|
646
|
+
...meta,
|
|
647
|
+
space: space?.id
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
};
|
|
652
|
+
return /* @__PURE__ */ import_react2.default.createElement("div", {
|
|
653
|
+
role: "none",
|
|
654
|
+
className: "contents group/attention",
|
|
655
|
+
...attendableAttrs
|
|
656
|
+
}, role === "complementary" && /* @__PURE__ */ import_react2.default.createElement(CommentsHeading, {
|
|
657
|
+
attendableId: qualifiedSubjectId
|
|
658
|
+
}), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.ScrollArea.Root, {
|
|
659
|
+
classNames: "row-span-2"
|
|
660
|
+
}, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.ScrollArea.Viewport, null, /* @__PURE__ */ import_react2.default.createElement(CommentsContainer, {
|
|
661
|
+
threads,
|
|
662
|
+
detached,
|
|
663
|
+
currentId: attention.has(qualifiedSubjectId) ? state.current : void 0,
|
|
664
|
+
autoFocusCurrentTextbox: state.focus,
|
|
665
|
+
showResolvedThreads,
|
|
666
|
+
onThreadAttend: (thread) => {
|
|
667
|
+
if (state.current !== thread.id) {
|
|
668
|
+
state.current = thread.id;
|
|
669
|
+
void dispatch?.({
|
|
670
|
+
action: import_app_framework.LayoutAction.SCROLL_INTO_VIEW,
|
|
671
|
+
data: {
|
|
672
|
+
id: thread.id
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
},
|
|
677
|
+
onThreadDelete: (thread) => dispatch?.({
|
|
678
|
+
plugin: import_chunk_BWBONZGU.THREAD_PLUGIN,
|
|
679
|
+
action: import_chunk_WPPLQNMJ.ThreadAction.DELETE,
|
|
680
|
+
data: {
|
|
681
|
+
document: data.subject,
|
|
682
|
+
thread
|
|
683
|
+
}
|
|
684
|
+
}),
|
|
685
|
+
onMessageDelete: (thread, messageId) => dispatch?.({
|
|
686
|
+
plugin: import_chunk_BWBONZGU.THREAD_PLUGIN,
|
|
687
|
+
action: import_chunk_WPPLQNMJ.ThreadAction.DELETE_MESSAGE,
|
|
688
|
+
data: {
|
|
689
|
+
document: data.subject,
|
|
690
|
+
thread,
|
|
691
|
+
messageId
|
|
692
|
+
}
|
|
693
|
+
}),
|
|
694
|
+
onThreadToggleResolved: (thread) => dispatch?.({
|
|
695
|
+
plugin: import_chunk_BWBONZGU.THREAD_PLUGIN,
|
|
696
|
+
action: import_chunk_WPPLQNMJ.ThreadAction.TOGGLE_RESOLVED,
|
|
697
|
+
data: {
|
|
698
|
+
thread
|
|
699
|
+
}
|
|
700
|
+
}),
|
|
701
|
+
onComment: (thread) => {
|
|
702
|
+
const doc2 = data.subject;
|
|
703
|
+
if (state.staging[doc2.id]?.find((t) => t === thread)) {
|
|
704
|
+
thread.status = "active";
|
|
705
|
+
doc2.threads ? doc2.threads.push(thread) : doc2.threads = [
|
|
706
|
+
thread
|
|
707
|
+
];
|
|
708
|
+
state.staging[doc2.id] = state.staging[doc2.id]?.filter((t) => t.id !== thread.id);
|
|
709
|
+
dispatchAnalytic("threads.thread-created", {
|
|
710
|
+
threadId: thread.id
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
dispatchAnalytic("threads.message-added", {
|
|
714
|
+
threadId: thread.id,
|
|
715
|
+
threadLength: thread.messages.length
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
}), /* @__PURE__ */ import_react2.default.createElement("div", {
|
|
719
|
+
role: "none",
|
|
720
|
+
className: "bs-10"
|
|
721
|
+
}), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.ScrollArea.Scrollbar, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.ScrollArea.Thumb, null)))));
|
|
722
|
+
} else if (data.subject instanceof import_types2.ThreadType) {
|
|
723
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_chunk_3VAAUEU5.ChatHeading, {
|
|
724
|
+
attendableId: data.subject.id
|
|
725
|
+
}), /* @__PURE__ */ import_react2.default.createElement(import_chunk_3VAAUEU5.ChatContainer, {
|
|
726
|
+
thread: data.subject
|
|
727
|
+
}));
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return null;
|
|
732
|
+
}
|
|
733
|
+
},
|
|
734
|
+
intent: {
|
|
735
|
+
resolver: async (intent) => {
|
|
736
|
+
switch (intent.action) {
|
|
737
|
+
case import_chunk_WPPLQNMJ.ThreadAction.CREATE: {
|
|
738
|
+
return {
|
|
739
|
+
data: (0, import_echo_schema2.create)(import_types2.ChannelType, {
|
|
740
|
+
threads: [
|
|
741
|
+
(0, import_echo_schema2.create)(import_types2.ThreadType, {
|
|
742
|
+
messages: []
|
|
743
|
+
})
|
|
744
|
+
]
|
|
745
|
+
})
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
case import_chunk_WPPLQNMJ.ThreadAction.SELECT: {
|
|
749
|
+
state.focus = intent.data?.current === state.current ? state.focus : intent.data?.focus;
|
|
750
|
+
state.current = intent.data?.current;
|
|
751
|
+
return {
|
|
752
|
+
data: true
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
case import_chunk_WPPLQNMJ.ThreadAction.TOGGLE_RESOLVED: {
|
|
756
|
+
const { thread } = intent.data ?? {};
|
|
757
|
+
if (!(thread instanceof import_types2.ThreadType)) {
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
if (thread.status === "active" || thread.status === void 0) {
|
|
761
|
+
thread.status = "resolved";
|
|
762
|
+
} else if (thread.status === "resolved") {
|
|
763
|
+
thread.status = "active";
|
|
764
|
+
}
|
|
765
|
+
const space = (0, import_echo.getSpace)(thread);
|
|
766
|
+
const spaceId = space?.id;
|
|
767
|
+
return {
|
|
768
|
+
intents: [
|
|
769
|
+
[
|
|
770
|
+
{
|
|
771
|
+
action: import_meta.ObservabilityAction.SEND_EVENT,
|
|
772
|
+
data: {
|
|
773
|
+
name: "threads.toggle-resolved",
|
|
774
|
+
properties: {
|
|
775
|
+
threadId: thread.id,
|
|
776
|
+
spaceId
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
]
|
|
781
|
+
]
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
case import_chunk_WPPLQNMJ.ThreadAction.DELETE: {
|
|
785
|
+
const { document: doc, thread } = intent.data ?? {};
|
|
786
|
+
if (!(doc instanceof import_types.DocumentType) || !(thread instanceof import_types2.ThreadType)) {
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
const stagingArea = state.staging[doc.id];
|
|
790
|
+
if (stagingArea) {
|
|
791
|
+
const index = state.staging[doc.id]?.findIndex((t) => t.id === thread.id);
|
|
792
|
+
if (index !== -1) {
|
|
793
|
+
state.staging[doc.id]?.splice(index, 1);
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
const space = (0, import_echo.getSpace)(thread);
|
|
798
|
+
if (!space || !doc.threads) {
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
if (!intent.undo) {
|
|
802
|
+
const index = doc.threads.findIndex((t) => t?.id === thread.id);
|
|
803
|
+
const cursor = doc.threads[index]?.anchor;
|
|
804
|
+
if (index !== -1) {
|
|
805
|
+
doc.threads?.splice(index, 1);
|
|
806
|
+
}
|
|
807
|
+
space.db.remove(thread);
|
|
808
|
+
return {
|
|
809
|
+
undoable: {
|
|
810
|
+
message: translations_default[0]["en-US"][import_chunk_BWBONZGU.THREAD_PLUGIN]["thread deleted label"],
|
|
811
|
+
data: {
|
|
812
|
+
cursor
|
|
813
|
+
}
|
|
814
|
+
},
|
|
815
|
+
intents: [
|
|
816
|
+
[
|
|
817
|
+
{
|
|
818
|
+
action: import_meta.ObservabilityAction.SEND_EVENT,
|
|
819
|
+
data: {
|
|
820
|
+
name: "threads.delete",
|
|
821
|
+
properties: {
|
|
822
|
+
threadId: thread.id,
|
|
823
|
+
spaceId: space.id
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
]
|
|
828
|
+
]
|
|
829
|
+
};
|
|
830
|
+
} else if (intent.undo) {
|
|
831
|
+
const savedThread = space.db.add(thread);
|
|
832
|
+
doc.threads.push(savedThread);
|
|
833
|
+
return {
|
|
834
|
+
data: true,
|
|
835
|
+
intents: [
|
|
836
|
+
[
|
|
837
|
+
{
|
|
838
|
+
action: import_meta.ObservabilityAction.SEND_EVENT,
|
|
839
|
+
data: {
|
|
840
|
+
name: "threads.undo-delete",
|
|
841
|
+
properties: {
|
|
842
|
+
threadId: thread.id,
|
|
843
|
+
spaceId: space.id
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
]
|
|
848
|
+
]
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
break;
|
|
852
|
+
}
|
|
853
|
+
case import_chunk_WPPLQNMJ.ThreadAction.DELETE_MESSAGE: {
|
|
854
|
+
const { document: doc, thread, messageId } = intent.data ?? {};
|
|
855
|
+
const space = (0, import_echo.getSpace)(doc);
|
|
856
|
+
if (!(doc instanceof import_types.DocumentType) || !(thread instanceof import_types2.ThreadType) || !space) {
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
if (!intent.undo) {
|
|
860
|
+
const message = thread.messages.find((m) => m?.id === messageId);
|
|
861
|
+
const messageIndex = thread.messages.findIndex((m) => m?.id === messageId);
|
|
862
|
+
if (messageIndex === -1 || !message) {
|
|
863
|
+
return void 0;
|
|
864
|
+
}
|
|
865
|
+
if (messageIndex === 0 && thread.messages.length === 1) {
|
|
866
|
+
return {
|
|
867
|
+
intents: [
|
|
868
|
+
[
|
|
869
|
+
{
|
|
870
|
+
action: import_chunk_WPPLQNMJ.ThreadAction.DELETE,
|
|
871
|
+
data: {
|
|
872
|
+
document: doc,
|
|
873
|
+
thread
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
]
|
|
877
|
+
]
|
|
878
|
+
};
|
|
879
|
+
} else {
|
|
880
|
+
thread.messages.splice(messageIndex, 1);
|
|
881
|
+
}
|
|
882
|
+
return {
|
|
883
|
+
undoable: {
|
|
884
|
+
message: translations_default[0]["en-US"][import_chunk_BWBONZGU.THREAD_PLUGIN]["message deleted label"],
|
|
885
|
+
data: {
|
|
886
|
+
message,
|
|
887
|
+
messageIndex
|
|
888
|
+
}
|
|
889
|
+
},
|
|
890
|
+
intents: [
|
|
891
|
+
[
|
|
892
|
+
{
|
|
893
|
+
action: import_meta.ObservabilityAction.SEND_EVENT,
|
|
894
|
+
data: {
|
|
895
|
+
name: "threads.message.delete",
|
|
896
|
+
properties: {
|
|
897
|
+
threadId: thread.id,
|
|
898
|
+
spaceId: space.id
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
]
|
|
903
|
+
]
|
|
904
|
+
};
|
|
905
|
+
} else if (intent.undo) {
|
|
906
|
+
const message = intent.data?.message;
|
|
907
|
+
const messageIndex = intent.data?.messageIndex;
|
|
908
|
+
if (!(message instanceof import_types2.MessageType) || !(typeof messageIndex === "number")) {
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
thread.messages.splice(messageIndex, 0, message);
|
|
912
|
+
return {
|
|
913
|
+
data: true,
|
|
914
|
+
intents: [
|
|
915
|
+
[
|
|
916
|
+
{
|
|
917
|
+
action: import_meta.ObservabilityAction.SEND_EVENT,
|
|
918
|
+
data: {
|
|
919
|
+
name: "threads.message.undo-delete",
|
|
920
|
+
properties: {
|
|
921
|
+
threadId: thread.id,
|
|
922
|
+
spaceId: space.id
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
]
|
|
927
|
+
]
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
},
|
|
934
|
+
markdown: {
|
|
935
|
+
// TODO(burdon): Factor out extension factory into separate file (for simplicity).
|
|
936
|
+
extensions: ({ document: doc }) => {
|
|
937
|
+
const space = doc && (0, import_echo.getSpace)(doc);
|
|
938
|
+
if (!doc || !space) {
|
|
939
|
+
return [
|
|
940
|
+
(0, import_react_ui_editor.comments)()
|
|
941
|
+
];
|
|
942
|
+
}
|
|
943
|
+
const threads = (0, import_signals_core.computed)(() => [
|
|
944
|
+
...doc.threads.filter(import_util.nonNullable),
|
|
945
|
+
...state.staging[doc.id] ?? []
|
|
946
|
+
].filter((thread) => !(thread?.status === "resolved")));
|
|
947
|
+
return [
|
|
948
|
+
(0, import_react_ui_editor.listener)({
|
|
949
|
+
onChange: () => {
|
|
950
|
+
doc.threads.forEach((thread) => {
|
|
951
|
+
if (thread?.anchor) {
|
|
952
|
+
const [start, end] = thread.anchor.split(":");
|
|
953
|
+
const name = doc.content && (0, import_echo.getTextInRange)((0, import_echo.createDocAccessor)(doc.content, [
|
|
954
|
+
"content"
|
|
955
|
+
]), start, end);
|
|
956
|
+
if (name && name !== thread.name) {
|
|
957
|
+
thread.name = name;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
}),
|
|
963
|
+
(0, import_react_ui_editor.createExternalCommentSync)(doc.id, (sink) => (0, import_signals_core.effect)(() => sink()), () => threads.value.filter((thread) => thread?.anchor).map((thread) => ({
|
|
964
|
+
id: thread.id,
|
|
965
|
+
cursor: thread.anchor
|
|
966
|
+
}))),
|
|
967
|
+
(0, import_react_ui_editor.comments)({
|
|
968
|
+
id: doc.id,
|
|
969
|
+
onCreate: ({ cursor }) => {
|
|
970
|
+
const [start, end] = cursor.split(":");
|
|
971
|
+
const name = doc.content && (0, import_echo.getTextInRange)((0, import_echo.createDocAccessor)(doc.content, [
|
|
972
|
+
"content"
|
|
973
|
+
]), start, end);
|
|
974
|
+
const thread = (0, import_echo_schema2.create)(import_types2.ThreadType, {
|
|
975
|
+
name,
|
|
976
|
+
anchor: cursor,
|
|
977
|
+
messages: [],
|
|
978
|
+
status: "staged"
|
|
979
|
+
});
|
|
980
|
+
const stagingArea = state.staging[doc.id];
|
|
981
|
+
if (stagingArea) {
|
|
982
|
+
stagingArea.push(thread);
|
|
983
|
+
} else {
|
|
984
|
+
state.staging[doc.id] = [
|
|
985
|
+
thread
|
|
986
|
+
];
|
|
987
|
+
}
|
|
988
|
+
void intentPlugin?.provides.intent.dispatch([
|
|
989
|
+
{
|
|
990
|
+
action: import_app_framework.NavigationAction.OPEN,
|
|
991
|
+
data: {
|
|
992
|
+
activeParts: {
|
|
993
|
+
complementary: `${(0, import_echo.fullyQualifiedId)(doc)}${import_app_framework.SLUG_PATH_SEPARATOR}comments${import_app_framework.SLUG_COLLECTION_INDICATOR}`
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
action: import_chunk_WPPLQNMJ.ThreadAction.SELECT,
|
|
999
|
+
data: {
|
|
1000
|
+
current: thread.id,
|
|
1001
|
+
focus: true
|
|
1002
|
+
}
|
|
1003
|
+
},
|
|
1004
|
+
{
|
|
1005
|
+
action: import_app_framework.LayoutAction.SET_LAYOUT,
|
|
1006
|
+
data: {
|
|
1007
|
+
element: "complementary",
|
|
1008
|
+
subject: doc,
|
|
1009
|
+
state: true
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
]);
|
|
1013
|
+
return thread.id;
|
|
1014
|
+
},
|
|
1015
|
+
onDelete: ({ id }) => {
|
|
1016
|
+
const stagingArea = state.staging[doc.id];
|
|
1017
|
+
if (stagingArea) {
|
|
1018
|
+
const index = stagingArea.findIndex((thread2) => thread2.id === id);
|
|
1019
|
+
if (index !== -1) {
|
|
1020
|
+
stagingArea.splice(index, 1);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
const thread = doc.threads.find((thread2) => thread2?.id === id);
|
|
1024
|
+
if (thread) {
|
|
1025
|
+
thread.anchor = void 0;
|
|
1026
|
+
}
|
|
1027
|
+
},
|
|
1028
|
+
onUpdate: ({ id, cursor }) => {
|
|
1029
|
+
const thread = state.staging[doc.id]?.find((thread2) => thread2.id === id) ?? doc.threads.find((thread2) => thread2?.id === id);
|
|
1030
|
+
if (thread instanceof import_types2.ThreadType && thread.anchor) {
|
|
1031
|
+
const [start, end] = thread.anchor.split(":");
|
|
1032
|
+
thread.name = doc.content && (0, import_echo.getTextInRange)((0, import_echo.createDocAccessor)(doc.content, [
|
|
1033
|
+
"content"
|
|
1034
|
+
]), start, end);
|
|
1035
|
+
thread.anchor = cursor;
|
|
1036
|
+
}
|
|
1037
|
+
},
|
|
1038
|
+
onSelect: ({ selection: { current, closest } }) => {
|
|
1039
|
+
const dispatch2 = intentPlugin?.provides.intent.dispatch;
|
|
1040
|
+
if (dispatch2) {
|
|
1041
|
+
void dispatch2([
|
|
1042
|
+
{
|
|
1043
|
+
action: import_chunk_WPPLQNMJ.ThreadAction.SELECT,
|
|
1044
|
+
data: {
|
|
1045
|
+
current: current ?? closest
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
]);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
})
|
|
1052
|
+
];
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
};
|
|
1058
|
+
var src_default = ThreadPlugin;
|
|
1059
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1060
|
+
0 && (module.exports = {
|
|
1061
|
+
ThreadAction,
|
|
1062
|
+
ThreadPlugin,
|
|
1063
|
+
useAnalyticsCallback,
|
|
1064
|
+
useOnEditAnalytics,
|
|
1065
|
+
useStatus
|
|
1066
|
+
});
|
|
1067
|
+
//# sourceMappingURL=index.cjs.map
|