camox 0.71.0 → 0.74.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/core/createApp.d.ts +4 -103
  2. package/dist/core/createApp.js +3 -24
  3. package/dist/core/createBlock.d.ts +2 -2
  4. package/dist/core/createBlock.js +41 -185
  5. package/dist/core/createLayout.d.ts +6 -77
  6. package/dist/core/createLayout.js +12 -50
  7. package/dist/core/editing/createEditableBlock.d.ts +9 -75
  8. package/dist/core/editing/createEditableBlock.js +258 -640
  9. package/dist/core/hooks/useIsEditable.js +2 -2
  10. package/dist/core/lib/artifactData.js +8 -3
  11. package/dist/core/lib/contentType.d.ts +23 -38
  12. package/dist/core/lib/contentType.js +34 -62
  13. package/dist/core/lib/iconTypes.d.ts +0 -3
  14. package/dist/core/lib/icons.js +63 -51
  15. package/dist/core/lib/recordScope.js +1 -1
  16. package/dist/features/canvas/CanvasOverlays.js +94 -176
  17. package/dist/features/canvas/CanvasPageFrame.js +62 -68
  18. package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -3
  19. package/dist/features/canvas/canvasOverlayGeometry.js +1 -7
  20. package/dist/features/canvas/sidebar/CuratedPageInspector.js +3 -21
  21. package/dist/features/canvas/sidebar/LayoutPageBlocks.js +1 -2
  22. package/dist/features/canvas/useCanvasCamera.js +1 -1
  23. package/dist/features/canvas/useCanvasFrame.js +1 -1
  24. package/dist/features/content/ContentCollection.js +2 -2
  25. package/dist/features/content/collection-form.js +6 -7
  26. package/dist/features/page/CuratedPageContent.js +15 -24
  27. package/dist/features/page/UnplacedBlockContent.js +1 -6
  28. package/dist/features/preview/CamoxPreview.js +30 -33
  29. package/dist/features/preview/EditablePageContent.js +131 -151
  30. package/dist/features/preview/components/BlockActionsPopover.js +43 -152
  31. package/dist/features/preview/components/CanvasPreview.js +2 -2
  32. package/dist/features/preview/components/Frame.js +3 -3
  33. package/dist/features/preview/components/IconFieldEditor.js +1 -1
  34. package/dist/features/preview/components/ItemFieldsEditor.js +1 -3
  35. package/dist/features/preview/components/Overlays.js +18 -84
  36. package/dist/features/preview/components/PageInfo.js +121 -98
  37. package/dist/features/preview/components/PageTree.js +57 -103
  38. package/dist/features/preview/components/PreviewPanel.js +8 -11
  39. package/dist/features/preview/components/RecordCombobox.js +65 -78
  40. package/dist/features/preview/components/ReferenceFieldEditor.js +1 -19
  41. package/dist/features/preview/components/ReferenceListFieldEditor.js +1 -19
  42. package/dist/features/preview/components/RemovedBlockPlaceholder.js +2 -2
  43. package/dist/features/preview/components/SelectionEditor.js +6 -5
  44. package/dist/features/preview/components/useRepeatableItemActions.js +18 -24
  45. package/dist/features/preview/components/useUpdateBlockPosition.js +1 -1
  46. package/dist/features/preview/overlayMessages.js +1 -4
  47. package/dist/features/preview/previewStore.js +3 -23
  48. package/dist/features/renderer/RendererApp.js +17 -141
  49. package/dist/features/renderer/definitionAnswers.js +1 -8
  50. package/dist/features/renderer/rendererHost.js +1 -31
  51. package/dist/features/renderer/studioConnection.js +1 -25
  52. package/dist/features/routes/pageRuntime.js +15 -4
  53. package/dist/features/runtime/ClaimCard.js +192 -0
  54. package/dist/features/runtime/pageApp.js +5 -4
  55. package/dist/features/runtime/runtime.js +29 -8
  56. package/dist/features/runtime/worker.js +2 -2
  57. package/dist/features/runtime/workerRequest.d.ts +6 -0
  58. package/dist/features/runtime/workerRequest.js +13 -1
  59. package/dist/features/runtime/workerRuntime.d.ts +2 -2
  60. package/dist/features/runtime/workerRuntime.js +2 -2
  61. package/dist/features/studio/components/AgentSidebar.js +7 -7
  62. package/dist/features/studio/components/ChatWidget.js +142 -106
  63. package/dist/features/studio/components/ContentFindings.js +127 -230
  64. package/dist/features/studio/components/DeleteDraftDialog.js +112 -0
  65. package/dist/features/studio/components/DraftBar.js +98 -53
  66. package/dist/features/studio/components/DraftsControl.js +203 -190
  67. package/dist/features/studio/components/ReviewDraftDialog.js +670 -0
  68. package/dist/features/studio/components/{Patrol.js → Specialists.js} +291 -330
  69. package/dist/features/studio/components/Squareling.js +5 -5
  70. package/dist/features/studio/components/ThreadComposer.js +106 -127
  71. package/dist/features/studio/components/ThreadMessages.js +137 -45
  72. package/dist/features/studio/findingSentence.js +14 -12
  73. package/dist/features/studio/fixMessage.js +23 -0
  74. package/dist/features/studio/reportSentence.js +1 -1
  75. package/dist/features/studio/{patrollerBio.js → specialistBio.js} +8 -5
  76. package/dist/features/studio/studioStore.js +29 -15
  77. package/dist/features/studio/workingSentence.js +1 -1
  78. package/dist/features/vite/blockBoilerplate.js +1 -1
  79. package/dist/features/vite/definitionsSync.js +1 -8
  80. package/dist/lib/api-client.js +5 -1
  81. package/dist/lib/queries.js +5 -6
  82. package/dist/lib/studio-definitions.js +0 -2
  83. package/dist/lib/studio-reads.d.ts +1 -1
  84. package/dist/lib/studio-reads.js +5 -10
  85. package/dist/lib/use-thread.js +196 -138
  86. package/dist/package.js +1 -1
  87. package/dist/studio-overlays.css +0 -29
  88. package/dist/studio.css +1 -1
  89. package/package.json +4 -4
  90. package/skills/camox/SKILL.md +1 -1
  91. package/skills/camox/references/artifacts.md +4 -4
  92. package/skills/camox/references/block-definitions.md +21 -25
  93. package/skills/camox/references/dom-integrations.md +1 -1
  94. package/skills/camox/references/layout-definitions.md +3 -12
  95. package/skills/camox/references/routed-layouts.md +2 -2
  96. package/skills/camox-expand/SKILL.md +5 -5
  97. package/skills/camoxify/SKILL.md +4 -4
  98. package/dist/features/canvas/canvasInsertionSeams.js +0 -44
  99. package/dist/features/preview/components/AddBlockSheet.js +0 -314
  100. package/dist/features/preview/components/BlockPeek.js +0 -66
  101. package/dist/features/preview/components/BlockThumbnail.js +0 -281
  102. package/dist/features/preview/components/blockGridNavigation.js +0 -15
  103. package/dist/features/preview/referencePickerFocus.js +0 -29
  104. package/dist/features/studio/components/ReviewDraftSheet.js +0 -1587
