use-chisel 0.1.8 → 0.1.10
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/README.md +76 -2
- package/dist/hosted-entry.js +4 -133
- package/dist/index.js +5 -168
- package/dist/review/snapshot-upload.d.ts +2 -0
- package/dist/review-content-entry.d.ts +1 -0
- package/dist/review-content-entry.js +9 -3
- package/dist/review-entry.d.ts +1 -0
- package/dist/review-entry.js +4 -3
- package/dist/workspace/breakpoints.d.ts +3 -0
- package/dist/workspace/comment-box.d.ts +4 -1
- package/dist/workspace/comments.d.ts +22 -0
- package/dist/workspace/project-controls.d.ts +20 -0
- package/dist/workspace/review-links.d.ts +4 -0
- package/dist/workspace/workspace.d.ts +9 -1
- package/dist/workspace-entry.d.ts +2 -1
- package/dist/workspace-entry.js +17 -346
- package/package.json +5 -4
- package/src/review/workspace-design.css +11 -3
- package/dist/persistence.d.ts +0 -30
- package/dist/review/media-lightbox.d.ts +0 -8
- package/dist/theme.d.ts +0 -1
- package/dist/workspace/area.d.ts +0 -10
- package/dist/workspace/color-picker.d.ts +0 -6
- package/dist/workspace/color.d.ts +0 -9
- package/dist/workspace/comment-drag-handle.d.ts +0 -3
- package/dist/workspace/composer-position.d.ts +0 -13
- package/dist/workspace/confirmation.d.ts +0 -11
- package/dist/workspace/hover-dismiss.d.ts +0 -4
- package/dist/workspace/mode-shortcuts.d.ts +0 -1
- package/dist/workspace/page-control.d.ts +0 -7
- package/dist/workspace/preview-navigation.d.ts +0 -4
- package/dist/workspace/thread-morph.d.ts +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# use-chisel
|
|
2
2
|
|
|
3
|
+
Hosted website reviews and visual editing for Next.js.
|
|
4
|
+
|
|
5
|
+
## Quickstart
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install use-chisel
|
|
9
|
+
npx chisel
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Sign in with Google, connect the project, restart its development server, and
|
|
13
|
+
open `/chisel`. Chisel stores shared feedback in its hosted service; client
|
|
14
|
+
projects do not configure a database.
|
|
15
|
+
|
|
16
|
+
Before inviting clients, deploy the site with `CHISEL_ENABLED=1`, open its public
|
|
17
|
+
HTTPS `/chisel` page, then use **Share review link**. Chisel remembers the deployed
|
|
18
|
+
URL for sharing from local development. Localhost links cannot be shared with clients.
|
|
19
|
+
Return to your projects from the account menu or the hosted `/chisel/projects` page.
|
|
20
|
+
|
|
21
|
+
## Review workflow
|
|
22
|
+
|
|
23
|
+
- Copy a thread link to reopen its page, breakpoint, and exact captured width,
|
|
24
|
+
including after sign-in. Links require existing review access.
|
|
25
|
+
- The thread header's status pill shows **Open**, **Ready**, or **Resolved**.
|
|
26
|
+
Owners choose Ready for review; the comment author confirms by selecting
|
|
27
|
+
Resolved, or selects Open if more work is needed. Changes appear immediately
|
|
28
|
+
while saving; failed saves restore the previous status.
|
|
29
|
+
- Open and unread counts appear on the breakpoint controls and page picker.
|
|
30
|
+
- Comment and reply text, rich formatting, and inline edit drafts recover locally
|
|
31
|
+
after refresh. Drafts expire after seven days and are isolated by project/user.
|
|
32
|
+
Uploaded files must be reattached after refresh.
|
|
33
|
+
- A screenshot and viewport context are captured when composing a new comment.
|
|
34
|
+
Its image uploads after the comment posts. Failed captures do not block feedback;
|
|
35
|
+
failed uploads offer retry. Password/payment-code fields and elements marked
|
|
36
|
+
`data-chisel-private` are excluded. Cross-origin media or browser restrictions
|
|
37
|
+
can prevent a complete capture; a screenshot is a reference, not a browser recording.
|
|
38
|
+
- Owners can copy selected feedback for Codex, including context, replies, proposed
|
|
39
|
+
changes, and private attachment links. Media links expire; thread links remain.
|
|
40
|
+
|
|
3
41
|
## Combined Workspace
|
|
4
42
|
|
|
5
43
|
`use-chisel/workspace` exports `ChiselWorkspace`, `ChiselPreview`,
|
|
@@ -12,6 +50,18 @@ with Google.
|
|
|
12
50
|
|
|
13
51
|
Edit, Comment, and View share one toolbar. Threads expand from element pins;
|
|
14
52
|
history appears in the sidebar.
|
|
53
|
+
The mode toolbar sits at bottom left; the breakpoint switcher sits at bottom
|
|
54
|
+
right. **D**, **T**, and **M** select exact iframe widths of 1440px, 768px, and
|
|
55
|
+
390px. Drag either preview edge to resize, use arrow keys on the edge, or type a
|
|
56
|
+
pixel width and press Enter, up to the space available beside the sidebar.
|
|
57
|
+
Typed widths also apply when leaving the field; Escape cancels the edit.
|
|
58
|
+
Wider previews scroll horizontally rather than shrinking the selected width.
|
|
59
|
+
Comments cascade to narrower previews: Desktop feedback appears on all three
|
|
60
|
+
breakpoints, Tablet feedback on Tablet and Mobile, and Mobile feedback only on
|
|
61
|
+
Mobile. Mobile is below 768px, Tablet is 768–1023px, and Desktop starts at 1024px;
|
|
62
|
+
comments without a `breakpoint` belong to Desktop. Opening inherited feedback
|
|
63
|
+
keeps the current preview width. Custom stores
|
|
64
|
+
should persist the optional `WorkspaceComment.breakpoint` field on creation.
|
|
15
65
|
Use **E** for Edit, **C** for Comment, and **V** for View. **Shift+C** toggles
|
|
16
66
|
all comment pins, threads, and the comments sidebar. Shortcuts are ignored
|
|
17
67
|
while typing in form fields or editable content. Comments are browser-local by
|
|
@@ -53,6 +103,11 @@ hosted service; project credentials and Supabase service keys are not required
|
|
|
53
103
|
in the client project. The hosted workspace supports rich text, attachments,
|
|
54
104
|
replies, resolution, review links, reviewer presence, and unread indicators.
|
|
55
105
|
|
|
106
|
+
Review sign-in is remembered across tabs and browser restarts on the same
|
|
107
|
+
website. Sessions expire after 30 days of inactivity and renew during use.
|
|
108
|
+
Temporary connection failures keep the saved sign-in; signing out clears it
|
|
109
|
+
across tabs. Project access and website origin are still checked on every request.
|
|
110
|
+
|
|
56
111
|
The generated route defaults off in production. To use it on a deployed review
|
|
57
112
|
site, set `CHISEL_ENABLED=1` for that deployment and redeploy. Hosted connections
|
|
58
113
|
require HTTPS, except on localhost. Automatic setup currently requires an App
|
|
@@ -121,5 +176,24 @@ dictation, and explicit submit in the same form. Custom rich text can be passed
|
|
|
121
176
|
optional mutation `body`, with validated upload IDs in `attachmentTokens`. Adapters
|
|
122
177
|
must validate both before storing them and bind uploads to the authenticated user
|
|
123
178
|
and site. Keep the editor and attachment draft when `onSubmit` or `onReply` returns
|
|
124
|
-
`false`; release it only after a successful save.
|
|
125
|
-
|
|
179
|
+
`false`; release it only after a successful save. The shared rich-text review UI
|
|
180
|
+
uses Slate. Supabase stays in the hosted service or the host's adapter; client
|
|
181
|
+
projects do not need its SDK. Icons are bundled at build time.
|
|
182
|
+
|
|
183
|
+
### Custom host adapters
|
|
184
|
+
|
|
185
|
+
Optional workspace props keep custom hosts on the same review workflow:
|
|
186
|
+
`projectId` isolates local drafts; `manageReview(action, payload)` loads project
|
|
187
|
+
settings and handles `settings`, `remove_reviewer`, `start_round`, and `approve`;
|
|
188
|
+
`accountURL` links to the host's project directory. The exported `ManageReview`
|
|
189
|
+
and `ReviewProject` types describe this contract.
|
|
190
|
+
|
|
191
|
+
`saveSnapshot(commentId, file)` uploads the captured PNG after the comment saves.
|
|
192
|
+
The shared `uploadSnapshot` helper reuses the attachment transport and preserves
|
|
193
|
+
upload IDs on retry. Bind the upload through the `snapshot` mutation, checking
|
|
194
|
+
membership, author permissions, file ownership/type, and one snapshot per thread.
|
|
195
|
+
`getAttachmentURL(id)` supplies private media links for the Codex export.
|
|
196
|
+
Stores should persist `context`, `status`, status author/time, and review-round IDs.
|
|
197
|
+
The `status` mutation supports `open`, `ready`, and `resolved`; keep `resolved`
|
|
198
|
+
consistent for older clients. `commentURL`, `feedbackMarkdown`, and
|
|
199
|
+
`publicReviewURL` are exported from `use-chisel/review-content` for custom hosts.
|
package/dist/hosted-entry.js
CHANGED
|
@@ -1,134 +1,5 @@
|
|
|
1
|
-
"use client";import{
|
|
2
|
-
.chisel-review .comment-thread[data-native-ui=true]{padding:0;gap:0;border:0;border-radius:
|
|
3
|
-
|
|
4
|
-
.chisel-review .comment-thread[data-native-ui=true] form{width:100%}
|
|
5
|
-
.chisel-review-thread-content{width:100%;min-width:0}
|
|
6
|
-
.chisel-review-message{display:flex;gap:12px;padding:16px}
|
|
7
|
-
.chisel-review-message-content{min-width:0;flex:1}
|
|
8
|
-
.chisel-review-avatar{width:32px;height:32px;flex-shrink:0}
|
|
9
|
-
.chisel-review-avatar img,.chisel-review .feedback-reply-avatar img{width:100%;height:100%;object-fit:cover;border-radius:inherit}
|
|
10
|
-
.chisel-review-byline{display:flex;gap:8px;flex-wrap:wrap;align-items:baseline;line-height:1.5}
|
|
11
|
-
.chisel-review-byline strong{font-weight:500}
|
|
12
|
-
.chisel-review-byline time{color:var(--chisel-ui-secondary);font-size:12px;font-variant-numeric:tabular-nums}
|
|
13
|
-
.chisel-rich-body{white-space:pre-wrap;overflow-wrap:anywhere;line-height:1.5;color:var(--chisel-ui-text)}
|
|
14
|
-
.chisel-rich-body p,.chisel-rich-editor p{margin:0;min-height:1.5em}
|
|
15
|
-
.chisel-rich-body a,.chisel-rich-editor a{color:var(--chisel-ui-accent-text);text-decoration:underline;text-underline-offset:2px}
|
|
16
|
-
.chisel-rich-body code,.chisel-rich-editor code{font:0.9em ui-monospace,monospace;background:var(--chisel-ui-inset);padding:1px 3px;border-radius:4px}
|
|
17
|
-
.chisel-review .chisel-expand-thread{margin:0 16px 12px 60px;min-height:40px;padding:0;background:transparent;color:var(--chisel-ui-accent-text)}
|
|
18
|
-
.chisel-review-reply{display:flex;align-items:flex-start;gap:12px;padding:16px;border-top:1px solid var(--chisel-ui-border)}
|
|
19
|
-
.chisel-rich-editor{min-width:0;min-height:40px;max-height:min(180px,30dvh);overflow-y:auto;padding:8px;font-size:14px;line-height:1.5;outline:none;overflow-wrap:anywhere}
|
|
20
|
-
.chisel-review-reply .chisel-rich-editor{padding:12px 14px;min-height:44px}
|
|
21
|
-
.chisel-review .comment-box-native{border:0;border-radius:var(--chisel-ui-radius);box-shadow:0 0 0 1px var(--chisel-ui-border),0 8px 32px #00000014;font:inherit}
|
|
22
|
-
.chisel-review .comment-box-native>form{display:flex;flex-direction:column;min-height:0;height:100%;flex:1}
|
|
23
|
-
.chisel-review .comment-box-native .comment-box-prompt{align-items:flex-start;padding:8px;gap:0}
|
|
24
|
-
.chisel-review .comment-box-native .comment-box-symbol{margin-top:0;background:transparent;border-radius:8px}
|
|
25
|
-
.chisel-review .comment-box-native .comment-box-footer{background:var(--chisel-ui-surface);border-top:1px solid var(--chisel-ui-border)}
|
|
26
|
-
.chisel-review .comment-box-native .comment-box-cancel{border:0;border-radius:8px;background:transparent;font:inherit}
|
|
27
|
-
.chisel-review .comment-box-native .comment-box-submit{border-radius:8px;background:var(--chisel-ui-action);color:var(--chisel-ui-action-text)}
|
|
28
|
-
.chisel-review .comment-box-native .comment-box-element{background:var(--chisel-ui-inset)}
|
|
29
|
-
.chisel-review .comment-box-native .comment-box-properties{background:var(--chisel-ui-surface)}
|
|
30
|
-
.chisel-review .feedback-comment{border-radius:var(--chisel-ui-radius)}
|
|
31
|
-
.chisel-review .comment-thread[data-expanded=false] .chisel-rich-body{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;max-height:4.5em;overflow:hidden}
|
|
32
|
-
.chisel-review [data-slate-placeholder]{color:var(--chisel-ui-secondary);opacity:1!important}
|
|
33
|
-
.chisel-review .chisel-reply-field{position:relative;flex:1;min-width:0;border:1px solid var(--chisel-ui-border);border-radius:16px;background:var(--chisel-ui-raised)}
|
|
34
|
-
.chisel-review .chisel-reply-submit{position:absolute;right:4px;bottom:4px;display:grid;place-items:center;width:40px;height:40px;padding:0;border:0;border-radius:50%;background:var(--chisel-ui-action);color:var(--chisel-ui-action-text)}
|
|
35
|
-
.chisel-review .feedback-reply-avatar{width:32px;height:32px;margin-top:8px}
|
|
36
|
-
.chisel-composer-input{flex:1;min-width:0;max-height:min(320px,42dvh);overflow:auto}
|
|
37
|
-
.chisel-attachment-controls{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:0 8px;font-size:12px;color:var(--chisel-ui-secondary)}
|
|
38
|
-
.chisel-review-reply .chisel-attachment-controls{padding-right:48px}
|
|
39
|
-
.chisel-formatting-tools button{display:grid;place-items:center;width:40px;height:40px;flex-shrink:0;padding:0;border:0;border-radius:8px;background:transparent;color:var(--chisel-ui-secondary);transition:background 150ms,scale 150ms}
|
|
40
|
-
.chisel-formatting-tools button:hover{background:var(--chisel-ui-hover)}
|
|
41
|
-
.chisel-formatting-tools button[aria-pressed=true]{color:var(--chisel-ui-accent-text);background:var(--chisel-ui-accent-surface)}
|
|
42
|
-
.chisel-formatting-tools{display:flex;gap:0;flex-wrap:wrap;padding:0 4px}
|
|
43
|
-
.chisel-formatting-tools button:active{scale:0.96}
|
|
44
|
-
.chisel-link-dialog{display:flex;flex-wrap:wrap;gap:6px;padding:8px;border-top:1px solid var(--chisel-ui-border);background:var(--chisel-ui-surface)}
|
|
45
|
-
.chisel-link-dialog label{flex:1;min-width:120px;font-size:12px;color:var(--chisel-ui-secondary)}
|
|
46
|
-
.chisel-link-dialog input{display:block;width:100%;height:40px;background:var(--chisel-ui-inset);border:1px solid var(--chisel-ui-border);border-radius:6px;color:var(--chisel-ui-text);padding:6px}
|
|
47
|
-
.chisel-link-dialog button{align-self:flex-end;min-height:40px;min-width:40px;padding:6px;border:0;border-radius:6px;background:var(--chisel-ui-hover);color:var(--chisel-ui-text)}
|
|
48
|
-
.chisel-link-dialog [role=alert]{width:100%;color:var(--chisel-ui-danger);font-size:12px}
|
|
49
|
-
.chisel-attachment-error{color:var(--chisel-ui-danger);line-height:1.5}
|
|
50
|
-
.chisel-attachment-previews{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px;max-height:240px;overflow:auto}
|
|
51
|
-
.chisel-attachment-preview{position:relative;min-width:0;overflow:hidden;border:1px solid var(--chisel-ui-border);border-radius:8px;background:var(--chisel-ui-surface)}
|
|
52
|
-
.chisel-attachment-preview>img,.chisel-attachment-preview>a>img,.chisel-attachment-preview>video{display:block;width:100%;height:100px;object-fit:contain;background:var(--chisel-ui-inset);outline:1px solid #0000001a;outline-offset:-1px}
|
|
53
|
-
.chisel-attachment-preview>span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:8px;font-size:12px}
|
|
54
|
-
.chisel-attachment-preview>button:not(.review-media-thumbnail){position:absolute;top:0;right:0;display:grid;place-items:center;width:40px;height:40px;padding:0;border:0;border-radius:0 8px;background:var(--chisel-ui-surface);color:var(--chisel-ui-text)}
|
|
55
|
-
.chisel-attachment-preview>.chisel-attachment-retry{right:40px;border-radius:0 0 0 8px}
|
|
56
|
-
.chisel-attachment-preview>.chisel-attachment-load{position:static;width:100%;height:auto;min-height:100px;padding:8px}
|
|
57
|
-
.comment-thread .feedback-thread-header{position:sticky;top:0;z-index:1;background:var(--chisel-ui-surface)}
|
|
58
|
-
.chisel-review .comment-thread[data-native-ui=true][data-expanded=false]{border-radius:16px 16px 16px 0}
|
|
59
|
-
@media(prefers-color-scheme:dark){.chisel-attachment-preview>img,.chisel-attachment-preview>a>img,.chisel-attachment-preview>video{outline-color:#ffffff1a}}
|
|
60
|
-
@media(prefers-reduced-motion:reduce){.chisel-formatting-tools button{transition:none}}
|
|
61
|
-
`;var X=`/* Shared presentation for the owned review UI. */
|
|
62
|
-
.feedback-shell.chisel-review .comment-thread[data-native-ui=true],.feedback-shell.chisel-review .comment-box-native{border:0;border-radius:16px;background:var(--chisel-ui-surface);box-shadow:var(--chisel-ui-popover-shadow)}
|
|
63
|
-
.feedback-shell.chisel-review .comment-thread[data-expanded=false]{border-radius:16px 16px 16px 0}
|
|
64
|
-
.chisel-review-thread-content,.review-thread,.review-comment-content{width:100%;min-width:0}
|
|
65
|
-
.review-comment,.feedback-shell.chisel-review .chisel-review-message{display:flex;align-items:flex-start;gap:12px;padding:12px 20px}
|
|
66
|
-
.review-comment-content,.chisel-review-message-content{flex:1;min-width:0}
|
|
67
|
-
.review-comment-avatar{display:grid;place-items:center;flex-shrink:0;width:28px;height:28px;border-radius:50%;overflow:hidden;background:var(--chisel-ui-avatar);color:var(--chisel-ui-avatar-text);font-size:12px}
|
|
68
|
-
.review-comment-avatar img{width:100%;height:100%;object-fit:cover}
|
|
69
|
-
.review-comment-header,.chisel-review-byline{display:flex;align-items:baseline;flex-wrap:wrap;gap:8px;line-height:20px;margin-bottom:4px}
|
|
70
|
-
.review-comment-author{font-size:13px;font-weight:500;overflow-wrap:anywhere}
|
|
71
|
-
.review-comment-time{font-size:12px;color:var(--chisel-ui-muted);font-variant-numeric:tabular-nums;white-space:nowrap}
|
|
72
|
-
.review-comment-header{position:relative;padding-right:32px}
|
|
73
|
-
.review-comment-edit{position:absolute;right:-8px;top:-10px;display:grid;place-items:center;width:40px;height:40px;border:0;border-radius:8px;background:transparent;color:var(--chisel-ui-muted);opacity:0;transition:opacity 120ms,background 120ms}
|
|
74
|
-
.review-comment:hover .review-comment-edit,.review-comment:focus-within .review-comment-edit,.review-comment-edit:focus-visible{opacity:1}
|
|
75
|
-
.review-comment-edit:hover{background:var(--chisel-ui-hover);color:var(--chisel-ui-text)}
|
|
76
|
-
@media(hover:none){.review-comment-edit{opacity:1}}
|
|
77
|
-
.review-inline-edit{border:1px solid var(--chisel-ui-border);border-radius:10px;padding:8px}
|
|
78
|
-
.review-inline-edit-actions{display:flex;justify-content:flex-end;gap:6px;margin-top:8px}
|
|
79
|
-
.review-inline-edit-actions button{min-height:32px;padding:0 10px;border:0;border-radius:6px;background:var(--chisel-ui-hover);color:var(--chisel-ui-text)}
|
|
80
|
-
.review-comment-body,.chisel-rich-body{font-size:14px;line-height:21px;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
81
|
-
.review-comment-body p{margin:0;min-height:21px}.review-comment-body p+p{margin-top:8px}
|
|
82
|
-
.review-comment-body a{color:var(--chisel-ui-accent-text);text-decoration:underline;text-underline-offset:3px}
|
|
83
|
-
.review-comment-body code{font:12px/1.5 ui-monospace,SFMono-Regular,monospace;background:var(--chisel-ui-inset);border-radius:4px;padding:2px 4px}
|
|
84
|
-
.review-composer{margin:0}
|
|
85
|
-
.feedback-shell.chisel-review .chisel-review-reply{display:flex;align-items:flex-start;gap:12px;border:0;padding:20px}
|
|
86
|
-
.feedback-shell.chisel-review .chisel-review-reply[hidden]{display:none}
|
|
87
|
-
.feedback-shell.chisel-review .feedback-reply-avatar{width:28px;height:28px;margin-top:8px}
|
|
88
|
-
.feedback-shell.chisel-review .chisel-reply-field{position:relative;flex:1;min-width:0;min-height:48px;border:0;border-radius:12px;background:var(--chisel-ui-raised)}
|
|
89
|
-
.review-composer-editor{min-width:0;min-height:40px;max-height:min(180px,30dvh);overflow:auto;padding:10px 12px;font-size:14px;line-height:21px;overflow-wrap:anywhere;outline:none}
|
|
90
|
-
.review-composer-editor p{margin:0}
|
|
91
|
-
.review-composer-editor>p,.chisel-rich-editor>p{position:relative}
|
|
92
|
-
.feedback-shell.chisel-review .chisel-review-reply :is(.review-composer-editor,.chisel-rich-editor){padding-right:56px}
|
|
93
|
-
.feedback-shell.chisel-review .chisel-reply-submit{position:absolute;right:4px;bottom:4px;display:grid;place-items:center;width:40px;height:40px;min-height:40px;padding:0;border:0;border-radius:8px;background:var(--chisel-ui-action);color:var(--chisel-ui-action-text)}
|
|
94
|
-
.chisel-reply-submit:disabled{opacity:.35}
|
|
95
|
-
.feedback-shell.chisel-review .comment-box-native>form{display:flex;flex-direction:column;flex:1;min-height:0;height:100%}
|
|
96
|
-
.feedback-shell.chisel-review .comment-box-native .comment-box-prompt{align-items:flex-start;padding:8px;gap:0}
|
|
97
|
-
.feedback-shell.chisel-review .comment-box-native .comment-box-footer{border:0;background:var(--chisel-ui-surface)}
|
|
98
|
-
.feedback-shell.chisel-review .comment-box-native .comment-box-element{background:var(--chisel-ui-raised)}
|
|
99
|
-
.feedback-shell.chisel-review .comment-box-native .comment-box-cancel{border:0;border-radius:8px;background:transparent}
|
|
100
|
-
.feedback-shell.chisel-review .comment-box-native .comment-box-cancel:hover{background:var(--chisel-ui-hover)}
|
|
101
|
-
.feedback-shell.chisel-review .comment-box-native .comment-box-submit{border-radius:8px}
|
|
102
|
-
.chisel-composer-input{flex:1;min-width:0;max-height:min(320px,42dvh);overflow:auto}
|
|
103
|
-
.chisel-attachment-controls{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:0 8px;color:var(--chisel-ui-secondary);font-size:12px;line-height:18px}
|
|
104
|
-
.chisel-review-reply .chisel-attachment-controls{padding-right:48px}
|
|
105
|
-
.chisel-attachment-error{color:var(--chisel-ui-danger);line-height:1.5}
|
|
106
|
-
.chisel-attachment-previews,.review-attachments{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px;max-height:240px;overflow:auto}
|
|
107
|
-
.review-attachments{padding:12px 0 0;max-height:none}
|
|
108
|
-
.feedback-shell.chisel-review .chisel-attachment-preview,.review-attachment{position:relative;min-width:0;margin:0;overflow:hidden;border:0;border-radius:8px;background:var(--chisel-ui-raised)}
|
|
109
|
-
.chisel-attachment-preview>img,.chisel-attachment-preview>video,.review-media-thumbnail img,.review-media-thumbnail video{display:block;width:100%;height:120px;object-fit:contain;background:var(--chisel-ui-inset)}
|
|
110
|
-
.review-attachment figcaption{padding:8px;font-size:12px;line-height:18px;overflow-wrap:anywhere}
|
|
111
|
-
.review-attachment-placeholder{min-height:100px;display:grid;place-items:center;padding:12px;color:var(--chisel-ui-secondary);font-size:12px}
|
|
112
|
-
.chisel-attachment-preview>button:not(.review-media-thumbnail){position:absolute;top:0;right:0;display:grid;place-items:center;width:40px;height:40px;padding:0;border:0;border-radius:0 8px;background:var(--chisel-ui-surface);color:var(--chisel-ui-text)}
|
|
113
|
-
.review-retry-upload{display:inline-flex;align-items:center;gap:6px;min-height:40px;padding:0 8px;border:0;border-radius:8px;background:transparent;color:var(--chisel-ui-text);font:inherit}
|
|
114
|
-
.review-retry-upload:hover{background:var(--chisel-ui-hover)}
|
|
115
|
-
.chisel-attachment-preview>span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:8px;font-size:12px}
|
|
116
|
-
.feedback-shell.chisel-review .chisel-expand-thread{display:inline-flex;align-items:center;margin:0 20px 8px 60px;min-height:40px;padding:0;border:0;background:transparent;color:var(--chisel-ui-secondary);font-size:13px}
|
|
117
|
-
.chisel-review [data-slate-placeholder]{opacity:1!important;color:var(--chisel-ui-secondary)}
|
|
118
|
-
@media(pointer:coarse){.feedback-shell.chisel-review .chisel-reply-submit{width:44px;height:44px}.chisel-review-reply .chisel-attachment-controls{padding-right:52px}.feedback-shell.chisel-review .chisel-reply-field{min-height:52px}.feedback-shell.chisel-review .chisel-review-reply :is(.review-composer-editor,.chisel-rich-editor){padding-right:60px}}
|
|
119
|
-
@media(forced-colors:active){.feedback-shell.chisel-review .comment-thread[data-native-ui=true],.feedback-shell.chisel-review .comment-box-native,.feedback-shell.chisel-review .chisel-reply-field{border:1px solid CanvasText;box-shadow:none}.review-comment-avatar{border:1px solid CanvasText}}
|
|
120
|
-
.review-media-thumbnail{position:relative;display:block;width:100%;padding:0;border:0;background:var(--chisel-ui-inset);cursor:pointer}
|
|
121
|
-
.review-media-thumbnail img,.review-media-thumbnail video{display:block;width:100%;height:120px;object-fit:contain}
|
|
122
|
-
.review-media-play{position:absolute;inset:50% auto auto 50%;display:grid;place-items:center;width:40px;height:40px;border-radius:50%;background:#0009;color:white;transform:translate(-50%,-50%)}
|
|
123
|
-
.review-media-lightbox{position:fixed;inset:0;width:100vw;height:100dvh;max-width:none;max-height:none;margin:0;padding:24px;border:0;background:transparent;color:var(--chisel-ui-text)}
|
|
124
|
-
.review-media-lightbox::backdrop{background:#000b}
|
|
125
|
-
.review-media-lightbox-content{display:flex;flex-direction:column;width:min(100%,1000px);max-height:100%;margin:auto;border-radius:12px;overflow:hidden;background:var(--chisel-ui-surface);box-shadow:0 16px 48px #0006}
|
|
126
|
-
.review-media-lightbox-content header{display:flex;align-items:center;gap:12px;min-height:56px;padding:8px 12px 8px 16px}
|
|
127
|
-
.review-media-lightbox-content header span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
128
|
-
.review-media-lightbox-content header a{color:var(--chisel-ui-text);font-size:13px}
|
|
129
|
-
.review-media-lightbox-content header button{display:grid;place-items:center;flex-shrink:0;width:40px;height:40px;padding:0;border:0;border-radius:8px;background:transparent;color:var(--chisel-ui-text)}
|
|
130
|
-
.review-media-lightbox-content header button:hover{background:var(--chisel-ui-hover)}
|
|
131
|
-
.review-media-lightbox-content>img,.review-media-lightbox-content>video{display:block;min-height:0;max-width:100%;max-height:calc(100dvh - 104px);margin:auto;object-fit:contain;background:#000}
|
|
132
|
-
`;var b="https://chisel-review.vercel.app";function H(p){return Array.isArray(p)?p.filter(o=>o&&typeof o.id=="string"&&typeof o.name=="string"&&typeof o.path=="string").map(o=>({id:o.id,name:o.name.slice(0,100),path:o.path.slice(0,2048),image:typeof o.image=="string"&&/^https?:\/\//.test(o.image)?o.image:null})):[]}function Pe({projectId:p}){let o=`chisel:session:${p}`,c=w(""),[m,N]=h(null),[q,y]=h(!0),[B,I]=h(""),[Q,k]=h(!1),[M,S]=h([]),[Y,G]=h([]),[K,L]=h("connecting"),C=w("/"),T=w(!1),[Z,ee]=h(0),j=w(new Set),u=x(()=>{for(let e of j.current)e()},[]),E=w(null);E.current=m;let P=w(null),z=w(""),d=x(async(e,i,t,r,a=!1)=>{let n=await fetch(`${b}/chisel/api/hosted/${e}`,{method:i,headers:{Authorization:`Bearer ${c.current}`,...t?{"Content-Type":"application/json","X-Chisel-Protocol":"2"}:{}},...t?{body:JSON.stringify(t)}:{},signal:r,keepalive:a}),v=await n.json();if(!n.ok)throw n.status===401&&E.current&&k(!0),Object.assign(new Error(v.error||"Chisel is unavailable. Please try again."),{status:n.status});if(v.siteId&&v.siteId!==p)throw new Error("This session belongs to another project.");return v},[p]),l=x((e,i)=>d(e==="GET"?`comments?path=${encodeURIComponent(C.current)}`:"comments",e,i),[d]),ie=U(()=>{let e=0;return{async list(){let i=++e;try{let t=await l("GET");return i===e&&(S(t.comments),T.current||G(H(t.participants))),t.comments}catch(t){throw t}},async mutate(i){++e;let t=(await l("POST",i)).comment;return++e,S(r=>r.some(a=>a.id===t.id)?r.map(a=>a.id===t.id?t:a):[...r,t]),window.setTimeout(u,0),t},async delete(i){++e,await l("POST",{type:"delete",id:i}),++e,S(t=>t.filter(r=>r.id!==i)),window.setTimeout(u,0)},subscribe(i){return j.current.add(i),()=>{j.current.delete(i)}}}},[l,u]),te=x(async(e,i)=>{await l("POST",{type:"read",id:e,activity:i})},[l]),re=x((e,i)=>{S(t=>t.map(r=>r.id===e?{...r,readActivity:Math.max(r.readActivity??0,i)}:r))},[]),{flush:D,markDisplayed:ae}=ge(te,re);O(()=>{if(!m)return;let e=!0,i,t,r=new AbortController,a=()=>{document.visibilityState==="visible"&&(clearTimeout(t),t=setTimeout(()=>{u(),D()},40))};async function n(){try{let R=await fetch(`${b}/chisel/api/hosted/events?path=${encodeURIComponent(C.current)}`,{headers:{Authorization:`Bearer ${c.current}`},signal:r.signal});if(R.status===401&&k(!0),!R.ok||!R.body)throw new Error("Live updates unavailable");let se=R.body.getReader(),ce=new TextDecoder,f="";for(;e;){let{value:le,done:de}=await se.read();if(de)break;f+=ce.decode(le,{stream:!0});let $;for(;($=f.indexOf(`
|
|
1
|
+
"use client";import{useCallback as u,useEffect as F,useMemo as H,useRef as g,useState as v}from"react";import{ChiselWorkspace as ye,ChiselWorkspaceStyles as J}from"use-chisel/workspace";import{ReviewComposer as ke,ReviewThread as Se,useReviewAttachments as Te,useReadQueue as Ce,uploadSnapshot as Ee}from"use-chisel/review";import{publicReviewURL as Re}from"use-chisel/review-content";var ee=`.chisel-review{font-family:var(--chisel-ui-font);-webkit-font-smoothing:antialiased}.chisel-review .comment-thread[data-native-ui=true]{padding:0;gap:0;border:0;border-radius:16px;background:var(--chisel-ui-surface);box-shadow:0 0 0 1px var(--chisel-ui-border),0 8px 32px #00000014;font-size:14px}.chisel-review .comment-thread[data-native-ui=true] .feedback-preview{margin:4px 12px 0;border-radius:8px}.chisel-review .comment-thread[data-native-ui=true] form{width:100%}.chisel-review-thread-content{width:100%;min-width:0}.chisel-review-message{display:flex;gap:12px;padding:16px}.chisel-review-message-content{min-width:0;flex:1}.chisel-review-avatar{width:32px;height:32px;flex-shrink:0}.chisel-review-avatar img,.chisel-review .feedback-reply-avatar img{width:100%;height:100%;object-fit:cover;border-radius:inherit}.chisel-review-byline{display:flex;gap:8px;flex-wrap:wrap;align-items:baseline;line-height:1.5}.chisel-review-byline strong{font-weight:500}.chisel-review-byline time{color:var(--chisel-ui-secondary);font-size:12px;font-variant-numeric:tabular-nums}.chisel-rich-body{white-space:pre-wrap;overflow-wrap:anywhere;line-height:1.5;color:var(--chisel-ui-text)}.chisel-rich-body p,.chisel-rich-editor p{margin:0;min-height:1.5em}.chisel-rich-body a,.chisel-rich-editor a{color:var(--chisel-ui-accent-text);text-decoration:underline;text-underline-offset:2px}.chisel-rich-body code,.chisel-rich-editor code{font:.9em ui-monospace,monospace;background:var(--chisel-ui-inset);padding:1px 3px;border-radius:4px}.chisel-review .chisel-expand-thread{margin:0 16px 12px 60px;min-height:40px;padding:0;background:transparent;color:var(--chisel-ui-accent-text)}.chisel-review-reply{display:flex;align-items:flex-start;gap:12px;padding:16px;border-top:1px solid var(--chisel-ui-border)}.chisel-rich-editor{min-width:0;min-height:40px;max-height:min(180px,30dvh);overflow-y:auto;padding:8px;font-size:14px;line-height:1.5;outline:none;overflow-wrap:anywhere}.chisel-review-reply .chisel-rich-editor{padding:12px 14px;min-height:44px}.chisel-review .comment-box-native{border:0;border-radius:var(--chisel-ui-radius);box-shadow:0 0 0 1px var(--chisel-ui-border),0 8px 32px #00000014;font:inherit}.chisel-review .comment-box-native>form{display:flex;flex-direction:column;min-height:0;height:100%;flex:1}.chisel-review .comment-box-native .comment-box-prompt{align-items:flex-start;padding:8px;gap:0}.chisel-review .comment-box-native .comment-box-symbol{margin-top:0;background:transparent;border-radius:8px}.chisel-review .comment-box-native .comment-box-footer{background:var(--chisel-ui-surface);border-top:1px solid var(--chisel-ui-border)}.chisel-review .comment-box-native .comment-box-cancel{border:0;border-radius:8px;background:transparent;font:inherit}.chisel-review .comment-box-native .comment-box-submit{border-radius:8px;background:var(--chisel-ui-action);color:var(--chisel-ui-action-text)}.chisel-review .comment-box-native .comment-box-element{background:var(--chisel-ui-inset)}.chisel-review .comment-box-native .comment-box-properties{background:var(--chisel-ui-surface)}.chisel-review .feedback-comment{border-radius:var(--chisel-ui-radius)}.chisel-review .comment-thread[data-expanded=false] .chisel-rich-body{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;max-height:4.5em;overflow:hidden}.chisel-review [data-slate-placeholder]{color:var(--chisel-ui-secondary);opacity:1!important}.chisel-review .chisel-reply-field{position:relative;flex:1;min-width:0;border:1px solid var(--chisel-ui-border);border-radius:16px;background:var(--chisel-ui-raised)}.chisel-review .chisel-reply-submit{position:absolute;right:4px;bottom:4px;display:grid;place-items:center;width:40px;height:40px;padding:0;border:0;border-radius:50%;background:var(--chisel-ui-action);color:var(--chisel-ui-action-text)}.chisel-review .feedback-reply-avatar{width:32px;height:32px;margin-top:8px}.chisel-composer-input{flex:1;min-width:0;max-height:min(320px,42dvh);overflow:auto}.chisel-attachment-controls{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:0 8px;font-size:12px;color:var(--chisel-ui-secondary)}.chisel-review-reply .chisel-attachment-controls{padding-right:48px}.chisel-formatting-tools button{display:grid;place-items:center;width:40px;height:40px;flex-shrink:0;padding:0;border:0;border-radius:8px;background:transparent;color:var(--chisel-ui-secondary);transition:background .15s,scale .15s}.chisel-formatting-tools button:hover{background:var(--chisel-ui-hover)}.chisel-formatting-tools button[aria-pressed=true]{color:var(--chisel-ui-accent-text);background:var(--chisel-ui-accent-surface)}.chisel-formatting-tools{display:flex;gap:0;flex-wrap:wrap;padding:0 4px}.chisel-formatting-tools button:active{scale:.96}.chisel-link-dialog{display:flex;flex-wrap:wrap;gap:6px;padding:8px;border-top:1px solid var(--chisel-ui-border);background:var(--chisel-ui-surface)}.chisel-link-dialog label{flex:1;min-width:120px;font-size:12px;color:var(--chisel-ui-secondary)}.chisel-link-dialog input{display:block;width:100%;height:40px;background:var(--chisel-ui-inset);border:1px solid var(--chisel-ui-border);border-radius:6px;color:var(--chisel-ui-text);padding:6px}.chisel-link-dialog button{align-self:flex-end;min-height:40px;min-width:40px;padding:6px;border:0;border-radius:6px;background:var(--chisel-ui-hover);color:var(--chisel-ui-text)}.chisel-link-dialog [role=alert]{width:100%;color:var(--chisel-ui-danger);font-size:12px}.chisel-attachment-error{color:var(--chisel-ui-danger);line-height:1.5}.chisel-attachment-previews{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px;max-height:240px;overflow:auto}.chisel-attachment-preview{position:relative;min-width:0;overflow:hidden;border:1px solid var(--chisel-ui-border);border-radius:8px;background:var(--chisel-ui-surface)}.chisel-attachment-preview>img,.chisel-attachment-preview>a>img,.chisel-attachment-preview>video{display:block;width:100%;height:100px;object-fit:contain;background:var(--chisel-ui-inset);outline:1px solid #0000001a;outline-offset:-1px}.chisel-attachment-preview>span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:8px;font-size:12px}.chisel-attachment-preview>button:not(.review-media-thumbnail){position:absolute;top:0;right:0;display:grid;place-items:center;width:40px;height:40px;padding:0;border:0;border-radius:0 8px;background:var(--chisel-ui-surface);color:var(--chisel-ui-text)}.chisel-attachment-preview>.chisel-attachment-retry{right:40px;border-radius:0 0 0 8px}.chisel-attachment-preview>.chisel-attachment-load{position:static;width:100%;height:auto;min-height:100px;padding:8px}.comment-thread .feedback-thread-header{position:sticky;top:0;z-index:1;background:var(--chisel-ui-surface)}.chisel-review .comment-thread[data-native-ui=true][data-expanded=false]{border-radius:16px 16px 16px 0}@media(prefers-color-scheme:dark){.chisel-attachment-preview>img,.chisel-attachment-preview>a>img,.chisel-attachment-preview>video{outline-color:#ffffff1a}}@media(prefers-reduced-motion:reduce){.chisel-formatting-tools button{transition:none}}
|
|
2
|
+
`;var ie=`.feedback-shell.chisel-review .comment-thread[data-native-ui=true],.feedback-shell.chisel-review .comment-box-native{border:0;border-radius:16px;background:var(--chisel-ui-surface);box-shadow:var(--chisel-ui-popover-shadow)}.feedback-shell.chisel-review .comment-thread[data-expanded=false]{border-radius:16px 16px 16px 0}.chisel-review-thread-content,.review-thread,.review-comment-content{width:100%;min-width:0}.review-capture-context{margin:4px 12px 8px;font-size:12px;line-height:18px;color:var(--chisel-ui-muted);overflow-wrap:anywhere}.review-comment,.feedback-shell.chisel-review .chisel-review-message{display:flex;align-items:flex-start;gap:12px;padding:12px 20px}.review-comment-content,.chisel-review-message-content{flex:1;min-width:0}.review-comment-avatar{display:grid;place-items:center;flex-shrink:0;width:28px;height:28px;border-radius:50%;overflow:hidden;background:var(--chisel-ui-avatar);color:var(--chisel-ui-avatar-text);font-size:12px}.review-comment-avatar img{width:100%;height:100%;object-fit:cover}.review-comment-header,.chisel-review-byline{display:flex;align-items:baseline;flex-wrap:wrap;gap:8px;line-height:20px;margin-bottom:4px}.review-comment-author{font-size:13px;font-weight:500;overflow-wrap:anywhere}.review-comment-time{font-size:12px;color:var(--chisel-ui-muted);font-variant-numeric:tabular-nums;white-space:nowrap}.review-comment-header{position:relative;padding-right:32px}.review-comment-edit{position:absolute;right:-8px;top:-10px;display:grid;place-items:center;width:40px;height:40px;border:0;border-radius:8px;background:transparent;color:var(--chisel-ui-muted);opacity:0;transition:opacity .12s,background .12s}.review-comment:hover .review-comment-edit,.review-comment:focus-within .review-comment-edit,.review-comment-edit:focus-visible{opacity:1}.review-comment-edit:hover{background:var(--chisel-ui-hover);color:var(--chisel-ui-text)}@media(hover:none){.review-comment-edit{opacity:1}}.review-inline-edit{border:1px solid var(--chisel-ui-border);border-radius:10px;padding:8px}.review-inline-edit-actions{display:flex;justify-content:flex-end;gap:6px;margin-top:8px}.review-inline-edit-actions button{min-height:40px;padding:0 10px;border:0;border-radius:8px;background:transparent;color:var(--chisel-ui-text)}.review-inline-edit-actions button:last-child{background:var(--chisel-ui-action);color:var(--chisel-ui-action-text)}.review-inline-edit-actions button:not(:last-child):hover{background:var(--chisel-ui-hover)}.review-inline-edit-actions button:disabled{opacity:.45}@media(pointer:coarse){.review-inline-edit-actions button{min-height:44px}}.review-comment-body,.chisel-rich-body{font-size:14px;line-height:21px;white-space:pre-wrap;overflow-wrap:anywhere}.review-comment-body p{margin:0;min-height:21px}.review-comment-body p+p{margin-top:8px}.review-comment-body a{color:var(--chisel-ui-accent-text);text-decoration:underline;text-underline-offset:3px}.review-comment-body code{font:12px/1.5 ui-monospace,SFMono-Regular,monospace;background:var(--chisel-ui-inset);border-radius:4px;padding:2px 4px}.review-composer{margin:0}.feedback-shell.chisel-review .chisel-review-reply{display:flex;align-items:flex-start;gap:12px;border:0;padding:20px}.feedback-shell.chisel-review .chisel-review-reply[hidden]{display:none}.feedback-shell.chisel-review .feedback-reply-avatar{width:28px;height:28px;margin-top:8px}.feedback-shell.chisel-review .chisel-reply-field{position:relative;flex:1;min-width:0;min-height:48px;border:0;border-radius:12px;background:var(--chisel-ui-raised)}.review-composer-editor{min-width:0;min-height:40px;max-height:min(180px,30dvh);overflow:auto;padding:10px 12px;font-size:14px;line-height:21px;overflow-wrap:anywhere;outline:none}.review-composer-editor p{margin:0}.review-composer-editor>p,.chisel-rich-editor>p{position:relative}.feedback-shell.chisel-review .chisel-review-reply :is(.review-composer-editor,.chisel-rich-editor){padding-right:56px}.feedback-shell.chisel-review .chisel-reply-submit{position:absolute;right:4px;bottom:4px;display:grid;place-items:center;width:40px;height:40px;min-height:40px;padding:0;border:0;border-radius:8px;background:var(--chisel-ui-action);color:var(--chisel-ui-action-text)}.chisel-reply-submit:disabled{opacity:.35}.feedback-shell.chisel-review .comment-box-native>form{display:flex;flex-direction:column;flex:1;min-height:0;height:100%}.feedback-shell.chisel-review .comment-box-native .comment-box-prompt{align-items:flex-start;padding:8px;gap:0}.feedback-shell.chisel-review .comment-box-native .comment-box-footer{border:0;background:var(--chisel-ui-surface)}.feedback-shell.chisel-review .comment-box-native .comment-box-element{background:var(--chisel-ui-raised)}.feedback-shell.chisel-review .comment-box-native .comment-box-cancel{border:0;border-radius:8px;background:transparent}.feedback-shell.chisel-review .comment-box-native .comment-box-cancel:hover{background:var(--chisel-ui-hover)}.feedback-shell.chisel-review .comment-box-native .comment-box-submit{border-radius:8px}.chisel-composer-input{flex:1;min-width:0;max-height:min(320px,42dvh);overflow:auto}.chisel-attachment-controls{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:0 8px;color:var(--chisel-ui-secondary);font-size:12px;line-height:18px}.chisel-review-reply .chisel-attachment-controls{padding-right:48px}.chisel-attachment-error{color:var(--chisel-ui-danger);line-height:1.5}.chisel-attachment-previews,.review-attachments{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px;max-height:240px;overflow:auto}.review-attachments{padding:12px 0 0;max-height:none}.feedback-shell.chisel-review .chisel-attachment-preview,.review-attachment{position:relative;min-width:0;margin:0;overflow:hidden;border:0;border-radius:8px;background:var(--chisel-ui-raised)}.chisel-attachment-preview>img,.chisel-attachment-preview>video,.review-media-thumbnail img,.review-media-thumbnail video{display:block;width:100%;height:120px;object-fit:contain;background:var(--chisel-ui-inset)}.review-attachment figcaption{padding:8px;font-size:12px;line-height:18px;overflow-wrap:anywhere}.review-attachment-placeholder{min-height:100px;display:grid;place-items:center;padding:12px;color:var(--chisel-ui-secondary);font-size:12px}.chisel-attachment-preview>button:not(.review-media-thumbnail){position:absolute;top:0;right:0;display:grid;place-items:center;width:40px;height:40px;padding:0;border:0;border-radius:0 8px;background:var(--chisel-ui-surface);color:var(--chisel-ui-text)}.review-retry-upload{display:inline-flex;align-items:center;gap:6px;min-height:40px;padding:0 8px;border:0;border-radius:8px;background:transparent;color:var(--chisel-ui-text);font:inherit}.review-retry-upload:hover{background:var(--chisel-ui-hover)}.chisel-attachment-controls .review-retry-upload[aria-label]{min-width:40px;justify-content:center}.chisel-attachment-preview>span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:8px;font-size:12px}.feedback-shell.chisel-review .chisel-expand-thread{display:inline-flex;align-items:center;margin:0 20px 8px 60px;min-height:40px;padding:0;border:0;background:transparent;color:var(--chisel-ui-secondary);font-size:13px}.chisel-review [data-slate-placeholder]{opacity:1!important;color:var(--chisel-ui-secondary)}@media(pointer:coarse){.feedback-shell.chisel-review .chisel-reply-submit{width:44px;height:44px}.chisel-review-reply .chisel-attachment-controls{padding-right:52px}.feedback-shell.chisel-review .chisel-reply-field{min-height:52px}.feedback-shell.chisel-review .chisel-review-reply :is(.review-composer-editor,.chisel-rich-editor){padding-right:60px}}@media(forced-colors:active){.feedback-shell.chisel-review .comment-thread[data-native-ui=true],.feedback-shell.chisel-review .comment-box-native,.feedback-shell.chisel-review .chisel-reply-field{border:1px solid CanvasText;box-shadow:none}.review-comment-avatar{border:1px solid CanvasText}}.review-media-thumbnail{position:relative;display:block;width:100%;padding:0;border:0;background:var(--chisel-ui-inset);cursor:pointer}.review-media-thumbnail img,.review-media-thumbnail video{display:block;width:100%;height:120px;object-fit:contain}.review-media-play{position:absolute;inset:50% auto auto 50%;display:grid;place-items:center;width:40px;height:40px;border-radius:50%;background:#0009;color:#fff;transform:translate(-50%,-50%)}.review-media-lightbox{position:fixed;inset:0;width:100vw;height:100dvh;max-width:none;max-height:none;margin:0;padding:24px;border:0;background:transparent;color:var(--chisel-ui-text)}.review-media-lightbox[open]{display:flex;align-items:center;justify-content:center}.review-media-lightbox::backdrop{background:#000b}.review-media-lightbox-content{display:flex;flex-direction:column;width:fit-content;min-width:min(320px,100%);max-width:min(100%,1000px);max-height:100%;margin:auto;border-radius:12px;overflow:hidden;background:var(--chisel-ui-surface);box-shadow:0 16px 48px #0006}.review-media-lightbox-content header{display:flex;align-items:center;gap:12px;min-height:56px;padding:8px 12px 8px 16px}.review-media-lightbox-content header span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.review-media-lightbox-content header a{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:40px;min-height:40px;padding:0;border-radius:8px;color:var(--chisel-ui-text);font-size:13px}.review-media-lightbox-content header a:hover{background:var(--chisel-ui-hover)}.review-media-lightbox-content header button{display:grid;place-items:center;flex-shrink:0;width:40px;height:40px;padding:0;border:0;border-radius:8px;background:transparent;color:var(--chisel-ui-text)}.review-media-lightbox-content header button:hover{background:var(--chisel-ui-hover)}.review-media-lightbox-content>img,.review-media-lightbox-content>video{display:block;min-height:0;max-width:100%;max-height:calc(100dvh - 104px);margin:auto;object-fit:contain;background:#000}
|
|
3
|
+
`;import{Fragment as Le,jsx as d,jsxs as b}from"react/jsx-runtime";var x="https://chisel-review.vercel.app";function re(l,n){try{localStorage.setItem(l,n),sessionStorage.removeItem(l);return}catch{}try{sessionStorage.setItem(l,n)}catch{}}function X(l){try{localStorage.removeItem(l)}catch{}try{sessionStorage.removeItem(l)}catch{}}function Pe(l){let n="";try{n=localStorage.getItem(l)||""}catch{}if(!/^[0-9a-f]{64}$/.test(n))try{n=sessionStorage.getItem(l)||""}catch{}return/^[0-9a-f]{64}$/.test(n)?(re(l,n),n):""}function te(l){return Array.isArray(l)?l.filter(n=>n&&typeof n.id=="string"&&typeof n.name=="string"&&typeof n.path=="string").map(n=>({id:n.id,name:n.name.slice(0,100),path:n.path.slice(0,2048),image:typeof n.image=="string"&&/^https?:\/\//.test(n.image)?n.image:null})):[]}function Me({projectId:l}){let n=`chisel:session:${l}`,o=g(""),Y=g(n),[ne,O]=v(0),[m,j]=v(null),[ae,q]=v(!0),[P,k]=v(""),[oe,y]=v(!1),[K,S]=v([]),[se,N]=v([]),[ce,M]=v("connecting"),L=g("/"),z=g(!1),[le,de]=v(0),W=g(new Set),f=u(()=>{for(let e of W.current)e()},[]),T=g(null);T.current=m;let A=g(null),I=g(""),p=u(async(e,i,t,a,r=!1)=>{let c=o.current,h=await fetch(`${x}/chisel/api/hosted/${e}`,{method:i,headers:{Authorization:`Bearer ${c}`,...t?{"Content-Type":"application/json","X-Chisel-Protocol":"2"}:{}},...t?{body:JSON.stringify(t)}:{},signal:a,keepalive:r}),s=await h.json().catch(()=>null);if(c!==o.current)throw new Error("Your Chisel account changed. Please retry.");if(!h.ok)throw h.status===401&&c===o.current&&T.current&&y(!0),Object.assign(new Error(s?.error||"Chisel is unavailable. Please try again."),{status:h.status});if(!s||typeof s!="object")throw new Error("Chisel is unavailable. Please try again.");if(s.siteId&&s.siteId!==l)throw new Error("This session belongs to another project.");return s},[l]),w=u((e,i)=>p(e==="GET"?`comments?path=${encodeURIComponent(L.current)}`:"comments",e,i),[p]),B=H(()=>{let e=0;return{async list(){let i=++e,t=await w("GET");return i===e&&(S(t.comments),z.current||N(te(t.participants))),t.comments},async mutate(i){++e;let t=(await w("POST",i)).comment;return++e,S(a=>a.some(r=>r.id===t.id)?a.map(r=>r.id===t.id?t:r):[...a,t]),window.setTimeout(f,0),t},async delete(i){++e,await w("POST",{type:"delete",id:i}),++e,S(t=>t.filter(a=>a.id!==i)),window.setTimeout(f,0)},subscribe(i){return W.current.add(i),()=>{W.current.delete(i)}}}},[w,f]),he=u(async(e,i)=>{await w("POST",{type:"read",id:e,activity:i})},[w]),pe=u((e,i)=>{S(t=>t.map(a=>a.id===e?{...a,readActivity:Math.max(a.readActivity??0,i)}:a))},[]),{flush:Q,markDisplayed:ue}=Ce(he,pe);F(()=>{if(!m)return;let e=!0,i,t,a=new AbortController,r=()=>{document.visibilityState==="visible"&&(clearTimeout(t),t=setTimeout(()=>{f(),Q()},40))};async function c(){let s=!1;try{let C=o.current,$=await fetch(`${x}/chisel/api/hosted/events?path=${encodeURIComponent(L.current)}`,{headers:{Authorization:`Bearer ${C}`},signal:a.signal});if(e&&$.status===401&&C===o.current&&y(!0),!$.ok||!$.body)throw new Error("Live updates unavailable");let ge=$.body.getReader(),xe=new TextDecoder,E="";for(;e;){let{value:be,done:fe}=await ge.read();if(fe)break;E+=xe.decode(be,{stream:!0});let D;for(;(D=E.indexOf(`
|
|
133
4
|
|
|
134
|
-
`))>=0;){let
|
|
5
|
+
`))>=0;){let R=E.slice(0,D);if(E=E.slice(D+2),R==="data: ready")M("connected"),r();else if(R==="data: renew")s=!0;else if(R==="data: change")r();else if(R.startsWith("data: presence:"))try{z.current=!0,N(te(JSON.parse(R.slice(15))))}catch{}}}}catch{}e&&(z.current=!1,s||M("reconnecting"),i=setTimeout(()=>{c()},s?0:2e3))}M(s=>s==="connected"?s:"connecting"),c();let h=window.setInterval(r,1e4);return window.addEventListener("focus",r),window.addEventListener("online",r),document.addEventListener("visibilitychange",r),()=>{e=!1,z.current=!1,a.abort(),clearTimeout(i),clearTimeout(t),window.clearInterval(h),window.removeEventListener("focus",r),window.removeEventListener("online",r),document.removeEventListener("visibilitychange",r)}},[m,le,f,Q]);let me=u(e=>{L.current!==e&&(L.current=e,de(i=>i+1),f())},[f]),U=H(()=>({async userId(){return T.current?.user.id??""},async discard(e){await p("attachments","POST",{action:"cancel",id:e.id},void 0,!0)},async send(e,i,t){let a=async()=>{let c=await p("attachments","POST",{action:"confirm",id:e.id});if(c.attachment?.id!==e.id||c.attachment.token!==e.id)throw new Error("The upload confirmation was incomplete. Please retry.");return e.id};if(i){if(!t())return"";try{return await a()}catch(c){if(![404,503].includes(c.status??0))throw c}}let r=await p("attachments","POST",{action:"prepare",id:e.id,name:e.name,mimeType:e.mimeType,size:e.size});if(r.attachment?.id===e.id&&r.attachment.token===e.id)return e.id;if(typeof r.url!="string"||typeof r.key!="string")throw new Error("The upload could not be started. Please retry.");if(!t())return"";if(!e.stored){let c=new FormData;c.append("cacheControl","3600"),c.append("",e.file);try{(await fetch(r.url,{method:"PUT",headers:{apikey:r.key,"x-upsert":"false"},body:c})).ok&&(e.stored=!0)}catch{}}return t()?a():""}}),[p]),Z=H(()=>function(i=!1,t=0){return Te(i,t,U)},[U]),V=u(async(e,i)=>{let t=await p(`attachments?id=${encodeURIComponent(e)}`,"GET",void 0,i);if(typeof t.url!="string")throw new Error("Attachment unavailable");return t.url},[p]),G=u((e,i)=>p("project",e==="get"?"GET":"POST",e==="get"?void 0:{...i,action:e}),[p]),ve=u((e,i)=>Ee(i,U,t=>B.mutate({type:"snapshot",id:e,attachmentTokens:[t]})),[U,B]),we=u(e=>V(e,new AbortController().signal),[V]);F(()=>{Y.current!==n&&(o.current="",Y.current=n,j(null)),o.current=o.current||Pe(n);let e=!0,i=!1,t;q(!!o.current&&!T.current);async function a(){if(i||!o.current)return;clearTimeout(t),i=!0;let h=o.current;try{let s=await w("GET");if(!s.user?.id||s.siteId!==l||!["owner","reviewer"].includes(s.role))throw new Error("Could not verify your Chisel session. Please retry.");if(!e||h!==o.current)return;j(s),y(!1),k("");let C=new URL(window.location.href);C.searchParams.delete("invite"),window.history.replaceState(window.history.state,"",C)}catch(s){if(!e||h!==o.current)return;s.status===401?(o.current="",X(n),y(!!T.current)):t=setTimeout(()=>{document.visibilityState==="visible"&&a()},5e3),k(s instanceof Error?s.message:"Could not connect to Chisel.")}finally{i=!1,e&&q(!1)}}let r=()=>{document.visibilityState==="visible"&&a()},c=h=>{if(!(h.key!==n&&h.key!==null)){try{if(h.storageArea!==localStorage)return}catch{return}o.current=h.newValue&&/^[0-9a-f]{64}$/.test(h.newValue)?h.newValue:"",o.current||X(n),j(null),S([]),N([]),y(!1),k(""),O(s=>s+1)}};return o.current&&a(),window.addEventListener("online",r),window.addEventListener("focus",r),document.addEventListener("visibilitychange",r),window.addEventListener("storage",c),()=>{e=!1,clearTimeout(t),window.removeEventListener("online",r),window.removeEventListener("focus",r),document.removeEventListener("visibilitychange",r),window.removeEventListener("storage",c)}},[n,l,w,ne]),F(()=>{let e=i=>{i.origin!==x||i.source!==A.current||i.data?.type!=="chisel:session"||i.data.state!==I.current||!/^[0-9a-f]{64}$/.test(i.data.token)||(o.current=i.data.token,re(n,o.current),I.current="",A.current=null,k(""),O(t=>t+1))};return window.addEventListener("message",e),()=>window.removeEventListener("message",e)},[n]);function _(){let e=crypto.getRandomValues(new Uint8Array(32));I.current=Array.from(e,a=>a.toString(16).padStart(2,"0")).join("");let i=new URL("/chisel/connect",x);i.searchParams.set("site",l),i.searchParams.set("origin",window.location.origin),i.searchParams.set("state",I.current);let t=new URLSearchParams(window.location.search).get("invite");t&&i.searchParams.set("invite",t),A.current=window.open(i.toString(),"chisel-sign-in","popup,width=520,height=700"),A.current||k("Allow pop-ups for this site, then try again.")}return ae?b("main",{className:"chisel-sign-in",children:[d(J,{}),d("section",{children:d("p",{children:"Connecting to Chisel\u2026"})})]}):!m&&o.current?b("main",{className:"chisel-sign-in",children:[d(J,{}),b("section",{children:[d("strong",{className:"chisel-sign-in-brand",children:"chisel"}),d("h1",{children:"Reconnecting to Chisel"}),d("p",{children:"Your sign-in is saved. Check your connection and try again."}),d("button",{onClick:()=>O(e=>e+1),children:"Retry connection"}),P&&d("p",{role:"alert",children:P})]})]}):m?b(Le,{children:[b("style",{children:[ee,ie]}),d(ye,{user:m.user,commentStore:B,canManageComments:m.role==="owner",projectId:l,manageReview:G,saveSnapshot:ve,getAttachmentURL:we,accountURL:`${x}/chisel/projects`,agentURL:`${x}/chisel/mcp`,commentUI:{className:"chisel-review",renderComposer:e=>{let i=K.find(t=>t.id===e.commentId);return d(ke,{...e,defaultBody:i?.body,existingAttachments:i?.attachments,useAttachments:Z})},renderThread:e=>d(Se,{...e,onRead:ue,useAttachments:Z,loadMedia:V},e.comment.id)},collaboration:{status:ce,participants:se,setPage:me,markRead(){},unreadThreadIds:K.filter(e=>e.readActivity!==null&&e.readActivity<e.activity).map(e=>e.id)},getReviewLink:m.role==="owner"?async(e=!1)=>{let i=await G("get"),t=i.reviewURL??Re(window.location.origin);if(!t)throw new Error("Open the deployed website\u2019s HTTPS /chisel page to copy a review link. Localhost links cannot be shared with clients.");i.reviewURL||await G("settings",{reviewURL:t});let a=await fetch(`${x}/chisel/api/hosted/invite`,{method:"POST",headers:{Authorization:`Bearer ${o.current}`,"Content-Type":"application/json","X-Chisel-Protocol":"2"},body:JSON.stringify({rotate:e})}),r=await a.json();if(a.status===401&&y(!0),!a.ok||typeof r.invite!="string")throw new Error(r.error||"Could not create a review link.");let c=new URL(t);return c.searchParams.set("mode","comment"),c.searchParams.set("invite",r.invite),c.toString()}:void 0,validateSession:async()=>!!o.current,signOut:async()=>{let e=await fetch(`${x}/chisel/api/hosted/logout`,{method:"DELETE",headers:{Authorization:`Bearer ${o.current}`,"X-Chisel-Protocol":"2"}});if(!e.ok&&e.status!==401)throw new Error("Sign out failed.");o.current="",X(n)}},m.user.id),oe&&b("div",{role:"alert",style:{position:"fixed",bottom:16,right:16,zIndex:999999,background:"white",color:"black",padding:12,borderRadius:8,boxShadow:"0 2px 12px #0003"},children:["Your Chisel session expired. ",d("button",{type:"button",onClick:_,children:"Sign in again"})]})]}):b("main",{className:"chisel-sign-in",children:[d(J,{}),b("section",{children:[d("strong",{className:"chisel-sign-in-brand",children:"chisel"}),d("h1",{children:"Sign in to review"}),d("p",{children:"Connect this website to your Chisel account."}),d("button",{onClick:_,children:"Continue with Chisel"}),P&&d("p",{role:"alert",children:P})]})]})}export{Me as HostedChisel};
|