@agent-native/core-corpus 0.216.0 → 0.218.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/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +61 -1
- package/corpus/templates/analytics/AGENTS.md +1 -1
- package/corpus/templates/analytics/CHANGELOG.md +3 -0
- package/corpus/templates/analytics/actions/get-session-replay-summary.ts +9 -65
- package/corpus/templates/analytics/actions/list-event-catalog.ts +1 -1
- package/corpus/templates/analytics/actions/list-session-outputs.ts +40 -0
- package/corpus/templates/analytics/actions/list-session-recordings.ts +17 -4
- package/corpus/templates/analytics/actions/view-screen.ts +29 -3
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +38 -167
- package/corpus/templates/analytics/app/i18n/en-US.ts +27 -0
- package/corpus/templates/analytics/app/pages/sessions/EventCatalogPage.tsx +18 -1
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +3 -1
- package/corpus/templates/analytics/app/pages/sessions/SessionOutputs.tsx +197 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionsTriagePage.tsx +114 -4
- package/corpus/templates/analytics/changelog/2026-10-15-sessions-can-find-people-who-made-a-slides-deck-but-didn-t-p.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-16-owned-and-shared-chats-appear-in-separate-history-sections.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-16-the-activation-funnel-counts-visitors-who-decline-analytics-.md +6 -0
- package/corpus/templates/analytics/server/db/schema.ts +67 -0
- package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +9 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +28 -22
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +36 -1
- package/corpus/templates/analytics/server/lib/output-outcomes.ts +712 -0
- package/corpus/templates/analytics/server/lib/replay-origins.ts +33 -0
- package/corpus/templates/analytics/server/lib/session-event-index.ts +20 -0
- package/corpus/templates/analytics/server/lib/session-performance.ts +6 -40
- package/corpus/templates/analytics/server/lib/session-recording-associations.ts +30 -1
- package/corpus/templates/analytics/server/lib/session-replay-triage.ts +99 -0
- package/corpus/templates/analytics/server/lib/session-replay.ts +45 -31
- package/corpus/templates/analytics/server/lib/sessions-triage-lab.ts +8 -2
- package/corpus/templates/analytics/server/plugins/db.ts +46 -0
- package/corpus/templates/analytics/shared/output-use.ts +205 -0
- package/corpus/templates/analytics/shared/session-events.ts +6 -0
- package/corpus/templates/assets/CHANGELOG.md +6 -0
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +51 -117
- package/corpus/templates/assets/changelog/2026-10-16-owned-and-shared-chats-appear-in-separate-history-sections.md +6 -0
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +34 -101
- package/corpus/templates/brain/app/routes/sources.tsx +1 -1
- package/corpus/templates/brain/vitest.config.ts +7 -0
- package/corpus/templates/calendar/CHANGELOG.md +12 -0
- package/corpus/templates/calendar/actions/create-event.ts +2 -4
- package/corpus/templates/calendar/actions/update-event.ts +35 -6
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-10-16-booking-links-show-localized-visibility-badges.md +6 -0
- package/corpus/templates/calendar/changelog/2026-10-21-solo-events-avoid-notification-approval.md +6 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +62 -101
- package/corpus/templates/clips/CHANGELOG.md +7 -20
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +20 -77
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +63 -90
- package/corpus/templates/clips/app/components/sharing/share-test-support.tsx +180 -0
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +5 -584
- package/corpus/templates/clips/changelog/2026-10-16-share-dialogs-make-it-easier-to-see-who-has-access-and-manag.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-21-share-panels-describe-general-access-in-a-sentence.md +6 -0
- package/corpus/templates/community/qr/package.json +1 -1
- package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +6 -3
- package/corpus/templates/content/CHANGELOG.md +10 -0
- package/corpus/templates/content/actions/_browser-document-save-attempt.ts +23 -1
- package/corpus/templates/content/actions/_builder-cms-blob-custody.ts +467 -0
- package/corpus/templates/content/actions/_builder-cms-execution-lease.ts +17 -0
- package/corpus/templates/content/actions/_builder-cms-intent-lookup.ts +5 -0
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +881 -21
- package/corpus/templates/content/actions/_builder-cms-write-adapter.ts +28 -2
- package/corpus/templates/content/actions/_builder-cms-write-client.ts +109 -11
- package/corpus/templates/content/actions/_builder-docs-client.ts +1 -0
- package/corpus/templates/content/actions/_builder-private-blob.test-fixture.ts +90 -0
- package/corpus/templates/content/actions/_builder-source-execution-guard.ts +48 -0
- package/corpus/templates/content/actions/_content-save-outcomes.ts +5 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +290 -8
- package/corpus/templates/content/actions/_database-utils.ts +93 -7
- package/corpus/templates/content/actions/_database-view-setup.ts +21 -2
- package/corpus/templates/content/actions/_delete-content-space.ts +8 -1
- package/corpus/templates/content/actions/_github-source-freshness.ts +30 -4
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +23 -6
- package/corpus/templates/content/actions/cancel-prepared-builder-source-update.ts +110 -26
- package/corpus/templates/content/actions/change-content-database-source-role.ts +51 -7
- package/corpus/templates/content/actions/delete-document.ts +41 -3
- package/corpus/templates/content/actions/disconnect-content-database-source.ts +68 -2
- package/corpus/templates/content/actions/disconnect-local-folder-source.ts +33 -2
- package/corpus/templates/content/actions/execute-builder-source-execution.ts +900 -140
- package/corpus/templates/content/actions/get-document.ts +2 -0
- package/corpus/templates/content/actions/permanently-delete-document.ts +6 -0
- package/corpus/templates/content/actions/prepare-builder-source-execution.ts +155 -13
- package/corpus/templates/content/actions/prepare-builder-source-review.ts +299 -73
- package/corpus/templates/content/actions/set-live-body-switch.ts +45 -0
- package/corpus/templates/content/actions/update-document.ts +139 -20
- package/corpus/templates/content/actions/validate-builder-source-execution.ts +135 -26
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +119 -30
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +56 -13
- package/corpus/templates/content/app/components/editor/SuggestionText.tsx +18 -3
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +89 -22
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +23 -0
- package/corpus/templates/content/app/components/editor/database/GitHubSourceStatusLine.tsx +27 -2
- package/corpus/templates/content/app/components/editor/database/ListItemLayout.tsx +32 -8
- package/corpus/templates/content/app/components/editor/database/ListItemRow.tsx +27 -2
- package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +1 -0
- package/corpus/templates/content/app/components/editor/extensions/SuggestionHighlight.ts +383 -34
- package/corpus/templates/content/app/components/editor/suggestions/draft-session.ts +31 -0
- package/corpus/templates/content/app/components/editor/suggestions/presentation-rebase.ts +82 -4
- package/corpus/templates/content/app/global.css +31 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +40 -2
- package/corpus/templates/content/app/hooks/use-documents.ts +14 -0
- package/corpus/templates/content/app/i18n-data.ts +1 -0
- package/corpus/templates/content/changelog/2026-10-16-accepting-a-suggestion-on-a-page-that-changed-since-it-was-s.md +6 -0
- package/corpus/templates/content/changelog/2026-10-17-builder-content-avoids-retrying-a-write-when-builder-accepte.md +6 -0
- package/corpus/templates/content/changelog/2026-10-18-link-a-new-collection-to-a-github-folder-from-its-sources.md +1 -1
- package/corpus/templates/content/changelog/2026-10-20-builder-content-sync-keeps-read-and-write-status-accurate-wh.md +6 -0
- package/corpus/templates/content/changelog/2026-10-20-suggested-edits-that-add-remove-split-or-merge-paragraphs-li.md +6 -0
- package/corpus/templates/content/changelog/2026-10-21-list-rows-can-show-each-pages-first-lines.md +6 -0
- package/corpus/templates/content/changelog/2026-10-22-a-collection-linked-to-a-big-github-folder-fills-faster-and-p.md +6 -0
- package/corpus/templates/content/docs/product/capabilities/content.source.adapters.md +29 -0
- package/corpus/templates/content/parity/matrix.md +42 -42
- package/corpus/templates/content/parity/matrix.ts +3 -1
- package/corpus/templates/content/server/db/schema.ts +20 -0
- package/corpus/templates/content/server/lib/content-trash-purge.ts +15 -1
- package/corpus/templates/content/server/lib/live-body-writer.ts +138 -26
- package/corpus/templates/content/server/live-copy/binding.ts +31 -0
- package/corpus/templates/content/server/live-copy/bounded-task.d.ts +6 -0
- package/corpus/templates/content/server/live-copy/exec-db.ts +1 -0
- package/corpus/templates/content/server/live-copy/holds.ts +59 -0
- package/corpus/templates/content/server/live-copy/persist.ts +656 -0
- package/corpus/templates/content/server/live-copy/switch.ts +136 -0
- package/corpus/templates/content/server/live-copy/task-names.ts +4 -0
- package/corpus/templates/content/server/live-copy/tasks.ts +183 -0
- package/corpus/templates/content/server/live-copy/write-cause.ts +85 -0
- package/corpus/templates/content/server/live-copy/write.ts +85 -0
- package/corpus/templates/content/server/plugins/builder-private-payload-cleanup.ts +22 -0
- package/corpus/templates/content/server/plugins/collab.ts +3 -0
- package/corpus/templates/content/server/plugins/db.ts +28 -0
- package/corpus/templates/content/shared/api.ts +30 -1
- package/corpus/templates/content/shared/database-item-layout.ts +54 -22
- package/corpus/templates/content/shared/document-intent-merge.ts +16 -9
- package/corpus/templates/content/shared/og-description.ts +258 -36
- package/corpus/templates/content/shared/suggestion-diff.ts +23 -6
- package/corpus/templates/content/shared/suggestion-formatting.ts +44 -14
- package/corpus/templates/content/shared/suggestion-text.ts +20 -5
- package/corpus/templates/design/.agents/skills/design-templates/SKILL.md +5 -1
- package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +25 -4
- package/corpus/templates/design/CHANGELOG.md +5 -0
- package/corpus/templates/design/actions/get-getting-started.ts +53 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +10 -0
- package/corpus/templates/design/app/components/design/bridge/native-shader-runtime.bridge.ts +132 -79
- package/corpus/templates/design/app/components/design/bridge/native-source-provider.ts +268 -130
- package/corpus/templates/design/app/components/design/bridge/native-worker-scene-host.ts +122 -42
- package/corpus/templates/design/app/components/design/bridge/shader-runtime.bridge.ts +41 -4
- package/corpus/templates/design/app/components/design/design-canvas/text-content-change-result.ts +46 -12
- package/corpus/templates/design/app/components/home/DesignHomeLibrary.tsx +15 -8
- package/corpus/templates/design/app/components/layout/GettingStarted.tsx +50 -0
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +3 -0
- package/corpus/templates/design/app/components/templates/DesignTemplateGrid.tsx +163 -0
- package/corpus/templates/design/app/components/templates/DesignTemplateLibrary.tsx +65 -78
- package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +6 -2
- package/corpus/templates/design/app/global.css +6 -0
- package/corpus/templates/design/app/i18n/en-US.ts +17 -0
- package/corpus/templates/design/app/lib/canvas-load-outcome.ts +147 -0
- package/corpus/templates/design/app/lib/canvas-outcome-tracking.ts +531 -0
- package/corpus/templates/design/app/lib/canvas-style-kind.ts +50 -0
- package/corpus/templates/design/app/pages/DesignSystems.tsx +1 -1
- package/corpus/templates/design/app/pages/Index.tsx +28 -67
- package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +86 -29
- package/corpus/templates/design/app/pages/design-editor/commands/save-file-content.ts +38 -3
- package/corpus/templates/design/app/pages/design-editor/domains/use-editor-core.ts +9 -0
- package/corpus/templates/design/app/pages/design-editor/domains/use-editor-files-and-saving.ts +2 -0
- package/corpus/templates/design/changelog/2026-10-16-design-pages-use-localized-visibility-badges-and-a-shared-ow.md +6 -0
- package/corpus/templates/design/changelog/2026-10-21-a-getting-started-checklist-at-the-bottom-of-the-sidebar-tra.md +6 -0
- package/corpus/templates/design/changelog/2026-10-21-templates-now-open-a-read-only-preview-from-the-card-and-the.md +6 -0
- package/corpus/templates/design/changelog/2026-10-22-collapsed-shader-layers-no-longer-interrupt-other-shaders-on.md +6 -0
- package/corpus/templates/design/changelog/2026-10-22-shader-fills-keep-rendering-when-other-screen-content-cannot.md +6 -0
- package/corpus/templates/design/scripts/design-export-validation/export-baseline.json +24 -0
- package/corpus/templates/design/server/lib/getting-started.ts +267 -0
- package/corpus/templates/design/server/plugins/getting-started.ts +5 -0
- package/corpus/templates/design/shared/design-template-presets/analytics-dashboard.ts +127 -0
- package/corpus/templates/design/shared/design-template-presets/design-studio.ts +98 -0
- package/corpus/templates/design/shared/design-template-presets/messaging-app.ts +101 -0
- package/corpus/templates/design/shared/design-template-presets/project-tasks.ts +120 -0
- package/corpus/templates/design/shared/design-template-presets.ts +8 -0
- package/corpus/templates/dispatch/CHANGELOG.md +4 -0
- package/corpus/templates/dispatch/app/i18n-data.ts +75 -0
- package/corpus/templates/dispatch/changelog/2026-10-21-owned-and-shared-chats-appear-in-separate-history-sections.md +6 -0
- package/corpus/templates/factory/app/components/layout/Sidebar.tsx +34 -100
- package/corpus/templates/forms/app/pages/FormsListPage.tsx +1 -1
- package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/plan/CHANGELOG.md +6 -0
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +34 -109
- package/corpus/templates/plan/changelog/2026-10-16-owned-and-shared-chats-appear-in-separate-history-sections.md +6 -0
- package/corpus/templates/slides/CHANGELOG.md +7 -0
- package/corpus/templates/slides/actions/delete-deck.ts +7 -0
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -1
- package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +1 -1
- package/corpus/templates/slides/app/pages/Index.tsx +7 -2
- package/corpus/templates/slides/changelog/2026-10-16-deck-lists-use-the-shared-ownership-filter-and-visibility-ba.md +6 -0
- package/corpus/templates/slides/changelog/2026-10-21-connected-deck-deletion-requires-approval.md +6 -0
- package/corpus/templates/slides/scripts/edit-fidelity/client-action.ts +61 -0
- package/corpus/templates/slides/scripts/edit-fidelity/run.ts +10 -0
- package/package.json +1 -1
- package/corpus/templates/chat/app/lib/sidebar-thread-state.ts +0 -29
- package/corpus/templates/slides/app/components/deck/DeckFilterMenu.tsx +0 -83
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
createNativeSceneProvider,
|
|
31
31
|
cloneNativeTextFlow,
|
|
32
32
|
NativeSourceError,
|
|
33
|
+
NativeSourceCapabilityError,
|
|
33
34
|
nativeTargetOverflowInsets,
|
|
34
35
|
nativeTextFlowUsesDocumentFont,
|
|
35
36
|
paintNativeTextFlow,
|
|
@@ -50,6 +51,12 @@ import {
|
|
|
50
51
|
} from "./native-worker-protocol";
|
|
51
52
|
import { NativeWorkerSourceSnapshot } from "./native-worker-source-snapshot";
|
|
52
53
|
|
|
54
|
+
export class NativeWorkerSceneSourceError extends NativeSourceError {
|
|
55
|
+
constructor(readonly captureFailure: NativeSourceCapabilityError) {
|
|
56
|
+
super("worker-scene-source-unsupported", captureFailure.message);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
53
60
|
export type NativeWorkerSceneEntry = {
|
|
54
61
|
instance: EffectInstance;
|
|
55
62
|
definition: EffectDefinition;
|
|
@@ -147,6 +154,7 @@ type Publication = {
|
|
|
147
154
|
targetEpochs: Map<string, { source: number; authored: number }>;
|
|
148
155
|
rootRecords: readonly NativeSourceRecord[];
|
|
149
156
|
payloads: Map<string, { payload: string; definitionHash: string }>;
|
|
157
|
+
authoredPayloads: Map<string, { payload: string; definitionHash: string }>;
|
|
150
158
|
clockIdentity?: { origin: number | null; sourcePlaying: boolean };
|
|
151
159
|
};
|
|
152
160
|
|
|
@@ -216,13 +224,27 @@ export function nativeWorkerOutputSceneRecords(
|
|
|
216
224
|
return nativeWorkerOutputRecords(records, sizes);
|
|
217
225
|
}
|
|
218
226
|
|
|
227
|
+
function nativeWorkerTargetDrawable(
|
|
228
|
+
rect: Pick<DOMRect, "x" | "y" | "width" | "height">,
|
|
229
|
+
): boolean {
|
|
230
|
+
if (
|
|
231
|
+
![rect.x, rect.y, rect.width, rect.height].every(Number.isFinite) ||
|
|
232
|
+
rect.width < 0 ||
|
|
233
|
+
rect.height < 0
|
|
234
|
+
)
|
|
235
|
+
throw new NativeSourceError(
|
|
236
|
+
"worker-target-geometry-invalid",
|
|
237
|
+
"A native effect target has unavailable or oversized geometry.",
|
|
238
|
+
);
|
|
239
|
+
return rect.width > 0 && rect.height > 0;
|
|
240
|
+
}
|
|
241
|
+
|
|
219
242
|
function nativeWorkerTargetGeometry(
|
|
220
|
-
|
|
243
|
+
rect: DOMRect,
|
|
221
244
|
pixelRatio: number,
|
|
222
245
|
cssWidth: number,
|
|
223
246
|
cssHeight: number,
|
|
224
247
|
): { width: number; height: number; rect: NativeWorkerEffectTarget["rect"] } {
|
|
225
|
-
const rect = target.getBoundingClientRect();
|
|
226
248
|
const width = Math.max(1, Math.ceil(cssWidth * pixelRatio));
|
|
227
249
|
const height = Math.max(1, Math.ceil(cssHeight * pixelRatio));
|
|
228
250
|
if (
|
|
@@ -330,6 +352,8 @@ export class NativeWorkerSceneHost {
|
|
|
330
352
|
compact: boolean;
|
|
331
353
|
},
|
|
332
354
|
private readonly getClockOrigin?: () => number,
|
|
355
|
+
private readonly hasPresentationToRetire?: () => boolean,
|
|
356
|
+
private readonly beforeCommit?: () => void,
|
|
333
357
|
) {
|
|
334
358
|
const body = document.body;
|
|
335
359
|
if (!body)
|
|
@@ -451,26 +475,36 @@ export class NativeWorkerSceneHost {
|
|
|
451
475
|
this.targets.delete(id);
|
|
452
476
|
}
|
|
453
477
|
this.entries = [...entries];
|
|
454
|
-
for (const target of this.markedTargets) {
|
|
455
|
-
target.removeAttribute("data-an-native-fill-instance");
|
|
456
|
-
target.removeAttribute("data-an-native-layer-instance");
|
|
457
|
-
}
|
|
458
|
-
this.markedTargets.clear();
|
|
459
478
|
for (const entry of entries) {
|
|
460
479
|
const existing = this.targets.get(entry.instance.id);
|
|
461
480
|
if (existing) existing.entry = entry;
|
|
462
481
|
else this.targets.set(entry.instance.id, this.createTarget(entry));
|
|
463
482
|
}
|
|
483
|
+
this.restoreEntryMarkersAndVisibility();
|
|
484
|
+
this.requestUpdate();
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
private restoreEntryMarkersAndVisibility(): void {
|
|
488
|
+
for (const target of this.markedTargets) {
|
|
489
|
+
target.removeAttribute("data-an-native-fill-instance");
|
|
490
|
+
target.removeAttribute("data-an-native-layer-instance");
|
|
491
|
+
}
|
|
492
|
+
this.markedTargets.clear();
|
|
464
493
|
const topFill = new Map<Element, string>();
|
|
465
494
|
const topLayer = new Map<Element, string>();
|
|
466
|
-
for (const entry of entries) {
|
|
495
|
+
for (const entry of this.entries) {
|
|
467
496
|
if (entry.instance.placement === "fill")
|
|
468
497
|
topFill.set(entry.target, entry.instance.id);
|
|
469
498
|
if (entry.instance.placement === "layer")
|
|
470
499
|
topLayer.set(entry.target, entry.instance.id);
|
|
471
500
|
}
|
|
472
|
-
for (const entry of entries) {
|
|
473
|
-
const state = this.targets.get(entry.instance.id)
|
|
501
|
+
for (const entry of this.entries) {
|
|
502
|
+
const state = this.targets.get(entry.instance.id);
|
|
503
|
+
if (!state)
|
|
504
|
+
throw new NativeWorkerHostError(
|
|
505
|
+
"worker-instance-state-missing",
|
|
506
|
+
"A native worker instance is unavailable.",
|
|
507
|
+
);
|
|
474
508
|
this.markedTargets.add(entry.target);
|
|
475
509
|
if (topFill.get(entry.target) === entry.instance.id)
|
|
476
510
|
entry.target.setAttribute(
|
|
@@ -490,7 +524,6 @@ export class NativeWorkerSceneHost {
|
|
|
490
524
|
? "visible"
|
|
491
525
|
: "hidden";
|
|
492
526
|
}
|
|
493
|
-
this.requestUpdate();
|
|
494
527
|
}
|
|
495
528
|
|
|
496
529
|
setEntriesAndWait(
|
|
@@ -671,11 +704,13 @@ export class NativeWorkerSceneHost {
|
|
|
671
704
|
Math.abs(pixelRatio - committed.scene.pixelRatio) > 0.000001 ||
|
|
672
705
|
(committed.scene.frameRateTarget ?? 60) !== cadence.frameRateTarget ||
|
|
673
706
|
(committed.scene.compact ?? false) !== cadence.compact ||
|
|
674
|
-
this.entries.length !== committed.publication.
|
|
707
|
+
this.entries.length !== committed.publication.authoredPayloads.size
|
|
675
708
|
)
|
|
676
709
|
return null;
|
|
677
710
|
for (const entry of this.entries) {
|
|
678
|
-
const expected = committed.publication.
|
|
711
|
+
const expected = committed.publication.authoredPayloads.get(
|
|
712
|
+
entry.instance.id,
|
|
713
|
+
);
|
|
679
714
|
const epoch = committed.publication.targetEpochs.get(entry.instance.id);
|
|
680
715
|
const state = this.targets.get(entry.instance.id);
|
|
681
716
|
const target = committed.scene.targets.find(
|
|
@@ -689,11 +724,15 @@ export class NativeWorkerSceneHost {
|
|
|
689
724
|
!state ||
|
|
690
725
|
state.entry.target !== entry.target ||
|
|
691
726
|
state.provider.sourceEpoch?.() !== epoch.source ||
|
|
692
|
-
state.provider.authoredSourceEpoch?.() !== epoch.authored
|
|
693
|
-
!target
|
|
727
|
+
state.provider.authoredSourceEpoch?.() !== epoch.authored
|
|
694
728
|
)
|
|
695
729
|
return null;
|
|
696
730
|
const rect = entry.target.getBoundingClientRect();
|
|
731
|
+
if (!nativeWorkerTargetDrawable(rect)) {
|
|
732
|
+
if (target) return null;
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
if (!target) return null;
|
|
697
736
|
if (
|
|
698
737
|
Math.abs(rect.x - target.rect.x) > 0.001 ||
|
|
699
738
|
Math.abs(rect.y - target.rect.y) > 0.001 ||
|
|
@@ -811,12 +850,13 @@ export class NativeWorkerSceneHost {
|
|
|
811
850
|
}
|
|
812
851
|
|
|
813
852
|
private async updateLoop(): Promise<void> {
|
|
814
|
-
if (this.disposed || this.updating) return;
|
|
853
|
+
if (this.disposed || this.holdingLastFrame || this.updating) return;
|
|
815
854
|
this.updating = true;
|
|
816
855
|
try {
|
|
817
856
|
while (
|
|
818
857
|
this.dirty &&
|
|
819
858
|
!this.disposed &&
|
|
859
|
+
!this.holdingLastFrame &&
|
|
820
860
|
!this.capturingExport &&
|
|
821
861
|
this.visible
|
|
822
862
|
) {
|
|
@@ -824,6 +864,7 @@ export class NativeWorkerSceneHost {
|
|
|
824
864
|
try {
|
|
825
865
|
await this.sendSnapshot();
|
|
826
866
|
} catch (error) {
|
|
867
|
+
if (this.disposed || this.holdingLastFrame) return;
|
|
827
868
|
this.assetRevisions.clear();
|
|
828
869
|
this.onFailure(
|
|
829
870
|
error instanceof Error ? error : new Error(String(error)),
|
|
@@ -933,7 +974,16 @@ export class NativeWorkerSceneHost {
|
|
|
933
974
|
>();
|
|
934
975
|
const extents = new Map<string, NativeEffectExtentPlan>();
|
|
935
976
|
const previousByTarget = new Map<Element, string>();
|
|
936
|
-
|
|
977
|
+
const targetRects = new Map<HTMLElement | SVGSVGElement, DOMRect>();
|
|
978
|
+
const drawableEntries = this.entries.filter((entry) => {
|
|
979
|
+
let rect = targetRects.get(entry.target);
|
|
980
|
+
if (!rect) {
|
|
981
|
+
rect = entry.target.getBoundingClientRect();
|
|
982
|
+
targetRects.set(entry.target, rect);
|
|
983
|
+
}
|
|
984
|
+
return nativeWorkerTargetDrawable(rect);
|
|
985
|
+
});
|
|
986
|
+
for (const entry of drawableEntries) {
|
|
937
987
|
const state = this.targets.get(entry.instance.id);
|
|
938
988
|
if (!state || state.entry.target !== entry.target)
|
|
939
989
|
throw new NativeSourceError(
|
|
@@ -941,14 +991,14 @@ export class NativeWorkerSceneHost {
|
|
|
941
991
|
"A native worker target changed during scene capture.",
|
|
942
992
|
);
|
|
943
993
|
const layout = this.layout(entry.target);
|
|
944
|
-
const visible = entry.target
|
|
994
|
+
const visible = targetRects.get(entry.target)!;
|
|
945
995
|
const displayScale = Math.max(
|
|
946
996
|
visible.width / layout.width,
|
|
947
997
|
visible.height / layout.height,
|
|
948
998
|
);
|
|
949
999
|
const targetPixelRatio = pixelRatio * displayScale;
|
|
950
1000
|
const geometry = nativeWorkerTargetGeometry(
|
|
951
|
-
|
|
1001
|
+
visible,
|
|
952
1002
|
targetPixelRatio,
|
|
953
1003
|
layout.width,
|
|
954
1004
|
layout.height,
|
|
@@ -1212,13 +1262,13 @@ export class NativeWorkerSceneHost {
|
|
|
1212
1262
|
...(fillPhases ? { fillPhases } : {}),
|
|
1213
1263
|
});
|
|
1214
1264
|
}
|
|
1215
|
-
for (const entry of
|
|
1265
|
+
for (const entry of drawableEntries) {
|
|
1216
1266
|
if (entry.instance.placement !== "backdrop") continue;
|
|
1217
|
-
const owners =
|
|
1267
|
+
const owners = drawableEntries.filter(
|
|
1218
1268
|
(candidate, index) =>
|
|
1219
1269
|
(candidate.instance.placement === "layer" ||
|
|
1220
1270
|
(candidate.instance.placement === "fill" &&
|
|
1221
|
-
|
|
1271
|
+
drawableEntries.every(
|
|
1222
1272
|
(other, otherIndex) =>
|
|
1223
1273
|
otherIndex <= index ||
|
|
1224
1274
|
other.instance.placement !== "fill" ||
|
|
@@ -1337,10 +1387,17 @@ export class NativeWorkerSceneHost {
|
|
|
1337
1387
|
records,
|
|
1338
1388
|
);
|
|
1339
1389
|
}
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1390
|
+
let rawRootRecords: NativeSourceRecord[];
|
|
1391
|
+
try {
|
|
1392
|
+
rawRootRecords = await this.provider.readScene(
|
|
1393
|
+
undefined,
|
|
1394
|
+
"scene-presentation",
|
|
1395
|
+
);
|
|
1396
|
+
} catch (error) {
|
|
1397
|
+
if (!options && error instanceof NativeSourceCapabilityError)
|
|
1398
|
+
throw new NativeWorkerSceneSourceError(error);
|
|
1399
|
+
throw error;
|
|
1400
|
+
}
|
|
1344
1401
|
if (
|
|
1345
1402
|
this.provider.needsContinuousFrames() ||
|
|
1346
1403
|
(await this.provider.replaySafety(
|
|
@@ -1413,8 +1470,8 @@ export class NativeWorkerSceneHost {
|
|
|
1413
1470
|
compact: cadence.compact,
|
|
1414
1471
|
clock: this.snapshotClock(viewport, !!options, sourceClock),
|
|
1415
1472
|
requiredAssets,
|
|
1416
|
-
definitions: nativeWorkerDefinitions(
|
|
1417
|
-
instances:
|
|
1473
|
+
definitions: nativeWorkerDefinitions(drawableEntries),
|
|
1474
|
+
instances: drawableEntries.map((entry) => entry.instance),
|
|
1418
1475
|
targets: targetSnapshots,
|
|
1419
1476
|
records,
|
|
1420
1477
|
...(selected ? { backdropRecords: normalizedRootRecords } : {}),
|
|
@@ -1459,6 +1516,15 @@ export class NativeWorkerSceneHost {
|
|
|
1459
1516
|
),
|
|
1460
1517
|
rootRecords: rawRootRecords,
|
|
1461
1518
|
payloads: new Map(
|
|
1519
|
+
drawableEntries.map((entry) => [
|
|
1520
|
+
entry.instance.id,
|
|
1521
|
+
{
|
|
1522
|
+
payload: JSON.stringify(entry.instance),
|
|
1523
|
+
definitionHash: entry.definitionHash,
|
|
1524
|
+
},
|
|
1525
|
+
]),
|
|
1526
|
+
),
|
|
1527
|
+
authoredPayloads: new Map(
|
|
1462
1528
|
this.entries.map((entry) => [
|
|
1463
1529
|
entry.instance.id,
|
|
1464
1530
|
{
|
|
@@ -1716,16 +1782,18 @@ export class NativeWorkerSceneHost {
|
|
|
1716
1782
|
this.requestUpdate();
|
|
1717
1783
|
return;
|
|
1718
1784
|
}
|
|
1719
|
-
const
|
|
1785
|
+
const replacedPresentation = this.hasPresentationToRetire?.() === true;
|
|
1786
|
+
const cameraOnly =
|
|
1787
|
+
!replacedPresentation && this.canReuseCommittedPresentation(publication);
|
|
1788
|
+
const paintedChildren = new Set<Element>();
|
|
1789
|
+
const authoredOpacities = new Map<Element, string>();
|
|
1720
1790
|
if (!cameraOnly) {
|
|
1721
1791
|
const body = document.body;
|
|
1722
|
-
const paintedChildren = new Set<Element>();
|
|
1723
1792
|
for (const record of publication.rootRecords) {
|
|
1724
1793
|
const root = scenePaintRoot(record.node, body);
|
|
1725
1794
|
if (root && root !== this.canvas && !root.matches(OMIT_SCENE_CHILD))
|
|
1726
1795
|
paintedChildren.add(root);
|
|
1727
1796
|
}
|
|
1728
|
-
const authoredOpacities = new Map<Element, string>();
|
|
1729
1797
|
for (const child of paintedChildren) {
|
|
1730
1798
|
const opacity =
|
|
1731
1799
|
child.getAttribute("data-an-native-authored-opacity") ??
|
|
@@ -1747,6 +1815,10 @@ export class NativeWorkerSceneHost {
|
|
|
1747
1815
|
}
|
|
1748
1816
|
authoredOpacities.set(child, opacity);
|
|
1749
1817
|
}
|
|
1818
|
+
}
|
|
1819
|
+
this.beforeCommit?.();
|
|
1820
|
+
if (replacedPresentation) this.restoreEntryMarkersAndVisibility();
|
|
1821
|
+
if (!cameraOnly) {
|
|
1750
1822
|
for (const old of this.suppressed) {
|
|
1751
1823
|
if (paintedChildren.has(old)) continue;
|
|
1752
1824
|
old.removeAttribute("data-an-native-scene-suppressed");
|
|
@@ -1807,7 +1879,7 @@ export class NativeWorkerSceneHost {
|
|
|
1807
1879
|
});
|
|
1808
1880
|
if (drainCamera) this.requestUpdate();
|
|
1809
1881
|
for (const waiter of this.publicationWaiters) {
|
|
1810
|
-
const expected = publication.
|
|
1882
|
+
const expected = publication.authoredPayloads.get(waiter.instanceId);
|
|
1811
1883
|
const committedScene = this.committedSceneSnapshot;
|
|
1812
1884
|
if (
|
|
1813
1885
|
publication.generation < waiter.minimumGeneration ||
|
|
@@ -1835,6 +1907,7 @@ export class NativeWorkerSceneHost {
|
|
|
1835
1907
|
committed.targetEpochs !== publication.targetEpochs ||
|
|
1836
1908
|
committed.rootRecords !== publication.rootRecords ||
|
|
1837
1909
|
committed.payloads !== publication.payloads ||
|
|
1910
|
+
committed.authoredPayloads !== publication.authoredPayloads ||
|
|
1838
1911
|
this.canvas.style.visibility !== "visible" ||
|
|
1839
1912
|
!document.documentElement.hasAttribute("data-an-native-scene-managed")
|
|
1840
1913
|
)
|
|
@@ -1981,25 +2054,32 @@ export class NativeWorkerSceneHost {
|
|
|
1981
2054
|
scene.authoredEpoch === hiddenAuthoredEpoch &&
|
|
1982
2055
|
this.provider.sourceEpoch?.() === scene.sourceEpoch &&
|
|
1983
2056
|
this.provider.authoredSourceEpoch?.() === hiddenAuthoredEpoch &&
|
|
1984
|
-
|
|
1985
|
-
|
|
2057
|
+
this.entries.length === hiddenPayloads.length &&
|
|
2058
|
+
captured.publication.authoredPayloads.size === hiddenPayloads.length &&
|
|
1986
2059
|
!hiddenPayloads.some((expected, index) => {
|
|
1987
2060
|
const entry = this.entries[index];
|
|
1988
|
-
const target = scene.targets
|
|
1989
|
-
|
|
2061
|
+
const target = scene.targets.find(
|
|
2062
|
+
(item) => item.instanceId === expected.id,
|
|
2063
|
+
);
|
|
2064
|
+
const instance = scene.instances.find(
|
|
2065
|
+
(item) => item.id === expected.id,
|
|
2066
|
+
);
|
|
2067
|
+
const payload = captured.publication.authoredPayloads.get(
|
|
2068
|
+
expected.id,
|
|
2069
|
+
);
|
|
1990
2070
|
const provider = this.targets.get(expected.id)?.provider;
|
|
1991
2071
|
const capturedEpoch = captured.publication.targetEpochs.get(
|
|
1992
2072
|
expected.id,
|
|
1993
2073
|
);
|
|
1994
2074
|
return (
|
|
1995
2075
|
!entry ||
|
|
1996
|
-
!
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
target
|
|
2000
|
-
JSON.stringify(instance) !== expected.payload ||
|
|
2076
|
+
!payload ||
|
|
2077
|
+
payload.payload !== expected.payload ||
|
|
2078
|
+
payload.definitionHash !== expected.definitionHash ||
|
|
2079
|
+
!!target !== !!instance ||
|
|
2080
|
+
(instance && JSON.stringify(instance) !== expected.payload) ||
|
|
2001
2081
|
JSON.stringify(entry.instance) !== expected.payload ||
|
|
2002
|
-
target.definitionHash !== expected.definitionHash ||
|
|
2082
|
+
(target && target.definitionHash !== expected.definitionHash) ||
|
|
2003
2083
|
entry.definitionHash !== expected.definitionHash ||
|
|
2004
2084
|
!capturedEpoch ||
|
|
2005
2085
|
provider?.sourceEpoch?.() !== capturedEpoch.source ||
|
|
@@ -111,8 +111,12 @@
|
|
|
111
111
|
const registry: Record<string, AnShaderDef> = {};
|
|
112
112
|
const mounts: AnShaderMount[] = [];
|
|
113
113
|
let rafId: number | null = null;
|
|
114
|
+
let lastFrameTs: number | null = null;
|
|
114
115
|
let needsRender = false;
|
|
115
116
|
let scanTimer: ReturnType<typeof setTimeout> | null = null;
|
|
117
|
+
// How large the editor shows this document, from its zoom. Outside the
|
|
118
|
+
// editor nothing sends one, so standalone pages keep full resolution.
|
|
119
|
+
let viewScale = 1;
|
|
116
120
|
|
|
117
121
|
function nowMs(): number {
|
|
118
122
|
return W.performance && W.performance.now
|
|
@@ -420,9 +424,13 @@
|
|
|
420
424
|
const rect = el.getBoundingClientRect();
|
|
421
425
|
const wCss = Math.max(1, Math.round(rect.width));
|
|
422
426
|
const hCss = Math.max(1, Math.round(rect.height));
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
427
|
+
// Zoomed out, render at the on-screen size, but never below one canvas
|
|
428
|
+
// pixel per CSS pixel: presets size grain and halftone dots in canvas
|
|
429
|
+
// pixels, so this keeps them no coarser than a standard display shows.
|
|
430
|
+
const deviceRatio = Math.min(2, W.devicePixelRatio || 1);
|
|
431
|
+
const ratio = Math.max(Math.min(1, deviceRatio), deviceRatio * viewScale);
|
|
432
|
+
const wPx = Math.max(1, Math.round(wCss * ratio));
|
|
433
|
+
const hPx = Math.max(1, Math.round(hCss * ratio));
|
|
426
434
|
if (canvas.width !== wPx || canvas.height !== hPx) {
|
|
427
435
|
canvas.width = wPx;
|
|
428
436
|
canvas.height = hPx;
|
|
@@ -455,8 +463,18 @@
|
|
|
455
463
|
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
|
456
464
|
}
|
|
457
465
|
|
|
458
|
-
function frame(): void {
|
|
466
|
+
function frame(ts?: number): void {
|
|
459
467
|
rafId = null;
|
|
468
|
+
// On a board of several screens, Chromium can run each screen's
|
|
469
|
+
// animation-frame callbacks once per screen per display frame, all with
|
|
470
|
+
// the same timestamp. Draw on the first; the rest would repeat its pixels.
|
|
471
|
+
if (typeof ts === "number") {
|
|
472
|
+
if (ts === lastFrameTs) {
|
|
473
|
+
startLoop();
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
lastFrameTs = ts;
|
|
477
|
+
}
|
|
460
478
|
const t = (nowMs() - t0) / 1000;
|
|
461
479
|
const animate = !reducedMotion && !document.hidden;
|
|
462
480
|
for (let i = mounts.length - 1; i >= 0; i--) {
|
|
@@ -562,6 +580,25 @@
|
|
|
562
580
|
if (!document.hidden) requestRender();
|
|
563
581
|
});
|
|
564
582
|
|
|
583
|
+
// The editor posts its zoom to each screen. Zooming in keeps the
|
|
584
|
+
// document's own resolution; zoom steps round up to eighths so a pinch
|
|
585
|
+
// doesn't reallocate the canvases every frame.
|
|
586
|
+
W.addEventListener("message", function (event: MessageEvent) {
|
|
587
|
+
if (W.parent === W || event.source !== W.parent) return;
|
|
588
|
+
const data = event.data as {
|
|
589
|
+
type?: unknown;
|
|
590
|
+
scaleX?: unknown;
|
|
591
|
+
scaleY?: unknown;
|
|
592
|
+
} | null;
|
|
593
|
+
if (!data || data.type !== "set-editor-chrome-scale") return;
|
|
594
|
+
const scale = Math.max(Number(data.scaleX) || 0, Number(data.scaleY) || 0);
|
|
595
|
+
if (!(scale > 0)) return;
|
|
596
|
+
const next = Math.min(1, Math.ceil(scale * 8) / 8);
|
|
597
|
+
if (next === viewScale) return;
|
|
598
|
+
viewScale = next;
|
|
599
|
+
requestRender();
|
|
600
|
+
});
|
|
601
|
+
|
|
565
602
|
try {
|
|
566
603
|
new MutationObserver(function () {
|
|
567
604
|
scheduleScan();
|
package/corpus/templates/design/app/components/design/design-canvas/text-content-change-result.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
currentCanvasOutcomeDesignId,
|
|
3
|
+
recordCanvasOutcome,
|
|
4
|
+
runCanvasOperation,
|
|
5
|
+
type CanvasOperationHandle,
|
|
6
|
+
} from "@/lib/canvas-outcome-tracking";
|
|
1
7
|
import type { TextCommitStatus } from "@/pages/design-editor/command-types";
|
|
2
8
|
|
|
3
9
|
export type QueuePendingTextHostCommit = (
|
|
@@ -156,16 +162,7 @@ export function consumePendingTextCreation(
|
|
|
156
162
|
return true;
|
|
157
163
|
}
|
|
158
164
|
|
|
159
|
-
|
|
160
|
-
owner,
|
|
161
|
-
nodeId,
|
|
162
|
-
value,
|
|
163
|
-
isPendingTextCreation,
|
|
164
|
-
commit,
|
|
165
|
-
queueHostCommit,
|
|
166
|
-
cancelHostCommit,
|
|
167
|
-
requestSnapshot,
|
|
168
|
-
}: {
|
|
165
|
+
type CommitTextContentChangeArgs = {
|
|
169
166
|
owner: string | null;
|
|
170
167
|
nodeId: string | null;
|
|
171
168
|
value: string;
|
|
@@ -174,15 +171,50 @@ export function commitTextContentChange({
|
|
|
174
171
|
queueHostCommit: QueuePendingTextHostCommit;
|
|
175
172
|
cancelHostCommit: CancelPendingTextHostCommit;
|
|
176
173
|
requestSnapshot: () => void;
|
|
177
|
-
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export function commitTextContentChange(
|
|
177
|
+
args: CommitTextContentChangeArgs,
|
|
178
|
+
): "published" | "fallback-queued" {
|
|
179
|
+
return runCanvasOperation("text_edit", (op) =>
|
|
180
|
+
commitTextContentChangeWithOutcome(op, args),
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function commitTextContentChangeWithOutcome(
|
|
185
|
+
op: CanvasOperationHandle,
|
|
186
|
+
{
|
|
187
|
+
owner,
|
|
188
|
+
nodeId,
|
|
189
|
+
value,
|
|
190
|
+
isPendingTextCreation,
|
|
191
|
+
commit,
|
|
192
|
+
queueHostCommit,
|
|
193
|
+
cancelHostCommit,
|
|
194
|
+
requestSnapshot,
|
|
195
|
+
}: CommitTextContentChangeArgs,
|
|
196
|
+
): "published" | "fallback-queued" {
|
|
178
197
|
const canFallback = Boolean(
|
|
179
198
|
isPendingTextCreation && owner && nodeId && value.length > 0,
|
|
180
199
|
);
|
|
181
200
|
const queueFallback = () => {
|
|
182
201
|
if (!canFallback || !owner || !nodeId || value.length === 0) return false;
|
|
183
|
-
|
|
202
|
+
// The retry can settle after the user opened another design.
|
|
203
|
+
const designId = currentCanvasOutcomeDesignId();
|
|
204
|
+
const queued = queueHostCommit(owner, nodeId, value, (outcome) => {
|
|
184
205
|
if (outcome === "accepted") requestSnapshot();
|
|
206
|
+
recordCanvasOutcome(
|
|
207
|
+
"text_retry",
|
|
208
|
+
outcome === "accepted" ? "succeeded" : "failed",
|
|
209
|
+
outcome === "accepted" ? "none" : "not_written",
|
|
210
|
+
{ designId },
|
|
211
|
+
);
|
|
185
212
|
});
|
|
213
|
+
// A queued retry can be cancelled or replaced without settling, so the
|
|
214
|
+
// edit counts as deferred rather than waiting on a result that may never
|
|
215
|
+
// come. A retry that does settle counts on its own, as `text_retry`.
|
|
216
|
+
if (queued) op.defer("fallback_queued");
|
|
217
|
+
return queued;
|
|
186
218
|
};
|
|
187
219
|
|
|
188
220
|
let status: TextCommitStatus | void;
|
|
@@ -201,6 +233,8 @@ export function commitTextContentChange({
|
|
|
201
233
|
// Any later direct result supersedes an older retry. A retry must never
|
|
202
234
|
// overwrite text that a newer source edit already accepted.
|
|
203
235
|
if (owner && nodeId) cancelHostCommit(owner, nodeId);
|
|
236
|
+
if (status === "accepted") op.succeed();
|
|
237
|
+
else if (status === "refused") op.fail("refused");
|
|
204
238
|
requestSnapshot();
|
|
205
239
|
return "published";
|
|
206
240
|
}
|
|
@@ -2,6 +2,9 @@ import type { ReactNode } from "react";
|
|
|
2
2
|
|
|
3
3
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
4
4
|
|
|
5
|
+
const TAB_CLASS =
|
|
6
|
+
"h-auto px-0 py-0 text-lg leading-[27px] font-medium group-data-[variant=line]/tabs-list:h-auto group-data-[variant=line]/tabs-list:border-b group-data-[variant=line]/tabs-list:text-muted-foreground";
|
|
7
|
+
|
|
5
8
|
export type DesignHomeLibraryTab = "templates" | "recent";
|
|
6
9
|
|
|
7
10
|
interface DesignHomeLibraryProps {
|
|
@@ -29,7 +32,7 @@ export function DesignHomeLibrary({
|
|
|
29
32
|
|
|
30
33
|
return (
|
|
31
34
|
<section
|
|
32
|
-
className="agent-prompt-home-library"
|
|
35
|
+
className="agent-prompt-home-library mx-auto w-full max-w-[63rem]"
|
|
33
36
|
aria-label={labels.templates}
|
|
34
37
|
>
|
|
35
38
|
<Tabs
|
|
@@ -42,19 +45,19 @@ export function DesignHomeLibrary({
|
|
|
42
45
|
}}
|
|
43
46
|
>
|
|
44
47
|
<div className="flex flex-wrap items-center justify-between gap-3">
|
|
45
|
-
<TabsList variant="line">
|
|
46
|
-
<TabsTrigger value="recent" className="flex-none">
|
|
47
|
-
{labels.recent}
|
|
48
|
-
</TabsTrigger>
|
|
48
|
+
<TabsList variant="line" className="gap-2 border-b-0">
|
|
49
49
|
<TabsTrigger
|
|
50
50
|
value="templates"
|
|
51
|
-
className=
|
|
51
|
+
className={TAB_CLASS}
|
|
52
52
|
onClick={() => {
|
|
53
53
|
if (activeValue === "templates") onValueChange("templates");
|
|
54
54
|
}}
|
|
55
55
|
>
|
|
56
56
|
{labels.templates}
|
|
57
57
|
</TabsTrigger>
|
|
58
|
+
<TabsTrigger value="recent" className={TAB_CLASS}>
|
|
59
|
+
{labels.recent}
|
|
60
|
+
</TabsTrigger>
|
|
58
61
|
</TabsList>
|
|
59
62
|
{activeValue === "recent" ? (
|
|
60
63
|
<div className="flex w-full min-w-0 flex-wrap items-center justify-end gap-2 sm:w-auto">
|
|
@@ -65,8 +68,12 @@ export function DesignHomeLibrary({
|
|
|
65
68
|
browseAll
|
|
66
69
|
)}
|
|
67
70
|
</div>
|
|
68
|
-
<TabsContent value="templates">
|
|
69
|
-
|
|
71
|
+
<TabsContent value="templates" className="mt-4">
|
|
72
|
+
{templates}
|
|
73
|
+
</TabsContent>
|
|
74
|
+
<TabsContent value="recent" className="mt-4">
|
|
75
|
+
{recent}
|
|
76
|
+
</TabsContent>
|
|
70
77
|
</Tabs>
|
|
71
78
|
</section>
|
|
72
79
|
);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
2
|
+
import { GettingStartedCard } from "@agent-native/toolkit/app/onboarding";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { Link } from "react-router";
|
|
5
|
+
|
|
6
|
+
const GETTING_STARTED_STEP_KEYS = {
|
|
7
|
+
"create-design": "createDesign",
|
|
8
|
+
"add-brand": "addBrand",
|
|
9
|
+
"use-real-data": "useRealData",
|
|
10
|
+
"share-feedback": "shareFeedback",
|
|
11
|
+
"invite-teammate": "inviteTeammate",
|
|
12
|
+
"save-template": "saveTemplate",
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
export function GettingStarted({ className }: { className?: string }) {
|
|
16
|
+
const t = useT();
|
|
17
|
+
const labels = useMemo(
|
|
18
|
+
() => ({
|
|
19
|
+
title: t("gettingStarted.title"),
|
|
20
|
+
progress: (completeCount: number, totalCount: number) =>
|
|
21
|
+
t("gettingStarted.progress", { completeCount, totalCount }),
|
|
22
|
+
collapse: t("gettingStarted.collapse"),
|
|
23
|
+
expand: t("gettingStarted.expand"),
|
|
24
|
+
completed: t("gettingStarted.completed"),
|
|
25
|
+
loadError: t("gettingStarted.loadError"),
|
|
26
|
+
retry: t("gettingStarted.retry"),
|
|
27
|
+
}),
|
|
28
|
+
[t],
|
|
29
|
+
);
|
|
30
|
+
const stepTitles = useMemo(
|
|
31
|
+
() =>
|
|
32
|
+
Object.fromEntries(
|
|
33
|
+
Object.entries(GETTING_STARTED_STEP_KEYS).map(([id, key]) => [
|
|
34
|
+
id,
|
|
35
|
+
t(`gettingStarted.steps.${key}`),
|
|
36
|
+
]),
|
|
37
|
+
),
|
|
38
|
+
[t],
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<GettingStartedCard
|
|
43
|
+
checklist="getting-started"
|
|
44
|
+
labels={labels}
|
|
45
|
+
stepTitles={stepTitles}
|
|
46
|
+
LinkComponent={Link}
|
|
47
|
+
className={className}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -14,6 +14,8 @@ import { IconComponents, IconHome, IconTemplate } from "@tabler/icons-react";
|
|
|
14
14
|
import { useEffect, useState } from "react";
|
|
15
15
|
import { useLocation } from "react-router";
|
|
16
16
|
|
|
17
|
+
import { GettingStarted } from "./GettingStarted";
|
|
18
|
+
|
|
17
19
|
const COLLAPSE_KEY = "design.sidebar.collapsed";
|
|
18
20
|
|
|
19
21
|
export function Sidebar() {
|
|
@@ -79,6 +81,7 @@ export function Sidebar() {
|
|
|
79
81
|
items={items}
|
|
80
82
|
footerContent={
|
|
81
83
|
<>
|
|
84
|
+
{collapsed ? null : <GettingStarted className="mx-2 mb-2" />}
|
|
82
85
|
<div className={collapsed ? "flex flex-col items-center" : undefined}>
|
|
83
86
|
<BuilderCreditNotice compact showAtLimitOnly className="mb-2" />
|
|
84
87
|
</div>
|