camox 0.45.0 → 0.46.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/core/hooks/useArtifactHost.js +2 -2
- package/dist/features/canvas/CamoxCanvas.js +438 -771
- package/dist/features/canvas/CanvasPageFrame.js +1 -3
- package/dist/features/canvas/CanvasPreviewPageSlot.js +26 -6
- package/dist/features/canvas/canvasCamera.js +3 -3
- package/dist/features/canvas/canvasFrameDocument.js +4 -19
- package/dist/features/canvas/canvasItems.js +12 -102
- package/dist/features/canvas/canvasStore.js +3 -92
- package/dist/features/canvas/sidebar/CanvasNavigator.js +81 -183
- package/dist/features/canvas/sidebar/CanvasSidebar.js +22 -28
- package/dist/features/canvas/sidebar/CuratedPageInspector.js +2 -2
- package/dist/features/canvas/useCanvasCamera.js +0 -20
- package/dist/features/canvas/useCanvasFrame.js +5 -6
- package/dist/features/preview/CamoxPreview.js +3 -3
- package/dist/features/preview/components/{AddBlockDialog.js → AddBlockSheet.js} +35 -32
- package/dist/features/preview/components/BlockActionsPopover.js +6 -6
- package/dist/features/preview/components/BlockThumbnail.js +31 -33
- package/dist/features/preview/components/Overlays.js +1 -1
- package/dist/features/preview/components/PageTree.js +1 -1
- package/dist/features/preview/components/PreviewPanel.js +1 -1
- package/dist/features/preview/previewStore.js +9 -9
- package/dist/features/provider/CoreCamoxProvider.js +9 -6
- package/dist/features/routes/pageRuntime.js +8 -8
- package/dist/features/runtime/runtime.d.ts +2 -7
- package/dist/features/runtime/runtime.js +6 -19
- package/dist/features/studio/FollowAgentProvider.js +11 -22
- package/dist/features/studio/components/FaviconDialog.js +3 -3
- package/dist/features/studio/followAgent.js +5 -14
- package/dist/features/studio/routes.js +1 -23
- package/dist/lib/auth.js +36 -24
- package/dist/lib/studio-reads.js +0 -20
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +4 -4
- package/skills/camox-expand/SKILL.md +5 -4
- package/dist/features/canvas/CanvasBlockFrame.js +0 -353
- package/dist/features/canvas/CanvasBlockHeader.js +0 -55
- package/dist/features/canvas/CanvasShelfMarker.js +0 -255
- package/dist/features/canvas/sidebar/CatalogBlockInspector.js +0 -189
|
@@ -50,13 +50,13 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
|
|
|
50
50
|
const blockIndex = pageBlocks.findIndex((b) => b.id === block.id);
|
|
51
51
|
const afterPosition = blockIndex > 0 ? pageBlocks[blockIndex - 1].position : "";
|
|
52
52
|
previewStore.send({
|
|
53
|
-
type: "
|
|
53
|
+
type: "openAddBlockSheet",
|
|
54
54
|
afterPosition
|
|
55
55
|
});
|
|
56
56
|
};
|
|
57
57
|
const handleAddBlockBelow = (block) => {
|
|
58
58
|
previewStore.send({
|
|
59
|
-
type: "
|
|
59
|
+
type: "openAddBlockSheet",
|
|
60
60
|
afterPosition: block.position
|
|
61
61
|
});
|
|
62
62
|
};
|
|
@@ -104,7 +104,7 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
|
|
|
104
104
|
isLayoutBlock && layoutSlot === "before" && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(CommandGroup, { children: /* @__PURE__ */ jsx(CommandItem, {
|
|
105
105
|
onSelect: () => {
|
|
106
106
|
previewStore.send({
|
|
107
|
-
type: "
|
|
107
|
+
type: "openAddBlockSheet",
|
|
108
108
|
afterPosition: ""
|
|
109
109
|
});
|
|
110
110
|
onOpenChange(false);
|
|
@@ -118,7 +118,7 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
|
|
|
118
118
|
onSelect: () => {
|
|
119
119
|
const lastPageBlock = pageBlocks[pageBlocks.length - 1];
|
|
120
120
|
previewStore.send({
|
|
121
|
-
type: "
|
|
121
|
+
type: "openAddBlockSheet",
|
|
122
122
|
afterPosition: lastPageBlock?.position
|
|
123
123
|
});
|
|
124
124
|
onOpenChange(false);
|
|
@@ -419,7 +419,7 @@ function useBlockActionsShortcuts() {
|
|
|
419
419
|
const block_2 = pageBlocks.find((b_6) => b_6.id === sel_7.blockId);
|
|
420
420
|
if (!block_2) return;
|
|
421
421
|
previewStore.send({
|
|
422
|
-
type: "
|
|
422
|
+
type: "openAddBlockSheet",
|
|
423
423
|
afterPosition: block_2.position
|
|
424
424
|
});
|
|
425
425
|
}
|
|
@@ -444,7 +444,7 @@ function useBlockActionsShortcuts() {
|
|
|
444
444
|
if (blockIndex === -1) return;
|
|
445
445
|
const afterPosition_1 = blockIndex > 0 ? pageBlocks[blockIndex - 1].position : "";
|
|
446
446
|
previewStore.send({
|
|
447
|
-
type: "
|
|
447
|
+
type: "openAddBlockSheet",
|
|
448
448
|
afterPosition: afterPosition_1
|
|
449
449
|
});
|
|
450
450
|
}
|
|
@@ -27,6 +27,7 @@ const ThumbnailFrame = (t0) => {
|
|
|
27
27
|
$[1] = t1;
|
|
28
28
|
} else t1 = $[1];
|
|
29
29
|
const bundle = t1;
|
|
30
|
+
const initialization = React.useRef(0);
|
|
30
31
|
let t2;
|
|
31
32
|
if ($[2] !== frame?.contentDocument || $[3] !== sourceDocument) {
|
|
32
33
|
t2 = () => {
|
|
@@ -38,8 +39,15 @@ const ThumbnailFrame = (t0) => {
|
|
|
38
39
|
const base = doc.createElement("base");
|
|
39
40
|
base.href = source.baseURI;
|
|
40
41
|
doc.head.appendChild(base);
|
|
42
|
+
const stylesheetsLoaded = [];
|
|
41
43
|
source.querySelectorAll("style, link[rel=\"stylesheet\"]").forEach((style) => {
|
|
42
|
-
if (isSiteStyle(style))
|
|
44
|
+
if (!isSiteStyle(style)) return;
|
|
45
|
+
const clone = style.cloneNode(true);
|
|
46
|
+
if (clone.localName === "link") stylesheetsLoaded.push(new Promise((resolve) => {
|
|
47
|
+
clone.addEventListener("load", resolve, { once: true });
|
|
48
|
+
clone.addEventListener("error", resolve, { once: true });
|
|
49
|
+
}));
|
|
50
|
+
doc.head.appendChild(clone);
|
|
43
51
|
});
|
|
44
52
|
if (source !== document) for (const [from, to] of [
|
|
45
53
|
[source.documentElement, doc.documentElement],
|
|
@@ -53,7 +61,10 @@ const ThumbnailFrame = (t0) => {
|
|
|
53
61
|
reset.textContent = "\n html, body { margin: 0 !important; overflow: hidden !important; }\n *, *::before, *::after {\n animation: none !important;\n transition: none !important;\n caret-color: transparent !important;\n }\n ";
|
|
54
62
|
doc.head.appendChild(reset);
|
|
55
63
|
doc.body.setAttribute("inert", "");
|
|
56
|
-
|
|
64
|
+
const generation = initialization.current = initialization.current + 1;
|
|
65
|
+
Promise.all(stylesheetsLoaded).then(() => {
|
|
66
|
+
if (initialization.current === generation) setRoot(mount);
|
|
67
|
+
});
|
|
57
68
|
};
|
|
58
69
|
$[2] = frame?.contentDocument;
|
|
59
70
|
$[3] = sourceDocument;
|
|
@@ -185,12 +196,11 @@ const ThumbnailFrame = (t0) => {
|
|
|
185
196
|
return t14;
|
|
186
197
|
};
|
|
187
198
|
const BlockThumbnail = (t0) => {
|
|
188
|
-
const $ = c(
|
|
199
|
+
const $ = c(11);
|
|
189
200
|
const { block, className } = t0;
|
|
190
201
|
const ref = React.useRef(null);
|
|
191
202
|
const [isVisible, setIsVisible] = React.useState(false);
|
|
192
203
|
const [width, setWidth] = React.useState(0);
|
|
193
|
-
const checkerSize = 8 * (1 + width / VIEWPORT_WIDTH);
|
|
194
204
|
let t1;
|
|
195
205
|
let t2;
|
|
196
206
|
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
@@ -222,46 +232,34 @@ const BlockThumbnail = (t0) => {
|
|
|
222
232
|
React.useEffect(t1, t2);
|
|
223
233
|
let t3;
|
|
224
234
|
if ($[2] !== className) {
|
|
225
|
-
t3 = cn("
|
|
235
|
+
t3 = cn("bg-muted pointer-events-none relative flex h-28 w-full items-center overflow-hidden", className);
|
|
226
236
|
$[2] = className;
|
|
227
237
|
$[3] = t3;
|
|
228
238
|
} else t3 = $[3];
|
|
229
239
|
let t4;
|
|
230
|
-
if ($[4] !==
|
|
231
|
-
t4 = width > 0
|
|
232
|
-
backgroundSize: `${checkerSize * 2}px ${checkerSize * 2}px`,
|
|
233
|
-
backgroundPosition: `0 0, 0 ${checkerSize}px, ${checkerSize}px ${-checkerSize}px, ${-checkerSize}px 0`
|
|
234
|
-
} : void 0;
|
|
235
|
-
$[4] = checkerSize;
|
|
236
|
-
$[5] = width;
|
|
237
|
-
$[6] = t4;
|
|
238
|
-
} else t4 = $[6];
|
|
239
|
-
let t5;
|
|
240
|
-
if ($[7] !== block || $[8] !== isVisible || $[9] !== width) {
|
|
241
|
-
t5 = isVisible && width > 0 && /* @__PURE__ */ jsx(ThumbnailFrame, {
|
|
240
|
+
if ($[4] !== block || $[5] !== isVisible || $[6] !== width) {
|
|
241
|
+
t4 = isVisible && width > 0 && /* @__PURE__ */ jsx(ThumbnailFrame, {
|
|
242
242
|
block,
|
|
243
243
|
width
|
|
244
244
|
});
|
|
245
|
-
$[
|
|
246
|
-
$[
|
|
247
|
-
$[
|
|
248
|
-
$[
|
|
249
|
-
} else
|
|
250
|
-
let
|
|
251
|
-
if ($[
|
|
252
|
-
|
|
245
|
+
$[4] = block;
|
|
246
|
+
$[5] = isVisible;
|
|
247
|
+
$[6] = width;
|
|
248
|
+
$[7] = t4;
|
|
249
|
+
} else t4 = $[7];
|
|
250
|
+
let t5;
|
|
251
|
+
if ($[8] !== t3 || $[9] !== t4) {
|
|
252
|
+
t5 = /* @__PURE__ */ jsx("div", {
|
|
253
253
|
ref,
|
|
254
254
|
className: t3,
|
|
255
|
-
style: t4,
|
|
256
255
|
"aria-hidden": "true",
|
|
257
|
-
children:
|
|
256
|
+
children: t4
|
|
258
257
|
});
|
|
259
|
-
$[
|
|
260
|
-
$[
|
|
261
|
-
$[
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return t6;
|
|
258
|
+
$[8] = t3;
|
|
259
|
+
$[9] = t4;
|
|
260
|
+
$[10] = t5;
|
|
261
|
+
} else t5 = $[10];
|
|
262
|
+
return t5;
|
|
265
263
|
};
|
|
266
264
|
|
|
267
265
|
//#endregion
|
|
@@ -835,7 +835,7 @@ function _temp3(block_3) {
|
|
|
835
835
|
return /* @__PURE__ */ jsx(SortableBlock, { block: block_3 }, block_3.id);
|
|
836
836
|
}
|
|
837
837
|
function _temp4() {
|
|
838
|
-
previewStore.send({ type: "
|
|
838
|
+
previewStore.send({ type: "openAddBlockSheet" });
|
|
839
839
|
}
|
|
840
840
|
|
|
841
841
|
//#endregion
|
|
@@ -478,7 +478,7 @@ const PreviewPanel = (t0) => {
|
|
|
478
478
|
$[43] = t19;
|
|
479
479
|
} else t19 = $[43];
|
|
480
480
|
const t20 = !placed && "inset-0";
|
|
481
|
-
const t21 = underCanvas &&
|
|
481
|
+
const t21 = underCanvas && !placed && "invisible";
|
|
482
482
|
const t22 = device && "checkered flex items-center justify-center";
|
|
483
483
|
let t23;
|
|
484
484
|
if ($[44] !== t20 || $[45] !== t21 || $[46] !== t22) {
|
|
@@ -97,7 +97,7 @@ const selectIsCanvasShown = (state) => state.context.view === "canvas";
|
|
|
97
97
|
const initialPreviewContext = {
|
|
98
98
|
view: "preview",
|
|
99
99
|
isToolbarHidden: false,
|
|
100
|
-
|
|
100
|
+
addBlockSheet: null,
|
|
101
101
|
isCreatePageModalOpen: false,
|
|
102
102
|
editingPageId: null,
|
|
103
103
|
viewportMode: "full",
|
|
@@ -150,7 +150,7 @@ const previewStore = createStore({
|
|
|
150
150
|
return {
|
|
151
151
|
...context,
|
|
152
152
|
editingContext: owner ? targetContext(owner, null) : null,
|
|
153
|
-
|
|
153
|
+
addBlockSheet: null
|
|
154
154
|
};
|
|
155
155
|
},
|
|
156
156
|
activateLayout: (context, event) => {
|
|
@@ -162,7 +162,7 @@ const previewStore = createStore({
|
|
|
162
162
|
return {
|
|
163
163
|
...context,
|
|
164
164
|
editingContext: targetContext(owner, null),
|
|
165
|
-
|
|
165
|
+
addBlockSheet: null
|
|
166
166
|
};
|
|
167
167
|
},
|
|
168
168
|
selectTarget: (context, event) => ({
|
|
@@ -175,7 +175,7 @@ const previewStore = createStore({
|
|
|
175
175
|
type: "block",
|
|
176
176
|
blockId: event.blockId
|
|
177
177
|
}),
|
|
178
|
-
|
|
178
|
+
addBlockSheet: null
|
|
179
179
|
}),
|
|
180
180
|
selectItem: (context, event) => ({
|
|
181
181
|
...context,
|
|
@@ -312,13 +312,13 @@ const previewStore = createStore({
|
|
|
312
312
|
selection: null
|
|
313
313
|
} : null
|
|
314
314
|
}),
|
|
315
|
-
|
|
315
|
+
openAddBlockSheet: (context, event) => ({
|
|
316
316
|
...context,
|
|
317
|
-
|
|
317
|
+
addBlockSheet: { afterPosition: event.afterPosition }
|
|
318
318
|
}),
|
|
319
|
-
|
|
319
|
+
closeAddBlockSheet: (context) => ({
|
|
320
320
|
...context,
|
|
321
|
-
|
|
321
|
+
addBlockSheet: null
|
|
322
322
|
}),
|
|
323
323
|
focusCreatedBlock: (context, event) => ({
|
|
324
324
|
...context,
|
|
@@ -326,7 +326,7 @@ const previewStore = createStore({
|
|
|
326
326
|
type: "block",
|
|
327
327
|
blockId: event.blockId
|
|
328
328
|
}),
|
|
329
|
-
|
|
329
|
+
addBlockSheet: null
|
|
330
330
|
}),
|
|
331
331
|
openCreatePageModal: (context) => ({
|
|
332
332
|
...context,
|
|
@@ -42,23 +42,26 @@ function CoreCamoxProvider({ apiUrl, authenticationUrl, camoxApp, children, proj
|
|
|
42
42
|
if (!cached || replaceEqualDeep(cached, initialProject) !== cached) studioCache.set(read, initialProject);
|
|
43
43
|
seededProject.current = initialProject;
|
|
44
44
|
}
|
|
45
|
+
const { ready, error } = useProcessOtt(authClient, {
|
|
46
|
+
projectUuid,
|
|
47
|
+
apiUrl
|
|
48
|
+
}, initialAuthenticated);
|
|
49
|
+
const exchangingToken = !ready;
|
|
45
50
|
const authContext = React.useMemo(() => ({
|
|
46
51
|
authClient,
|
|
47
52
|
authenticationUrl,
|
|
48
53
|
apiUrl,
|
|
49
54
|
projectUuid,
|
|
50
|
-
initialAuthenticated
|
|
55
|
+
initialAuthenticated,
|
|
56
|
+
exchangingToken
|
|
51
57
|
}), [
|
|
52
58
|
authClient,
|
|
53
59
|
authenticationUrl,
|
|
54
60
|
apiUrl,
|
|
55
61
|
projectUuid,
|
|
56
|
-
initialAuthenticated
|
|
62
|
+
initialAuthenticated,
|
|
63
|
+
exchangingToken
|
|
57
64
|
]);
|
|
58
|
-
const { ready, error } = useProcessOtt(authClient, {
|
|
59
|
-
projectUuid,
|
|
60
|
-
apiUrl
|
|
61
|
-
}, initialAuthenticated);
|
|
62
65
|
const [isPreviewHandoff, setIsPreviewHandoff] = React.useState(false);
|
|
63
66
|
React.useEffect(() => {
|
|
64
67
|
setIsPreviewHandoff(new URL(window.location.href).searchParams.has("camox-preview"));
|
|
@@ -174,16 +174,16 @@ async function resolveMemberProject({ apiUrl, authCookieHeader, projectUuid }) {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
/**
|
|
177
|
-
* The project's favicon, which falls back to the
|
|
178
|
-
* `
|
|
177
|
+
* The project's favicon, which falls back to the default favicon when none was uploaded.
|
|
178
|
+
* Pass `withDefault: false` to get a 404 instead, to learn whether there is one.
|
|
179
179
|
*/
|
|
180
|
-
function buildFaviconUrl(apiUrl, project, {
|
|
180
|
+
function buildFaviconUrl(apiUrl, project, { withDefault = true } = {}) {
|
|
181
181
|
const url = `${apiUrl}/favicons/${project.id}?v=${project.updatedAt}`;
|
|
182
|
-
return
|
|
182
|
+
return withDefault ? `${url}&default=camox` : url;
|
|
183
183
|
}
|
|
184
|
-
/** The
|
|
185
|
-
function
|
|
186
|
-
return `${apiUrl}/favicons/
|
|
184
|
+
/** The default favicon, shown by a project without its own. */
|
|
185
|
+
function buildDefaultFaviconUrl(apiUrl) {
|
|
186
|
+
return `${apiUrl}/favicons/default`;
|
|
187
187
|
}
|
|
188
188
|
function buildCamoxPageLoaderData(apiUrl, page, origin) {
|
|
189
189
|
return {
|
|
@@ -340,4 +340,4 @@ function buildCamoxPageHead(camoxApp, loaderData, locale) {
|
|
|
340
340
|
}
|
|
341
341
|
|
|
342
342
|
//#endregion
|
|
343
|
-
export { buildCamoxPageHead, buildCamoxPageLoaderData,
|
|
343
|
+
export { buildCamoxPageHead, buildCamoxPageLoaderData, buildDefaultFaviconUrl, buildFaviconUrl, buildPageHead, buildPageMeta, createMarkdownResponse, createServerApiClient, createServerStudioCache, getMarkdownPath, isAuthSessionError, isNotFoundError, loadCamoxPage, loadCamoxPageForRequest, parseMarkdownPath, parseQuality, prefersMarkdown, readDraftOrLive, readScopeLocales, renderedHref, resolveMemberProject, withFrontMatter };
|
|
@@ -33,13 +33,8 @@ export interface PageRenderInput extends DraftRead {
|
|
|
33
33
|
previewHandoff?: boolean;
|
|
34
34
|
previewDocument?: string;
|
|
35
35
|
routeKind?: "studio" | "studio-content" | "studio-nested";
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
* with nothing selected, or with a block of the Block Catalog selected.
|
|
39
|
-
*/
|
|
40
|
-
canvasOnly?: {
|
|
41
|
-
blockId?: string;
|
|
42
|
-
};
|
|
36
|
+
/** Whether the location is the Canvas with nothing selected, which only the Canvas shows. */
|
|
37
|
+
canvasOnly?: boolean;
|
|
43
38
|
project?: MemberProject;
|
|
44
39
|
presentation?: "public" | "studio";
|
|
45
40
|
derived?: {
|
|
@@ -7,7 +7,7 @@ import { RUNTIME_ROUTE_PATHS, matchRuntimeOwnedRoute } from "./runtimeRoutes.js"
|
|
|
7
7
|
import { reads } from "../../lib/studio-reads.js";
|
|
8
8
|
import { asCollectionItem, recordMarkdownTemplate, recordPlainText } from "../../core/recordItem.js";
|
|
9
9
|
import { PLATFORM_SCRIPT } from "../../lib/platform.js";
|
|
10
|
-
import { STUDIO_ASSETS_PATH,
|
|
10
|
+
import { STUDIO_ASSETS_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH, matchCollectionContentPath } from "../studio/routes.js";
|
|
11
11
|
import { STUDIO_THEME_SCRIPT } from "../studio/studioTheme.js";
|
|
12
12
|
import { discoverLayoutPages, matchDerivedLayout } from "../../core/derivedRoutes.js";
|
|
13
13
|
import { buildCamoxPageHead, buildFaviconUrl, buildPageHead, buildPageMeta, createMarkdownResponse, createServerApiClient, createServerStudioCache, isNotFoundError, loadCamoxPageForRequest, parseMarkdownPath, prefersMarkdown, readDraftOrLive, readScopeLocales, renderedHref, resolveMemberProject, withFrontMatter } from "../routes/pageRuntime.js";
|
|
@@ -76,7 +76,7 @@ function matchRuntimeRoute(pathname) {
|
|
|
76
76
|
kind: "studio",
|
|
77
77
|
pathname
|
|
78
78
|
};
|
|
79
|
-
if (
|
|
79
|
+
if (pathname === "/camox/canvas") return {
|
|
80
80
|
kind: "canvas",
|
|
81
81
|
pathname
|
|
82
82
|
};
|
|
@@ -872,22 +872,10 @@ ${renderClientEntryScript(options.studioClientEntryUrl)}
|
|
|
872
872
|
} });
|
|
873
873
|
}
|
|
874
874
|
/**
|
|
875
|
-
* The Canvas with nothing selected
|
|
876
|
-
*
|
|
877
|
-
* without a page-content block of that id redirects home.
|
|
875
|
+
* The Canvas with nothing selected renders the page app, like a Page, so
|
|
876
|
+
* selecting it keeps the Canvas mounted.
|
|
878
877
|
*/
|
|
879
878
|
async function createCanvasOnlyResponse({ options, pathname, located, request, dataOnly = false }) {
|
|
880
|
-
const { blockId } = matchCanvasOnlyPath(located.path);
|
|
881
|
-
const app = blockId ? await options.getCamoxApp?.() : void 0;
|
|
882
|
-
const block = blockId ? app?.getBlockById(blockId) : void 0;
|
|
883
|
-
if (blockId && (!block || block._internal.layoutOnly)) {
|
|
884
|
-
if (dataOnly) return Response.json({
|
|
885
|
-
kind: "canvas",
|
|
886
|
-
message: "No block of the Block Catalog on this path",
|
|
887
|
-
pathname
|
|
888
|
-
}, { status: 404 });
|
|
889
|
-
return Response.redirect(new URL(withRuntimeBasePath(localizedPath("/", located.locale), options.runtimeBasePath), request.url), 302);
|
|
890
|
-
}
|
|
891
879
|
if (!options.apiUrl || !options.authenticationUrl || !options.projectUuid || !dataOnly && !options.renderPage) return Response.json({
|
|
892
880
|
message: "Camox page renderer is not configured.",
|
|
893
881
|
kind: "canvas",
|
|
@@ -895,7 +883,7 @@ async function createCanvasOnlyResponse({ options, pathname, located, request, d
|
|
|
895
883
|
}, { status: 500 });
|
|
896
884
|
const { project, clearAuthCookie } = await resolveRequestMember(request, options);
|
|
897
885
|
const studio = project !== void 0;
|
|
898
|
-
const title =
|
|
886
|
+
const title = "Canvas";
|
|
899
887
|
const input = {
|
|
900
888
|
project,
|
|
901
889
|
presentation: studio ? "studio" : "public",
|
|
@@ -911,10 +899,9 @@ async function createCanvasOnlyResponse({ options, pathname, located, request, d
|
|
|
911
899
|
layoutIdentity: null,
|
|
912
900
|
loaderData: null,
|
|
913
901
|
dehydratedState: dehydrate(new QueryClient()),
|
|
914
|
-
canvasOnly:
|
|
902
|
+
canvasOnly: true,
|
|
915
903
|
draftId: studio ? getRequestDraftId(request, options) : void 0
|
|
916
904
|
};
|
|
917
|
-
await preparePreviewDocument(input, options, await options.getDocument?.() ?? {}, "");
|
|
918
905
|
const headers = {
|
|
919
906
|
"Cache-Control": "private, no-store",
|
|
920
907
|
Vary: "Cookie",
|
|
@@ -4,8 +4,6 @@ import { useViewLocale } from "../../lib/view-locale-context.js";
|
|
|
4
4
|
import { useLocation, useNavigate } from "../navigation/navigation.js";
|
|
5
5
|
import { useCamoxApp } from "../provider/components/CamoxAppContext.js";
|
|
6
6
|
import { reads, useReadQueries, useReadQuery } from "../../lib/studio-reads.js";
|
|
7
|
-
import { useLocalizedPath } from "../../lib/view-locale.js";
|
|
8
|
-
import { blockCatalogPath } from "./routes.js";
|
|
9
7
|
import { FollowAgentContext } from "./followAgentContext.js";
|
|
10
8
|
import { canvasPageId, getCanvasPages } from "../canvas/canvasPages.js";
|
|
11
9
|
import { selectedCanvasPage } from "../canvas/canvasSelection.js";
|
|
@@ -103,12 +101,11 @@ function _temp(id) {
|
|
|
103
101
|
}
|
|
104
102
|
/** Where the editor is, and the Studio content following locates the agent's touches with. */
|
|
105
103
|
function useFollowWhere(runtimeBasePath) {
|
|
106
|
-
const $ = c(
|
|
104
|
+
const $ = c(35);
|
|
107
105
|
const app = useCamoxApp();
|
|
108
106
|
const projectUuid = useProjectUuid();
|
|
109
107
|
const location = useLocation();
|
|
110
108
|
const { locale, locales } = useViewLocale();
|
|
111
|
-
const localized = useLocalizedPath();
|
|
112
109
|
let t0;
|
|
113
110
|
if ($[0] !== projectUuid) {
|
|
114
111
|
t0 = reads.project({ projectUuid });
|
|
@@ -211,28 +208,20 @@ function useFollowWhere(runtimeBasePath) {
|
|
|
211
208
|
} else t9 = $[29];
|
|
212
209
|
const t10 = current?.key ?? null;
|
|
213
210
|
let t11;
|
|
214
|
-
if ($[30] !==
|
|
215
|
-
t11 =
|
|
216
|
-
$[30] = localized;
|
|
217
|
-
$[31] = t11;
|
|
218
|
-
} else t11 = $[31];
|
|
219
|
-
let t12;
|
|
220
|
-
if ($[32] !== locale.tag || $[33] !== pages || $[34] !== t10 || $[35] !== t11 || $[36] !== t9) {
|
|
221
|
-
t12 = {
|
|
211
|
+
if ($[30] !== locale.tag || $[31] !== pages || $[32] !== t10 || $[33] !== t9) {
|
|
212
|
+
t11 = {
|
|
222
213
|
pages,
|
|
223
214
|
locale: locale.tag,
|
|
224
215
|
location: t9,
|
|
225
|
-
pageKey: t10
|
|
226
|
-
blockCatalogPath: t11
|
|
216
|
+
pageKey: t10
|
|
227
217
|
};
|
|
228
|
-
$[
|
|
229
|
-
$[
|
|
230
|
-
$[
|
|
231
|
-
$[
|
|
232
|
-
$[
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
return t12;
|
|
218
|
+
$[30] = locale.tag;
|
|
219
|
+
$[31] = pages;
|
|
220
|
+
$[32] = t10;
|
|
221
|
+
$[33] = t9;
|
|
222
|
+
$[34] = t11;
|
|
223
|
+
} else t11 = $[34];
|
|
224
|
+
return t11;
|
|
236
225
|
}
|
|
237
226
|
function _temp2(page) {
|
|
238
227
|
return [page.id, page.layoutId];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getApiUrl } from "../../../lib/api-client.js";
|
|
2
2
|
import { reads, useStudioCache } from "../../../lib/studio-reads.js";
|
|
3
3
|
import { projectMutations } from "../../../lib/queries.js";
|
|
4
|
-
import {
|
|
4
|
+
import { buildDefaultFaviconUrl, buildFaviconUrl } from "../../routes/pageRuntime.js";
|
|
5
5
|
import { c } from "react/compiler-runtime";
|
|
6
6
|
import * as React from "react";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -63,7 +63,7 @@ function FaviconForm(t0) {
|
|
|
63
63
|
const [hasCurrent, setHasCurrent] = React.useState(false);
|
|
64
64
|
let t1;
|
|
65
65
|
if ($[0] !== project) {
|
|
66
|
-
t1 = buildFaviconUrl(getApiUrl(), project, {
|
|
66
|
+
t1 = buildFaviconUrl(getApiUrl(), project, { withDefault: false });
|
|
67
67
|
$[0] = project;
|
|
68
68
|
$[1] = t1;
|
|
69
69
|
} else t1 = $[1];
|
|
@@ -202,7 +202,7 @@ function FaviconForm(t0) {
|
|
|
202
202
|
const showsFavicon = pending ? pending.type === "upload" : hasCurrent;
|
|
203
203
|
let t14;
|
|
204
204
|
if ($[27] !== currentUrl || $[28] !== pendingUrl || $[29] !== showsFavicon) {
|
|
205
|
-
t14 = pendingUrl ?? (showsFavicon ? currentUrl :
|
|
205
|
+
t14 = pendingUrl ?? (showsFavicon ? currentUrl : buildDefaultFaviconUrl(getApiUrl()));
|
|
206
206
|
$[27] = currentUrl;
|
|
207
207
|
$[28] = pendingUrl;
|
|
208
208
|
$[29] = showsFavicon;
|
|
@@ -34,8 +34,7 @@ function locate(where, here, touch) {
|
|
|
34
34
|
return page ? at({ key: page.key }, touch.blockId) : null;
|
|
35
35
|
}
|
|
36
36
|
const placement = here?.blocks?.find((block) => block.type === touch.blockType);
|
|
37
|
-
|
|
38
|
-
return elsewhere ? null : { catalog: touch.blockType };
|
|
37
|
+
return here && placement ? at({ key: here.key }, placement.id) : null;
|
|
39
38
|
}
|
|
40
39
|
function destinationOf(where, batch) {
|
|
41
40
|
const here = currentPage(where);
|
|
@@ -50,7 +49,6 @@ function destinationOf(where, batch) {
|
|
|
50
49
|
return page ? `key:${page.key}` : refKey(ref);
|
|
51
50
|
};
|
|
52
51
|
for (const at of located) {
|
|
53
|
-
if ("catalog" in at) continue;
|
|
54
52
|
const key = identity(at.page);
|
|
55
53
|
const entry = touched.get(key) ?? {
|
|
56
54
|
page: at.page,
|
|
@@ -61,13 +59,7 @@ function destinationOf(where, batch) {
|
|
|
61
59
|
if (at.blockId && !entry.blockIds.includes(at.blockId)) entry.blockIds.push(at.blockId);
|
|
62
60
|
touched.set(key, entry);
|
|
63
61
|
}
|
|
64
|
-
if (touched.size === 0)
|
|
65
|
-
const catalog = located.find((at) => "catalog" in at);
|
|
66
|
-
return catalog && "catalog" in catalog ? {
|
|
67
|
-
kind: "catalog",
|
|
68
|
-
blockType: catalog.catalog
|
|
69
|
-
} : null;
|
|
70
|
-
}
|
|
62
|
+
if (touched.size === 0) return null;
|
|
71
63
|
const order = (ref) => {
|
|
72
64
|
const page = findPage(where, ref);
|
|
73
65
|
return page ? where.pages.indexOf(page) : where.pages.length;
|
|
@@ -75,7 +67,6 @@ function destinationOf(where, batch) {
|
|
|
75
67
|
const entries = [...touched.values()];
|
|
76
68
|
const chosen = (here && touched.get(`key:${here.key}`)) ?? entries.reduce((best, entry) => entry.count > best.count || entry.count === best.count && order(entry.page) < order(best.page) ? entry : best);
|
|
77
69
|
return {
|
|
78
|
-
kind: "page",
|
|
79
70
|
page: chosen.page,
|
|
80
71
|
blockIds: chosen.blockIds
|
|
81
72
|
};
|
|
@@ -169,11 +160,11 @@ function createFollowAgent({ navigate, where: initial }) {
|
|
|
169
160
|
return;
|
|
170
161
|
}
|
|
171
162
|
const destination = pendingNavigation;
|
|
172
|
-
const pathname =
|
|
163
|
+
const pathname = findPage(where, destination.page)?.pathname;
|
|
173
164
|
if (!pathname) return;
|
|
174
165
|
pendingNavigation = null;
|
|
175
166
|
arrivedAt = Date.now();
|
|
176
|
-
blocksToSelect = destination.
|
|
167
|
+
blocksToSelect = destination.blockIds.length ? destination : null;
|
|
177
168
|
selected = null;
|
|
178
169
|
navigate({
|
|
179
170
|
to: `${pathname}${where.location.search}`,
|
|
@@ -208,7 +199,7 @@ function createFollowAgent({ navigate, where: initial }) {
|
|
|
208
199
|
const destination = destinationOf(where, batch);
|
|
209
200
|
if (!destination) return;
|
|
210
201
|
const here = currentPage(where);
|
|
211
|
-
if (
|
|
202
|
+
if (here && findPage(where, destination.page) === here) {
|
|
212
203
|
pendingNavigation = null;
|
|
213
204
|
clearTimer();
|
|
214
205
|
if (!destination.blockIds.length) return;
|
|
@@ -27,28 +27,6 @@ function matchCollectionContentPath(pathname) {
|
|
|
27
27
|
}
|
|
28
28
|
/** The Studio URL of the Canvas with nothing selected. */
|
|
29
29
|
const STUDIO_CANVAS_PATH = `${STUDIO_BASE_PATH}/canvas`;
|
|
30
|
-
const STUDIO_BLOCKS_PATH = `${STUDIO_BASE_PATH}/blocks`;
|
|
31
|
-
/** The Studio URL of a block of the Block Catalog. */
|
|
32
|
-
const blockCatalogPath = (blockId) => `${STUDIO_BLOCKS_PATH}/${encodeURIComponent(blockId)}`;
|
|
33
|
-
/** The id of the Block Catalog block a pathname selects, if any. */
|
|
34
|
-
function matchBlockCatalogPath(pathname) {
|
|
35
|
-
const match = /^\/camox\/blocks\/([^/]+)$/.exec(pathname);
|
|
36
|
-
if (!match) return null;
|
|
37
|
-
try {
|
|
38
|
-
return decodeURIComponent(match[1]) || null;
|
|
39
|
-
} catch {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* A location that only exists on the Canvas: the Canvas with
|
|
45
|
-
* nothing selected, or a block of the Block Catalog.
|
|
46
|
-
*/
|
|
47
|
-
function matchCanvasOnlyPath(pathname) {
|
|
48
|
-
if (pathname === "/camox/canvas") return {};
|
|
49
|
-
const blockId = matchBlockCatalogPath(pathname);
|
|
50
|
-
return blockId ? { blockId } : null;
|
|
51
|
-
}
|
|
52
30
|
|
|
53
31
|
//#endregion
|
|
54
|
-
export { STUDIO_ASSETS_PATH, STUDIO_BASE_PATH,
|
|
32
|
+
export { STUDIO_ASSETS_PATH, STUDIO_BASE_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH, STUDIO_ROUTE_SEGMENT, collectionContentPath, matchCollectionContentPath };
|