@@ -8,11 +8,10 @@ import { CanvasWorkspaceContext } from "../canvas/canvasZoom.js";
8
8
  import { PreviewEditingOwnerContext } from "../preview/previewSelection.js";
9
9
  import { StudioNoticeContext } from "../preview/studioNotice.js";
10
10
  import { ContentEditsContext } from "../../core/editing/contentEdits.js";
11
- import { PreviewDocumentContext } from "../runtime/PreviewDocumentContext.js";
12
11
  import { restyle } from "../preview/components/previewStyles.js";
12
+ import { PreviewDocumentContext } from "../runtime/PreviewDocumentContext.js";
13
13
  import { FrameContext } from "../preview/components/Frame.js";
14
14
  import { DerivedPageContent } from "../page/DerivedPageContent.js";
15
- import { BlockPeek } from "../preview/components/BlockPeek.js";
16
15
  import { EditablePageContent } from "../preview/EditablePageContent.js";
17
16
  import { c } from "react/compiler-runtime";
18
17
  import * as React from "react";
@@ -30,10 +29,9 @@ import { createPortal } from "react-dom";
30
29
  * to load fails each frame, as a page that throws does.
31
30
  */
32
31
  function RendererApp(t0) {
33
- const $ = c(27);
32
+ const $ = c(21);
34
33
  const { connection, camoxApp, codeLoaded, projectUuid, runtimeBasePath } = t0;
35
34
  const frames = useFrames(connection);
36
- const thumbnails = React.useSyncExternalStore(connection.subscribe, connection.thumbnails, connection.thumbnails);
37
35
  const t1 = connection.edit;
38
36
  let t2;
39
37
  if ($[0] !== connection) {
@@ -70,47 +68,26 @@ function RendererApp(t0) {
70
68
  $[8] = t3;
71
69
  } else t3 = $[8];
72
70
  let t4;
73
- if ($[15] !== camoxApp || $[16] !== thumbnails) {
74
- let t5;
75
- if ($[18] !== camoxApp) {
76
- t5 = (t6) => {
77
- const { thumbnailId, slot, blockType } = t6;
78
- return createPortal(/* @__PURE__ */ jsx(RendererThumbnail, {
79
- slot,
80
- blockType,
81
- camoxApp
82
- }), slot, thumbnailId);
83
- };
84
- $[18] = camoxApp;
85
- $[19] = t5;
86
- } else t5 = $[19];
87
- t4 = thumbnails.map(t5);
88
- $[15] = camoxApp;
89
- $[16] = thumbnails;
71
+ if ($[15] !== t2 || $[16] !== t3) {
72
+ t4 = /* @__PURE__ */ jsx(StudioNoticeContext, {
73
+ value: t2,
74
+ children: t3
75
+ });
76
+ $[15] = t2;
77
+ $[16] = t3;
90
78
  $[17] = t4;
91
79
  } else t4 = $[17];
92
80
  let t5;
93
- if ($[20] !== t2 || $[21] !== t3 || $[22] !== t4) {
94
- t5 = /* @__PURE__ */ jsxs(StudioNoticeContext, {
95
- value: t2,
96
- children: [t3, t4]
97
- });
98
- $[20] = t2;
99
- $[21] = t3;
100
- $[22] = t4;
101
- $[23] = t5;
102
- } else t5 = $[23];
103
- let t6;
104
- if ($[24] !== connection.edit || $[25] !== t5) {
105
- t6 = /* @__PURE__ */ jsx(ContentEditsContext, {
81
+ if ($[18] !== connection.edit || $[19] !== t4) {
82
+ t5 = /* @__PURE__ */ jsx(ContentEditsContext, {
106
83
  value: t1,
107
- children: t5
84
+ children: t4
108
85
  });
109
- $[24] = connection.edit;
110
- $[25] = t5;
111
- $[26] = t6;
112
- } else t6 = $[26];
113
- return t6;
86
+ $[18] = connection.edit;
87
+ $[19] = t4;
88
+ $[20] = t5;
89
+ } else t5 = $[20];
90
+ return t5;
114
91
  }
115
92
  /**
116
93
  * The frames the studio gives the renderer to fill. Each change renders in a transition, so a
@@ -138,107 +115,6 @@ function useFrames(connection) {
138
115
  React.useEffect(t0, t1);
139
116
  return frames;
140
117
  }
141
- /** A block's thumbnail, rendered by the draft's code into its frame: nothing for a block it lacks. */
142
- function RendererThumbnail(t0) {
143
- const $ = c(17);
144
- const { slot, blockType, camoxApp } = t0;
145
- const frameWindow = slot.ownerDocument.defaultView;
146
- const left = useLeftInSlot(slot);
147
- const t1 = frameWindow?.frameElement ?? null;
148
- let t2;
149
- if ($[0] !== frameWindow || $[1] !== t1) {
150
- t2 = {
151
- window: frameWindow,
152
- iframeElement: t1
153
- };
154
- $[0] = frameWindow;
155
- $[1] = t1;
156
- $[2] = t2;
157
- } else t2 = $[2];
158
- const frameContext = t2;
159
- let t3;
160
- if ($[3] !== blockType || $[4] !== camoxApp) {
161
- t3 = /* @__PURE__ */ jsx(ThumbnailBlock, {
162
- blockType,
163
- camoxApp
164
- });
165
- $[3] = blockType;
166
- $[4] = camoxApp;
167
- $[5] = t3;
168
- } else t3 = $[5];
169
- let t4;
170
- if ($[6] !== left) {
171
- t4 = /* @__PURE__ */ jsx(RemovesLeft, { nodes: left });
172
- $[6] = left;
173
- $[7] = t4;
174
- } else t4 = $[7];
175
- let t5;
176
- if ($[8] !== t3 || $[9] !== t4) {
177
- t5 = /* @__PURE__ */ jsxs(React.Suspense, {
178
- fallback: null,
179
- children: [t3, t4]
180
- });
181
- $[8] = t3;
182
- $[9] = t4;
183
- $[10] = t5;
184
- } else t5 = $[10];
185
- let t6;
186
- if ($[11] !== left || $[12] !== t5) {
187
- t6 = /* @__PURE__ */ jsx(ThumbnailErrorBoundary, {
188
- left,
189
- children: t5
190
- });
191
- $[11] = left;
192
- $[12] = t5;
193
- $[13] = t6;
194
- } else t6 = $[13];
195
- let t7;
196
- if ($[14] !== frameContext || $[15] !== t6) {
197
- t7 = /* @__PURE__ */ jsx(NavigationProvider, {
198
- location: THUMBNAIL_LOCATION,
199
- navigate: noNavigation,
200
- children: /* @__PURE__ */ jsx(FrameContext.Provider, {
201
- value: frameContext,
202
- children: t6
203
- })
204
- });
205
- $[14] = frameContext;
206
- $[15] = t6;
207
- $[16] = t7;
208
- } else t7 = $[16];
209
- return t7;
210
- }
211
- const THUMBNAIL_LOCATION = {
212
- href: "",
213
- pathname: "/",
214
- search: "",
215
- hash: ""
216
- };
217
- const noNavigation = () => {};
218
- var ThumbnailErrorBoundary = class extends React.Component {
219
- state = { failed: false };
220
- static getDerivedStateFromError() {
221
- return { failed: true };
222
- }
223
- componentDidCatch(error) {
224
- console.error("Camox: a block's thumbnail failed to render.", error);
225
- }
226
- render() {
227
- return this.state.failed ? /* @__PURE__ */ jsx(RemovesLeft, { nodes: this.props.left }) : this.props.children;
228
- }
229
- };
230
- function ThumbnailBlock(t0) {
231
- const $ = c(2);
232
- const { blockType, camoxApp } = t0;
233
- const block = camoxApp.getBlockById(blockType) ?? (camoxApp.canLoadMoreBlocks() ? React.use(camoxApp.loadBlock(blockType)) : void 0);
234
- let t1;
235
- if ($[0] !== block) {
236
- t1 = block ? /* @__PURE__ */ jsx(BlockPeek, { block }) : null;
237
- $[0] = block;
238
- $[1] = t1;
239
- } else t1 = $[1];
240
- return t1;
241
- }
242
118
  /**
243
119
  * What another renderer document left in `slot`, read before this one renders into it. Each new
244
120
  * revision loads another renderer document, and removing the last one's frame never unmounts
@@ -1,15 +1,8 @@
1
1
  import { curatedLayoutContext } from "../../core/layoutContext.js";
2
2
 
3
3
  //#region src/features/renderer/definitionAnswers.ts
4
- /** The block of `type` in the draft's code, loading it if it is lazy. */
5
- async function blockOfCode(camoxApp, type) {
6
- const block = camoxApp.getBlockById(type);
7
- if (block || !camoxApp.canLoadMoreBlocks()) return block;
8
- return camoxApp.loadBlock(type);
9
- }
10
4
  async function answerFromCode(camoxApp, question) {
11
5
  switch (question.type) {
12
- case "initialBundle": return (await blockOfCode(camoxApp, question.blockType))?._internal.getInitialBundle() ?? null;
13
6
  case "prepareFrame": return null;
14
7
  case "pageTitle": {
15
8
  const layout = camoxApp.getLayoutById(question.layoutId);
@@ -24,4 +17,4 @@ async function answerFromCode(camoxApp, question) {
24
17
  }
25
18
 
26
19
  //#endregion
27
- export { answerFromCode, blockOfCode };
20
+ export { answerFromCode };
@@ -1,4 +1,3 @@
1
- import { referencePickerFocus } from "../preview/referencePickerFocus.js";
2
1
  import { canvasStore } from "../canvas/canvasStore.js";
3
2
  import { previewStore } from "../preview/previewStore.js";
4
3
  import { SDK_VERSION, deferredInbox } from "./protocol.js";
@@ -20,10 +19,7 @@ const storeMessages = {
20
19
  })
21
20
  };
22
21
  /** The stores the renderer forwards its events to, as the host applies them. */
23
- const forwarded = {
24
- preview: previewStore,
25
- referencePickerFocus
26
- };
22
+ const forwarded = { preview: previewStore };
27
23
  /** Applies an event the renderer forwarded to the studio's store. */
28
24
  const applyStoreEvent = (message) => {
29
25
  const store = forwarded[message.store];
@@ -43,7 +39,6 @@ function createRendererHost({ studioCache, draftScope, queryClient, notify } = {
43
39
  studioCache
44
40
  }) : void 0;
45
41
  const frames = /* @__PURE__ */ new Map();
46
- const thumbnails = /* @__PURE__ */ new Map();
47
42
  /** The questions asked that no renderer answered yet. */
48
43
  const asked = /* @__PURE__ */ new Map();
49
44
  let lastAskId = 0;
@@ -122,12 +117,6 @@ function createRendererHost({ studioCache, draftScope, queryClient, notify } = {
122
117
  slot,
123
118
  target
124
119
  });
125
- for (const [thumbnailId, { slot, blockType }] of thumbnails) post({
126
- type: "thumbnail",
127
- thumbnailId,
128
- slot,
129
- blockType
130
- });
131
120
  for (const [askId, { question }] of asked) post({
132
121
  type: "ask",
133
122
  askId,
@@ -213,25 +202,6 @@ function createRendererHost({ studioCache, draftScope, queryClient, notify } = {
213
202
  });
214
203
  });
215
204
  },
216
- showThumbnail(thumbnailId, slot, blockType) {
217
- thumbnails.set(thumbnailId, {
218
- slot,
219
- blockType
220
- });
221
- post({
222
- type: "thumbnail",
223
- thumbnailId,
224
- slot,
225
- blockType
226
- });
227
- },
228
- hideThumbnail(thumbnailId) {
229
- if (!thumbnails.delete(thumbnailId)) return;
230
- post({
231
- type: "thumbnailEnd",
232
- thumbnailId
233
- });
234
- },
235
205
  subscribe(listener) {
236
206
  connectionListeners.add(listener);
237
207
  return () => connectionListeners.delete(listener);
@@ -1,4 +1,3 @@
1
- import { referencePickerFocus } from "../preview/referencePickerFocus.js";
2
1
  import { canvasStore } from "../canvas/canvasStore.js";
3
2
  import { previewStore } from "../preview/previewStore.js";
4
3
  import { SDK_VERSION, deferredInbox } from "./protocol.js";
@@ -11,10 +10,7 @@ const mirrors = {
11
10
  canvas: canvasStore
12
11
  };
13
12
  /** The stores of this document whose events are forwarded to the studio's. */
14
- const forwards = {
15
- preview: previewStore,
16
- referencePickerFocus
17
- };
13
+ const forwards = { preview: previewStore };
18
14
  /** Has this document's copy of a mirrored store take the studio's state. */
19
15
  const mirror = (message) => mirrors[message.store]?.send({
20
16
  type: "mirror",
@@ -30,7 +26,6 @@ function connectToStudio(handle, { queryClient, studioCache, draftScope, camoxAp
30
26
  let welcomed = false;
31
27
  let frames = [];
32
28
  const listeners = /* @__PURE__ */ new Set();
33
- let thumbnails = [];
34
29
  const changed = () => {
35
30
  for (const listener of listeners) listener();
36
31
  };
@@ -38,10 +33,6 @@ function connectToStudio(handle, { queryClient, studioCache, draftScope, camoxAp
38
33
  frames = next;
39
34
  changed();
40
35
  };
41
- const setThumbnails = (next) => {
42
- thumbnails = next;
43
- changed();
44
- };
45
36
  /** The edits sent to the studio that it hasn't answered yet. */
46
37
  const editsInFlight = /* @__PURE__ */ new Map();
47
38
  let lastEditId = 0;
@@ -93,20 +84,6 @@ function connectToStudio(handle, { queryClient, studioCache, draftScope, camoxAp
93
84
  exact: true
94
85
  });
95
86
  return;
96
- case "thumbnail": {
97
- const { thumbnailId, slot, blockType } = message;
98
- const thumbnail = {
99
- thumbnailId,
100
- slot,
101
- blockType
102
- };
103
- const index = thumbnails.findIndex((shown) => shown.thumbnailId === thumbnailId);
104
- setThumbnails(index < 0 ? [...thumbnails, thumbnail] : thumbnails.map((shown, at) => at === index ? thumbnail : shown));
105
- return;
106
- }
107
- case "thumbnailEnd":
108
- setThumbnails(thumbnails.filter(({ thumbnailId }) => thumbnailId !== message.thumbnailId));
109
- return;
110
87
  case "ask": {
111
88
  const { askId, question } = message;
112
89
  if (question.type === "prepareFrame") {
@@ -165,7 +142,6 @@ function connectToStudio(handle, { queryClient, studioCache, draftScope, camoxAp
165
142
  return {
166
143
  connected: () => welcomed,
167
144
  frames: () => frames,
168
- thumbnails: () => thumbnails,
169
145
  subscribe(listener) {
170
146
  listeners.add(listener);
171
147
  return () => listeners.delete(listener);
@@ -157,13 +157,24 @@ function createServerStudioCache(queryClient, { apiUrl, authCookieHeader, lookTo
157
157
  }
158
158
  /**
159
159
  * The locales of the scope a request reads: the URL's draft's for a session naming one, else
160
- * Live's. A draft the API refuses reads Live's, as the request's other reads then do.
160
+ * Live's. A draft the API refuses reads Live's, as the request's other reads then do. Live's read
161
+ * keeps the session: a member's studio routes the locales Live doesn't serve yet, which visitors
162
+ * never see (ADR 0043), and a render with a session is private.
161
163
  */
162
164
  async function readScopeLocales({ apiUrl, authCookieHeader, draftId, projectUuid }) {
163
- const { value } = await readDraftOrLive(draftId, !!authCookieHeader, (readDraftId) => createServerApiClient(apiUrl, {
164
- authCookieHeader: readDraftId ? authCookieHeader : void 0,
165
+ const list = (session, readDraftId) => createServerApiClient(apiUrl, {
166
+ authCookieHeader: session,
165
167
  draftId: readDraftId
166
- }).locales.list({ projectUuid }));
168
+ }).locales.list({ projectUuid });
169
+ const { value } = await readDraftOrLive(draftId, !!authCookieHeader, async (readDraftId) => {
170
+ if (readDraftId || !authCookieHeader) return list(authCookieHeader, readDraftId);
171
+ try {
172
+ return await list(authCookieHeader, void 0);
173
+ } catch (error) {
174
+ if (!isAuthSessionError(error)) throw error;
175
+ return list(void 0, void 0);
176
+ }
177
+ });
167
178
  return value;
168
179
  }
169
180
  /**
@@ -0,0 +1,192 @@
1
+ import { useOptionalDraftScope } from "../../lib/draft-scope.js";
2
+ import { useAuthContext, useSignInRedirect } from "../../lib/auth.js";
3
+ import { getApiClient } from "../../lib/api-client.js";
4
+ import { c } from "react/compiler-runtime";
5
+ import * as React from "react";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { CLAIM_LINK_SEARCH_PARAM } from "@camox/api-contract/claim-links";
8
+
9
+ //#region src/features/runtime/ClaimCard.tsx
10
+ /** The page's URL without the Claim Link's token, which would reopen the card. */
11
+ function pageWithoutToken() {
12
+ const url = new URL(window.location.href);
13
+ url.searchParams.delete(CLAIM_LINK_SEARCH_PARAM);
14
+ return url.href;
15
+ }
16
+ /**
17
+ * The claim card, on a page opened from a Claim Link: who built the website for whom, with a
18
+ * button to claim it, or why it can't be claimed. A member of the website's organization sees it
19
+ * as a preview. Nothing shows without a token, or in a draft.
20
+ */
21
+ function ClaimCard() {
22
+ const $ = c(15);
23
+ const [token, setToken] = React.useState(null);
24
+ const [opening, setOpening] = React.useState(null);
25
+ const [closed, setClosed] = React.useState(false);
26
+ const { authenticationUrl } = useAuthContext();
27
+ const signIn = useSignInRedirect(pageWithoutToken);
28
+ const inDraft = useOptionalDraftScope().draftId !== null;
29
+ let t0;
30
+ let t1;
31
+ if ($[0] !== inDraft) {
32
+ t0 = () => {
33
+ if (inDraft) return;
34
+ const found = new URL(window.location.href).searchParams.get(CLAIM_LINK_SEARCH_PARAM);
35
+ if (!found) return;
36
+ setToken(found);
37
+ let current = true;
38
+ getApiClient().claimLinks.open({ token: found }).then((opened) => current && setOpening(opened), _temp);
39
+ return () => {
40
+ current = false;
41
+ };
42
+ };
43
+ t1 = [inDraft];
44
+ $[0] = inDraft;
45
+ $[1] = t0;
46
+ $[2] = t1;
47
+ } else {
48
+ t0 = $[1];
49
+ t1 = $[2];
50
+ }
51
+ React.useEffect(t0, t1);
52
+ if (inDraft || !token || !opening || closed) return null;
53
+ let t2;
54
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
55
+ t2 = () => {
56
+ window.history.replaceState(window.history.state, "", pageWithoutToken());
57
+ setClosed(true);
58
+ };
59
+ $[3] = t2;
60
+ } else t2 = $[3];
61
+ const close = t2;
62
+ let t3;
63
+ if ($[4] !== authenticationUrl || $[5] !== token) {
64
+ t3 = () => {
65
+ const destination = new URL("/claim", authenticationUrl);
66
+ destination.searchParams.set("token", token);
67
+ destination.searchParams.set("callback", pageWithoutToken());
68
+ window.location.href = destination.href;
69
+ };
70
+ $[4] = authenticationUrl;
71
+ $[5] = token;
72
+ $[6] = t3;
73
+ } else t3 = $[6];
74
+ const claim = t3;
75
+ let t4;
76
+ let t5;
77
+ if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
78
+ t4 = /* @__PURE__ */ jsx("style", { children: claimCardStyles });
79
+ t5 = /* @__PURE__ */ jsx("button", {
80
+ type: "button",
81
+ className: "camox-claim-close",
82
+ "aria-label": "Close",
83
+ onClick: close,
84
+ children: "×"
85
+ });
86
+ $[7] = t4;
87
+ $[8] = t5;
88
+ } else {
89
+ t4 = $[7];
90
+ t5 = $[8];
91
+ }
92
+ let t6;
93
+ if ($[9] !== claim || $[10] !== opening.operatorName || $[11] !== opening.organizationName || $[12] !== opening.state || $[13] !== signIn) {
94
+ t6 = /* @__PURE__ */ jsxs("aside", {
95
+ className: "camox-claim-card",
96
+ "aria-label": "Claim this website",
97
+ children: [
98
+ t4,
99
+ t5,
100
+ opening.state === "open" || opening.state === "preview" ? /* @__PURE__ */ jsxs(Fragment, { children: [
101
+ opening.state === "preview" && /* @__PURE__ */ jsx("span", {
102
+ className: "camox-claim-preview",
103
+ children: "Preview: this is the card whoever you send the link to sees"
104
+ }),
105
+ /* @__PURE__ */ jsxs("p", { children: [
106
+ opening.operatorName,
107
+ " from Camox built this website for ",
108
+ opening.organizationName,
109
+ ". Claim it to start editing."
110
+ ] }),
111
+ opening.state === "open" && /* @__PURE__ */ jsx("button", {
112
+ type: "button",
113
+ className: "camox-claim-action",
114
+ onClick: claim,
115
+ children: "Claim website"
116
+ })
117
+ ] }) : opening.state === "claimed" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", { children: "This website has been claimed." }), /* @__PURE__ */ jsx("button", {
118
+ type: "button",
119
+ className: "camox-claim-action",
120
+ onClick: signIn,
121
+ children: "Sign in"
122
+ })] }) : /* @__PURE__ */ jsx("p", { children: "This link no longer works. Ask whoever sent it for a new one." })
123
+ ]
124
+ });
125
+ $[9] = claim;
126
+ $[10] = opening.operatorName;
127
+ $[11] = opening.organizationName;
128
+ $[12] = opening.state;
129
+ $[13] = signIn;
130
+ $[14] = t6;
131
+ } else t6 = $[14];
132
+ return t6;
133
+ }
134
+ function _temp(error) {
135
+ return console.error("The Claim Link couldn't be opened", error);
136
+ }
137
+ const claimCardStyles = `
138
+ .camox-claim-card {
139
+ background: #09090b;
140
+ border: 1px solid #27272a;
141
+ border-radius: 12px;
142
+ bottom: 24px;
143
+ box-shadow: 0 10px 30px rgb(0 0 0 / 0.35);
144
+ box-sizing: border-box;
145
+ color: #fafafa;
146
+ color-scheme: dark;
147
+ display: flex;
148
+ flex-direction: column;
149
+ font: 15px/1.5 Inter, ui-sans-serif, system-ui, sans-serif;
150
+ gap: 12px;
151
+ max-width: min(24rem, calc(100vw - 32px));
152
+ padding: 20px 44px 20px 20px;
153
+ position: fixed;
154
+ right: 16px;
155
+ text-align: left;
156
+ z-index: 2147483647;
157
+ }
158
+ .camox-claim-card p { margin: 0; }
159
+ .camox-claim-card button { cursor: pointer; font: inherit; }
160
+ .camox-claim-card .camox-claim-close {
161
+ background: none;
162
+ border: 0;
163
+ color: #a1a1aa;
164
+ font-size: 20px;
165
+ line-height: 1;
166
+ padding: 4px 8px;
167
+ position: absolute;
168
+ right: 8px;
169
+ top: 8px;
170
+ }
171
+ .camox-claim-card .camox-claim-close:hover { color: #fafafa; }
172
+ .camox-claim-card .camox-claim-preview {
173
+ align-self: flex-start;
174
+ background: #27272a;
175
+ border-radius: 999px;
176
+ color: #d4d4d8;
177
+ font-size: 12px;
178
+ padding: 2px 10px;
179
+ }
180
+ .camox-claim-card .camox-claim-action {
181
+ align-self: flex-start;
182
+ background: #fafafa;
183
+ border: 0;
184
+ border-radius: 8px;
185
+ color: #09090b;
186
+ font-weight: 600;
187
+ padding: 8px 14px;
188
+ }
189
+ `;
190
+
191
+ //#endregion
192
+ export { ClaimCard };
@@ -2,8 +2,8 @@ import { DraftScopeContext } from "../../lib/draft-scope.js";
2
2
  import { useAuthState, useSignInRedirect } from "../../lib/auth.js";
3
3
  import { ArtifactCaptureContext } from "../../core/hooks/useArtifactHost.js";
4
4
  import { useSignInShortcut } from "../provider/signInShortcut.js";
5
- import { PreviewDocumentContext } from "./PreviewDocumentContext.js";
6
5
  import { PreviewActivation } from "../preview/components/PreviewActivation.js";
6
+ import { PreviewDocumentContext } from "./PreviewDocumentContext.js";
7
7
  import { Frame } from "../preview/components/Frame.js";
8
8
  import { PreviewSignInPage } from "../provider/PreviewSignInPage.js";
9
9
  import { CoreCamoxProvider } from "../provider/CoreCamoxProvider.js";
@@ -11,12 +11,13 @@ import { CuratedPageContent } from "../page/CuratedPageContent.js";
11
11
  import { DerivedPageContent } from "../page/DerivedPageContent.js";
12
12
  import { UnplacedBlockContent } from "../page/UnplacedBlockContent.js";
13
13
  import { UnplacedLayoutContent } from "../page/UnplacedLayoutContent.js";
14
+ import { ClaimCard } from "./ClaimCard.js";
14
15
  import { EditingFallbackSlot } from "./editingFallback.js";
15
16
  import { PageNavigationProvider } from "./pageNavigation.js";
16
17
  import { RuntimeChromeSlot } from "./runtimeChromeLoader.js";
17
18
  import { c } from "react/compiler-runtime";
18
19
  import * as React from "react";
19
- import { jsx, jsxs } from "react/jsx-runtime";
20
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
20
21
  import { HydrationBoundary, QueryClientProvider } from "@tanstack/react-query";
21
22
 
22
23
  //#region src/features/runtime/pageApp.tsx
@@ -43,12 +44,12 @@ function PageApp(t0) {
43
44
  camoxApp,
44
45
  input: currentInput
45
46
  })
46
- }) : /* @__PURE__ */ jsx(PageExperience, {
47
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(PageExperience, {
47
48
  camoxApp,
48
49
  input: currentInput,
49
50
  queryClient,
50
51
  studioDocument: input.presentation === "studio"
51
- })
52
+ }), /* @__PURE__ */ jsx(ClaimCard, {})] })
52
53
  })
53
54
  });
54
55
  $[0] = camoxApp;