@bud.sh/app 0.4.0 → 0.5.0
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/dist/client/assets/bud/design.js +1 -1
- package/dist/client/assets/{canvas-C8hyPWoT.js → canvas-Cu6R6xxT.js} +1 -1
- package/dist/client/assets/difference-worker-jfTSn-Tw.js +8 -0
- package/dist/client/assets/{edit-B050x0rV.js → edit-DUotSxjS.js} +12 -12
- package/dist/client/assets/files-js6ElfkU.js +1 -0
- package/dist/client/assets/i18n-DxqFr2mi.js +1 -0
- package/dist/client/assets/index-CFFxP0gS.css +2 -0
- package/dist/client/assets/{index-Dpxjiok1.js → index-ChANGtl-.js} +2 -2
- package/dist/client/assets/lru-DzKYIXMA.js +1 -0
- package/dist/client/assets/pages-6_lhiQmz.js +1 -0
- package/dist/client/assets/{project-branches-DzXdaT9L.js → project-branches-DO897zM6.js} +1 -1
- package/dist/client/assets/project-comments-DFFKVpia.js +1 -0
- package/dist/client/assets/project-thread-links-NLFWQRD2.js +1 -0
- package/dist/client/assets/{project-threads-CHGG-6fo.js → project-threads-Lay351p4.js} +105 -105
- package/dist/client/assets/{project-work-L5fYMSOu.js → project-work-du0Y-L5Y.js} +1 -1
- package/dist/client/assets/rolldown-runtime-XKyaHtl9.js +1 -0
- package/dist/client/assets/task-design-Avb2RO4w.js +23 -0
- package/dist/client/assets/tasks-CA-E8bbK.js +1 -0
- package/dist/client/assets/{tasks-request-DGigNdyK.js → tasks-request-C55IeuiP.js} +1 -1
- package/dist/client/assets/workspace-Cw5HvX5d.js +2 -0
- package/dist/client/index.html +3 -3
- package/dist/hosted/assets/{canvas-MWtOwaWm.js → canvas-V36732ER.js} +6 -4
- package/dist/hosted/assets/{comment-data-DsgJWq4n.js → comment-data-CF2ZV_3k.js} +4162 -3659
- package/dist/hosted/assets/{files-Wvo11G2A.js → files-DjSCjfU7.js} +5 -3
- package/dist/hosted/assets/{pages-BAmRFVtU.js → pages-BzjzeuPu.js} +3 -3
- package/dist/hosted/assets/{project-branches-BNloVosX.js → project-branches-BT97J9i7.js} +1 -1
- package/dist/hosted/assets/{project-thread-links-BmY8HQXt.js → project-thread-links-BRLgByEe.js} +2 -2
- package/dist/hosted/assets/{screen-QmqmI2Aq.js → screen-CKp2C7kx.js} +68 -137
- package/dist/hosted/assets/{tasks-C8iWPrWg.js → tasks-Dj7AyBJB.js} +12 -5
- package/dist/hosted/assets/{tasks-request-C89fN1dK.js → tasks-request-DZob623r.js} +1 -1
- package/dist/hosted/hosted.js +174 -18
- package/dist/node/assets/{src-BdvZ2mYc.js → src-CerrKjID.js} +57 -1
- package/dist/node/design.js +969 -809
- package/dist/node/server.js +25 -3
- package/dist/node-host/assets/{canvas-D_F8SIlm.js → canvas-TRUfxfL5.js} +6 -4
- package/dist/node-host/assets/{comment-data-q_8INiZz.js → comment-data-DyIZNpfG.js} +4143 -3640
- package/dist/node-host/assets/{files-xazOrNCX.js → files-Dh2TiQZq.js} +5 -3
- package/dist/node-host/assets/{pages-D6VkmdfQ.js → pages-BxpjbYhs.js} +3 -3
- package/dist/node-host/assets/{project-branches-C26hwmo3.js → project-branches-B7HUGiVK.js} +1 -1
- package/dist/node-host/assets/{project-thread-links-BOzjws5W.js → project-thread-links-CauJF0Cz.js} +2 -2
- package/dist/node-host/assets/{screen-Dog-YByu.js → screen-CZXWJEds.js} +68 -137
- package/dist/node-host/assets/{tasks-A1_bpb3_.js → tasks-Bs1IOpeU.js} +12 -5
- package/dist/node-host/assets/{tasks-request-Bie1PpQP.js → tasks-request-ZWmbc8fE.js} +1 -1
- package/dist/node-host/node-host.js +174 -18
- package/dist/server/assets/{canvas-Dn4RYoU2.js → canvas-Dc1mYCwQ.js} +7 -5
- package/dist/server/assets/{comment-data-B0OLHBGp.js → comment-data-CsjukwAW.js} +3911 -3619
- package/dist/server/assets/{events-6z5v7Uca.js → events-iHpLGr3k.js} +213 -2
- package/dist/server/assets/{files-C5Vilfe4.js → files-E9mSFeoc.js} +6 -4
- package/dist/server/assets/{listener-o1STuLju.js → listener-DN5TyOjJ.js} +45 -11
- package/dist/server/assets/{pages-BNa0MHEc.js → pages-BBBXyJWV.js} +4 -4
- package/dist/server/assets/{project-branches-GtQYyOH5.js → project-branches-B0YIK6Ur.js} +2 -2
- package/dist/server/assets/{project-thread-links-Nfz9NIny.js → project-thread-links-CBOpf6zk.js} +3 -3
- package/dist/server/assets/{project-work-Cy_BpHwR.js → project-work-qSKFO5yj.js} +3 -3
- package/dist/server/assets/{screen-BtcJmZwj.js → screen-BIQA2mr4.js} +69 -138
- package/dist/server/assets/{server-CYvuOSBA.js → server-DxK-UB_Z.js} +30 -4
- package/dist/server/assets/{services-DK4fqrlF.js → services-BRrgXYlT.js} +105 -9
- package/dist/server/assets/{tasks-B82tHwyQ.js → tasks-CiXodsLN.js} +14 -7
- package/dist/server/assets/{tasks-request-BtJBlkxV.js → tasks-request-DhwCzpRi.js} +2 -2
- package/dist/server/migration.js +3 -3
- package/dist/server/runtime.js +3 -3
- package/dist/server/server.js +2 -2
- package/dist/types/server.d.ts +11 -1
- package/package.json +1 -1
- package/dist/client/assets/difference-worker-BfF4_N3e.js +0 -8
- package/dist/client/assets/files-D_Tm7gCK.js +0 -1
- package/dist/client/assets/i18n-BtfXum8P.js +0 -1
- package/dist/client/assets/index-CjhJtepP.css +0 -2
- package/dist/client/assets/lru-BkhKJhvt.js +0 -1
- package/dist/client/assets/pages-B-_CKvDS.js +0 -1
- package/dist/client/assets/project-comments-CQkB2jbE.js +0 -1
- package/dist/client/assets/project-thread-links-BN7zL0AX.js +0 -1
- package/dist/client/assets/task-design-DYqcqq1b.js +0 -23
- package/dist/client/assets/tasks-A2FKo3_h.js +0 -1
- package/dist/client/assets/workspace-CvWmU2RK.js +0 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { i as __toESM } from "./rolldown-runtime-DktXgydw.js";
|
|
2
|
-
import { $ as FileSearchPanel, $n as
|
|
2
|
+
import { $ as FileSearchPanel, $n as markWorkerErrorReported, A as parseEditorPreferences, Ar as parseFileSearchResult, At as defaultReviewView, Bt as fileHref, Cr as parseRecoveries, D as ReviewActionDialog, Dr as parseReviewSnapshot, E as FileConflictPanel, Er as parseReviewRepository, F as FileWorkspace, Ft as reviewComparison, Gn as renderDiffWithHighlighter, Gt as fileRoutes, Hn as parseFileUpdate, Ht as readFileLocation, I as defaultFileDestination, It as reviewContextKey, Jn as areDiffTargetsEqual, Kn as areDiffRenderOptionsEqual, L as fileActionIntent, Lt as reviewHref, M as FileMutationDialog, Mr as parseFileDocument, Mt as parseReviewSession, N as FileReviewPanel, Nr as parseFileIndex, Nt as readReviewLocation, O as FileEditorPanel, Or as parseReviewSource, P as codeThemes, Pr as parseFilePath, Pt as rememberReviewPosition, Qn as isHandledWorkerPoolError, R as mutationFileView, Rt as closeFileTab, Sr as parseMutationResult, St as isCodeConversation, Tr as parseReviewHistory, Tt as readConversationLocation, Un as reviewConflictIdentity, Ut as reconcileFileView, Vn as createCodeAnchor, Vt as parseFileView, Wn as isDiffPlainText, Wt as rememberFile, Xn as WorkerPoolTerminatedError, Yn as WorkerPoolTaskCanceledError, Zn as WorkerPoolWorkerError, _r as parseReviewActionResult, ar as getSharedHighlighter, br as maxFileSaveBytes, bt as conversationHref, cn as toast, cr as attachResolvedThemes, dr as getResolvedOrResolveLanguage, er as isFilePlainText, f as storeDocument, fr as resolveLanguage, gn as Text, gr as parseReviewActionRecoveries, hr as parseReviewActionPlan, ir as areThemesEqual, j as FileRecoveryDialog, jr as parseFileChange, k as defaultEditorPreferences, kr as parseFileSearchQuery, kt as defaultReviewPosition, l as projectStore, ln as readPreference, lr as themeResolver, m as storedFiles, mn as t, mr as ResolvedLanguages, nr as areFileRenderOptionsEqual, or as prepareThemeResolution, p as storedDocument, pr as areLanguagesAttached, qn as areFilesEqual, rr as hasResolvedThemes, s as applyFileUpdate, sr as validateResolvedThemeName, tr as renderFileWithHighlighter, tt as ConversationSidebar, u as saveFiles, un as writePreference, ur as getThemes, v as projectLive, vr as parseFileSaveRequest, vt as codeCommentCounts, wr as parseReviewDiff, wt as locateCodeConversations, xr as parseMutationPlan, y as routes, yr as parseFileSaveResult, z as remainingMutationIntent, zt as defaultFileView } from "./comment-data-DyIZNpfG.js";
|
|
3
3
|
import { B as DEFAULT_THEMES, C as getFiletypeFromFileName, S as getCustomExtensionsVersion, x as getCustomExtensionsMap } from "./cloneFileDiffMetadata-C1BcNpxN.js";
|
|
4
|
-
import { n as createProjectComments, t as defineScreen } from "./screen-Dog-YByu.js";
|
|
5
4
|
import { t as require_lru } from "./lru-C0_oUet4.js";
|
|
6
|
-
import { t as
|
|
5
|
+
import { n as createProjectComments, t as defineScreen } from "./screen-CZXWJEds.js";
|
|
6
|
+
import { t as ProjectThreadLinks } from "./project-thread-links-CauJF0Cz.js";
|
|
7
7
|
import { ref } from "remix/component";
|
|
8
8
|
import { jsx, jsxs } from "remix/component/jsx-runtime";
|
|
9
9
|
//#region ../../node_modules/.pnpm/@pierre+diffs@1.5.2_@shikijs+themes@4.5.0_react-dom@19.3.1_react@19.3.1__react@19.3.1/node_modules/@pierre/diffs/dist/highlighter/languages/getResolvedLanguages.js
|
|
@@ -3271,6 +3271,8 @@ function ProjectFileReview(handle) {
|
|
|
3271
3271
|
},
|
|
3272
3272
|
onClose: closeComments,
|
|
3273
3273
|
onWrite: comments.write,
|
|
3274
|
+
viewerId: comments.viewer?.id,
|
|
3275
|
+
onDelete: (thread, messageId) => comments.remove(thread.id, messageId),
|
|
3274
3276
|
onCreate: createComment,
|
|
3275
3277
|
onCancelDraft: () => {
|
|
3276
3278
|
draftAnchor = void 0;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as createProjectComments, t as defineScreen } from "./screen-Dog-YByu.js";
|
|
1
|
+
import { Fr as MAX_CANVAS_Y, Kt as pageRoutes, Qt as Spinner, Zt as Loader, _t as PagesWorkspace, gn as Text, in as IconButton, l as projectStore, ln as readPreference, mn as t, rn as Select, un as writePreference } from "./comment-data-DyIZNpfG.js";
|
|
3
2
|
import { n as workspaceTab, t as followWorkspaceTab } from "../node-host.js";
|
|
4
|
-
import { n as createProjectPreviews, r as locatePreview, t as createProjectBranches } from "./project-branches-
|
|
3
|
+
import { n as createProjectPreviews, r as locatePreview, t as createProjectBranches } from "./project-branches-B7HUGiVK.js";
|
|
4
|
+
import { n as createProjectComments, t as defineScreen } from "./screen-CZXWJEds.js";
|
|
5
5
|
import { array, number, object, optional, parseSafe, string } from "remix/data-schema";
|
|
6
6
|
import { on, ref } from "remix/component";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "remix/component/jsx-runtime";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ir as parseElementAnchor, S as writeRows, Si as parsePreviewPins, _i as parsePreview, b as plainRow, c as previewKey, l as projectStore, mn as t, v as projectLive, vi as parsePreviewBranch, y as routes } from "./comment-data-DyIZNpfG.js";
|
|
2
2
|
import { array, boolean, enum_, nullable, number, object, parseSafe, string } from "remix/data-schema";
|
|
3
3
|
//#region app/client/project-previews.ts
|
|
4
4
|
/**
|
package/dist/node-host/assets/{project-thread-links-BOzjws5W.js → project-thread-links-CauJF0Cz.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as requestTasks } from "./tasks-request-
|
|
1
|
+
import { $r as valueByRole, An as parseThread, C as ThreadTaskLinks, Dt as taskHref, Gr as parseWorkItemRef, In as parseThreadLinkInput, Lr as parseWorkWorkspace, _ as requestComments, in as IconButton, mn as t, w as ThreadTaskPicker, y as routes } from "./comment-data-DyIZNpfG.js";
|
|
2
|
+
import { n as requestTasks } from "./tasks-request-ZWmbc8fE.js";
|
|
3
3
|
import { on, ref } from "remix/component";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "remix/component/jsx-runtime";
|
|
5
5
|
//#region app/client/project-task-picker.tsx
|
|
@@ -1,143 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* @param now - The creation time.
|
|
11
|
-
* @returns The provisional task.
|
|
12
|
-
*/
|
|
13
|
-
function predictWorkCreate(schema, id, create, now = /* @__PURE__ */ new Date()) {
|
|
14
|
-
let values = { ...create.values };
|
|
15
|
-
for (let field of schema.fields) if ((field.role === "created" || field.role === "updated") && values[field.id] === void 0) values[field.id] = field.kind === "date" ? now.toISOString().slice(0, 10) : now.toISOString();
|
|
16
|
-
return {
|
|
17
|
-
id,
|
|
18
|
-
revision: null,
|
|
19
|
-
values,
|
|
20
|
-
relations: [],
|
|
21
|
-
counts: {},
|
|
22
|
-
contentLoaded: false,
|
|
23
|
-
extra: null
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* How a task shows until its adapter confirms an edit: the edited values over its own.
|
|
28
|
-
* @param item - The task as last confirmed.
|
|
29
|
-
* @param update - The update request.
|
|
30
|
-
* @returns The predicted task.
|
|
31
|
-
*/
|
|
32
|
-
function predictWorkUpdate(item, update) {
|
|
33
|
-
return {
|
|
34
|
-
...item,
|
|
35
|
-
values: {
|
|
36
|
-
...item.values,
|
|
37
|
-
...update.values
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
var targets = {
|
|
42
|
-
close: ["done", "cancelled"],
|
|
43
|
-
reopen: [
|
|
44
|
-
"unstarted",
|
|
45
|
-
"backlog",
|
|
46
|
-
"started"
|
|
47
|
-
]
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* How a task shows until its adapter confirms an action. Closing and reopening move it to
|
|
51
|
-
* the schema's first matching status; otherwise only input naming the task's own fields
|
|
52
|
-
* applies, since an action's effects belong to the adapter.
|
|
53
|
-
* @param schema - The board's schema.
|
|
54
|
-
* @param item - The task as last confirmed.
|
|
55
|
-
* @param action - The action request.
|
|
56
|
-
* @returns The predicted task.
|
|
57
|
-
*/
|
|
58
|
-
function predictWorkAction(schema, item, action) {
|
|
59
|
-
let fields = new Set(schema.fields.map((field) => field.id));
|
|
60
|
-
let values = { ...item.values };
|
|
61
|
-
for (let [id, value] of Object.entries(action.input)) if (fields.has(id)) values[id] = value;
|
|
62
|
-
let kind = schema.actions.find((candidate) => candidate.id === action.action)?.kind;
|
|
63
|
-
let categories = kind ? targets[kind] : void 0;
|
|
64
|
-
let field = schema.fields.find((candidate) => candidate.role === "status");
|
|
65
|
-
let status = categories?.map((category) => schema.statuses.find((candidate) => candidate.category === category)).find(Boolean);
|
|
66
|
-
if (field && status) values[field.id] = status.value;
|
|
67
|
-
return {
|
|
68
|
-
...item,
|
|
69
|
-
values
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
/** Who a message shows as until the server, which derives authors from Git, confirms it. */
|
|
73
|
-
var pendingAuthor = {
|
|
74
|
-
id: "pending",
|
|
75
|
-
name: "You",
|
|
76
|
-
email: ""
|
|
77
|
-
};
|
|
78
|
-
function message(id, body, parentId, now) {
|
|
79
|
-
return {
|
|
80
|
-
id,
|
|
81
|
-
body: body.trim(),
|
|
82
|
-
author: pendingAuthor,
|
|
83
|
-
createdAt: now.toISOString(),
|
|
84
|
-
parentId
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* How a new discussion shows until its adapter confirms it.
|
|
89
|
-
* @param id - A provisional identity, also used for its first message.
|
|
90
|
-
* @param input - The create request.
|
|
91
|
-
* @param now - The creation time.
|
|
92
|
-
* @returns The provisional discussion.
|
|
93
|
-
*/
|
|
94
|
-
function predictThreadCreate(id, input, now = /* @__PURE__ */ new Date()) {
|
|
95
|
-
let createdAt = now.toISOString();
|
|
96
|
-
return {
|
|
97
|
-
id,
|
|
98
|
-
status: "open",
|
|
99
|
-
anchor: input.anchor,
|
|
100
|
-
itemIds: [...input.itemIds],
|
|
101
|
-
messages: [message(id, input.body, null, now)],
|
|
102
|
-
messageCount: 1,
|
|
103
|
-
messagesLoaded: true,
|
|
104
|
-
messagesTruncated: false,
|
|
105
|
-
createdAt,
|
|
106
|
-
updatedAt: createdAt,
|
|
107
|
-
revision: null
|
|
1
|
+
import { An as parseThread, Cn as predictThreadStatus, Nn as parseThreadFilter, Pn as parseThreadId, Rn as parseThreadSnapshot, S as writeRows, Sn as predictThreadReply, _ as requestComments, a as saveThreads, b as plainRow, bn as predictThreadCreate, cn as toast, g as CommentsRequestError, i as saveThread, l as projectStore, mn as t, n as unavailableComments, o as threadMatches, x as writeOptimistically, xn as predictThreadDelete, y as routes } from "./comment-data-DyIZNpfG.js";
|
|
2
|
+
//#region app/client/project-comments.ts
|
|
3
|
+
var viewers = /* @__PURE__ */ new Map();
|
|
4
|
+
function parseViewer(value) {
|
|
5
|
+
let viewer = value && typeof value === "object" && "viewer" in value ? value.viewer : void 0;
|
|
6
|
+
if (viewer === null) return null;
|
|
7
|
+
if (viewer && typeof viewer === "object" && "id" in viewer && "name" in viewer && typeof viewer.id === "string" && typeof viewer.name === "string" && viewer.id.length <= 256 && viewer.name.length <= 1e3) return {
|
|
8
|
+
id: viewer.id,
|
|
9
|
+
name: viewer.name
|
|
108
10
|
};
|
|
11
|
+
throw new TypeError("Invalid viewer.");
|
|
109
12
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
* @param id - A provisional message identity.
|
|
114
|
-
* @param input - The reply request.
|
|
115
|
-
* @param now - The reply time.
|
|
116
|
-
* @returns The predicted discussion.
|
|
117
|
-
*/
|
|
118
|
-
function predictThreadReply(thread, id, input, now = /* @__PURE__ */ new Date()) {
|
|
119
|
-
return {
|
|
120
|
-
...thread,
|
|
121
|
-
messages: thread.messagesLoaded ? [...thread.messages, message(id, input.body, input.parentId, now)] : thread.messages,
|
|
122
|
-
messageCount: thread.messageCount + 1,
|
|
123
|
-
updatedAt: now.toISOString()
|
|
124
|
-
};
|
|
13
|
+
function parseDeletion(value) {
|
|
14
|
+
if (!value || typeof value !== "object" || !("thread" in value)) throw new TypeError("Invalid deletion.");
|
|
15
|
+
return { thread: value.thread === null ? null : parseThread(value.thread) };
|
|
125
16
|
}
|
|
126
17
|
/**
|
|
127
|
-
* How a discussion shows until its adapter confirms a status change.
|
|
128
|
-
* @param thread - The discussion as last confirmed.
|
|
129
|
-
* @param input - The status request.
|
|
130
|
-
* @returns The predicted discussion.
|
|
131
|
-
*/
|
|
132
|
-
function predictThreadStatus(thread, input) {
|
|
133
|
-
return {
|
|
134
|
-
...thread,
|
|
135
|
-
status: input.status
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
//#endregion
|
|
139
|
-
//#region app/client/project-comments.ts
|
|
140
|
-
/**
|
|
141
18
|
* Reads one task's discussions with their messages in a single round, so the task page
|
|
142
19
|
* renders complete instead of loading its discussion after it appears.
|
|
143
20
|
* @param token - The current companion capability.
|
|
@@ -245,6 +122,21 @@ function createProjectComments(options) {
|
|
|
245
122
|
let generation = 0, reading;
|
|
246
123
|
let details = /* @__PURE__ */ new Map();
|
|
247
124
|
let detailFailures = /* @__PURE__ */ new Set();
|
|
125
|
+
let viewer = null, askedViewer = false;
|
|
126
|
+
function askViewer() {
|
|
127
|
+
if (askedViewer || !snapshot.capabilities.delete) return;
|
|
128
|
+
askedViewer = true;
|
|
129
|
+
let pending = viewers.get(options.token);
|
|
130
|
+
if (!pending) {
|
|
131
|
+
pending = requestComments(routes.comments.viewer.href(), options.token, new AbortController().signal, parseViewer, options.fetcher).catch(() => null);
|
|
132
|
+
viewers.set(options.token, pending);
|
|
133
|
+
}
|
|
134
|
+
pending.then((value) => {
|
|
135
|
+
viewer = value;
|
|
136
|
+
changed();
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
askViewer();
|
|
248
140
|
let opened = Promise.resolve(options.store).then(async (ready) => {
|
|
249
141
|
store = ready;
|
|
250
142
|
if (options.initial?.snapshot && !options.initial.stored) await saveThreads(ready, options.initial.snapshot, filter);
|
|
@@ -264,6 +156,7 @@ function createProjectComments(options) {
|
|
|
264
156
|
loaded = true;
|
|
265
157
|
now = Date.now();
|
|
266
158
|
version++;
|
|
159
|
+
askViewer();
|
|
267
160
|
changed();
|
|
268
161
|
}
|
|
269
162
|
function request(url, signal, parse, body) {
|
|
@@ -281,6 +174,12 @@ function createProjectComments(options) {
|
|
|
281
174
|
await saveThread(store, thread);
|
|
282
175
|
view();
|
|
283
176
|
}
|
|
177
|
+
async function forget(id) {
|
|
178
|
+
await opened;
|
|
179
|
+
members?.delete(id);
|
|
180
|
+
await writeRows(store.threads, { delete: [id] });
|
|
181
|
+
view();
|
|
182
|
+
}
|
|
284
183
|
function includes(thread) {
|
|
285
184
|
return threadMatches(thread, filter);
|
|
286
185
|
}
|
|
@@ -413,6 +312,13 @@ function createProjectComments(options) {
|
|
|
413
312
|
get ready() {
|
|
414
313
|
return loaded && snapshot.connection.state === "ready";
|
|
415
314
|
},
|
|
315
|
+
/**
|
|
316
|
+
* Who this browser comments as, once the server said.
|
|
317
|
+
* @returns The viewer, or null until then or without one.
|
|
318
|
+
*/
|
|
319
|
+
get viewer() {
|
|
320
|
+
return viewer;
|
|
321
|
+
},
|
|
416
322
|
loadingThread: (id) => details.has(id),
|
|
417
323
|
load,
|
|
418
324
|
loadThread,
|
|
@@ -474,6 +380,31 @@ function createProjectComments(options) {
|
|
|
474
380
|
thread: saved
|
|
475
381
|
};
|
|
476
382
|
},
|
|
383
|
+
/**
|
|
384
|
+
* Deletes one of the viewer's messages; its first message deletes the whole discussion.
|
|
385
|
+
* @param threadId - The discussion.
|
|
386
|
+
* @param messageId - The message to delete.
|
|
387
|
+
* @returns The snapshot after the confirmed deletion.
|
|
388
|
+
*/
|
|
389
|
+
async remove(threadId, messageId) {
|
|
390
|
+
requireCapability("delete");
|
|
391
|
+
let id = parseThreadId(threadId), thread = snapshot.threads.find((item) => item.id === id);
|
|
392
|
+
if (!thread?.revision) throw new Error(t("app.client.projectComments.reloadDiscussionBeforeSaving"));
|
|
393
|
+
let next = predictThreadDelete(thread, messageId);
|
|
394
|
+
return operate(routes.comments.deleteMessage.href({ id }), {
|
|
395
|
+
messageId,
|
|
396
|
+
expectedRevision: thread.revision
|
|
397
|
+
}, parseDeletion, (result) => {
|
|
398
|
+
if (!result.thread) return forget(id);
|
|
399
|
+
if (result.thread.id !== id) throw new CommentsRequestError(t("app.client.projectComments.refreshBeforeTryingAgain"), 409, "uncertain");
|
|
400
|
+
return merge(result.thread);
|
|
401
|
+
}, next ? t("app.client.projectComments.commentDeleted") : t("app.client.projectComments.discussionDeleted"), id, (store) => {
|
|
402
|
+
if (next && store.threads.has(id)) store.threads.update(id, (draft) => {
|
|
403
|
+
draft.messages = next.messages;
|
|
404
|
+
draft.messageCount = next.messageCount;
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
},
|
|
477
408
|
async sync() {
|
|
478
409
|
requireCapability("sync");
|
|
479
410
|
return operate(routes.comments.sync.href(), { direction: "both" }, parseThreadSnapshot, adopt, t("app.client.projectComments.commentsSynced"));
|
|
@@ -491,4 +422,4 @@ function defineScreen(screen) {
|
|
|
491
422
|
return screen;
|
|
492
423
|
}
|
|
493
424
|
//#endregion
|
|
494
|
-
export {
|
|
425
|
+
export { loadItemComments as i, createProjectComments as n, loadComments as r, defineScreen as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $t as Button, B as TaskWorkspace, C as ThreadTaskLinks, Dt as taskHref, Et as selectedTask, Jt as CommentThreadDetail,
|
|
2
|
-
import {
|
|
3
|
-
import { n as requestTasks, t as TaskRequestError } from "./tasks-request-Bie1PpQP.js";
|
|
1
|
+
import { $t as Button, B as TaskWorkspace, C as ThreadTaskLinks, Dt as taskHref, En as predictWorkUpdate, Et as selectedTask, Jt as CommentThreadDetail, Kr as parseWorkMutationResult, Ot as taskRole, Rr as parseSectionData, S as writeRows, T as ItemDiscussion, Tn as predictWorkCreate, Tt as readConversationLocation, Ur as parseWorkDetail, Xr as parseWorkSyncResult, Xt as CommentComposer, Yt as CommentThreadItem, b as plainRow, cn as toast, gn as Text, h as storedWorkspace, l as projectStore, mn as t, nt as CommentThreadHeading, qt as taskRoutes, wn as predictWorkAction, x as writeOptimistically, xt as conversationLabel, y as routes } from "./comment-data-DyIZNpfG.js";
|
|
2
|
+
import { n as requestTasks, t as TaskRequestError } from "./tasks-request-ZWmbc8fE.js";
|
|
4
3
|
import { r as projectWork } from "../node-host.js";
|
|
5
|
-
import { n as
|
|
4
|
+
import { i as loadItemComments, n as createProjectComments, t as defineScreen } from "./screen-CZXWJEds.js";
|
|
5
|
+
import { n as ProjectTaskPicker, t as ProjectThreadLinks } from "./project-thread-links-CauJF0Cz.js";
|
|
6
6
|
import { on, ref } from "remix/component";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "remix/component/jsx-runtime";
|
|
8
8
|
//#region app/client/task-discussion.tsx
|
|
@@ -195,7 +195,14 @@ function TaskDiscussion(handle) {
|
|
|
195
195
|
id: thread.id,
|
|
196
196
|
body,
|
|
197
197
|
parentId
|
|
198
|
-
}) : void 0
|
|
198
|
+
}) : void 0,
|
|
199
|
+
viewerId: comments.viewer?.id,
|
|
200
|
+
onDelete: capabilities.delete ? async (messageId) => {
|
|
201
|
+
let whole = thread.messages[0]?.id === messageId;
|
|
202
|
+
await comments.remove(thread.id, messageId);
|
|
203
|
+
if (whole && selected === thread.id) selected = void 0;
|
|
204
|
+
handle.update();
|
|
205
|
+
} : void 0
|
|
199
206
|
})
|
|
200
207
|
}, thread.id)) : /* @__PURE__ */ jsx(Text, {
|
|
201
208
|
variant: "ui-caption",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Gr as parseWorkItemRef, mn as t, qr as parseWorkQuery, y as routes } from "./comment-data-DyIZNpfG.js";
|
|
2
2
|
import { createMultiMatcher } from "remix/route-pattern/match";
|
|
3
3
|
//#region app/client/tasks-request.ts
|
|
4
4
|
var reads = createMultiMatcher();
|