@adminide-stack/yantra-mobile 12.0.131 → 12.0.132
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/lib/components/CustomDrawer.js +2 -2
- package/lib/components/CustomDrawer.js.map +1 -1
- package/lib/features/apps/AppsCatalog.js +7 -1
- package/lib/features/apps/AppsCatalog.js.map +1 -1
- package/lib/features/apps/nativeSurfaceTwin.js +35 -0
- package/lib/features/apps/nativeSurfaceTwin.js.map +1 -0
- package/lib/features/canvas/CanvasBoardsGrid.js +49 -49
- package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -1
- package/lib/features/canvas/CanvasExperience.js +69 -28
- package/lib/features/canvas/CanvasExperience.js.map +1 -1
- package/lib/features/canvas/audioEditor/AudioWaveform.js +1 -1
- package/lib/features/canvas/designCatalog.js +63 -39
- package/lib/features/canvas/designCatalog.js.map +1 -1
- package/lib/features/canvas/designCategories.js +56 -0
- package/lib/features/canvas/designCategories.js.map +1 -1
- package/lib/features/canvas/generator/DirectorSheet.js +3 -2
- package/lib/features/canvas/generator/DirectorSheet.js.map +1 -1
- package/lib/features/canvas/home/HeroComposer.js +165 -76
- package/lib/features/canvas/home/HeroComposer.js.map +1 -1
- package/lib/features/canvas/home/HeroMonitor.js +75 -46
- package/lib/features/canvas/home/HeroMonitor.js.map +1 -1
- package/lib/features/canvas/home/TemplatesGallery.js +273 -138
- package/lib/features/canvas/home/TemplatesGallery.js.map +1 -1
- package/lib/features/canvas/home/templatesGallerySources.js +221 -0
- package/lib/features/canvas/home/templatesGallerySources.js.map +1 -0
- package/lib/features/canvas/homeWork.js +12 -11
- package/lib/features/canvas/homeWork.js.map +1 -1
- package/lib/features/canvas/lazyEditors.js +51 -0
- package/lib/features/canvas/lazyEditors.js.map +1 -0
- package/lib/features/canvas/rankedCatalogSearch.js +33 -23
- package/lib/features/canvas/rankedCatalogSearch.js.map +1 -1
- package/lib/features/canvas/set/SetViewportWebView.js +1 -1
- package/lib/features/canvas/set/agent/tools.js +1 -1
- package/lib/features/canvas/studioCatalog.js +2 -2
- package/lib/features/canvas/studioCatalog.js.map +1 -1
- package/lib/features/canvas/templateSearch.js +8 -1
- package/lib/features/canvas/templateSearch.js.map +1 -1
- package/lib/features/canvas/videoEditor/BlurBoxOverlay.js +1 -1
- package/lib/features/design/DesignEditorExperience.js +103 -29
- package/lib/features/design/DesignEditorExperience.js.map +1 -1
- package/lib/features/design/DesignExperience.js +4 -3
- package/lib/features/design/DesignExperience.js.map +1 -1
- package/lib/features/design/doc/aiDesign.js +1 -1
- package/lib/features/design/doc/aiDesign.js.map +1 -1
- package/lib/features/design/doc/artifacts.js +40 -13
- package/lib/features/design/doc/artifacts.js.map +1 -1
- package/lib/features/design/doc/chart.js +387 -13
- package/lib/features/design/doc/chart.js.map +1 -1
- package/lib/features/design/doc/copyStyle.js +47 -0
- package/lib/features/design/doc/copyStyle.js.map +1 -0
- package/lib/features/design/doc/docOps.js +22 -4
- package/lib/features/design/doc/docOps.js.map +1 -1
- package/lib/features/design/doc/geometry.js +32 -18
- package/lib/features/design/doc/geometry.js.map +1 -1
- package/lib/features/design/doc/newDoc.js +5 -1
- package/lib/features/design/doc/newDoc.js.map +1 -1
- package/lib/features/design/doc/resize.js +101 -0
- package/lib/features/design/doc/resize.js.map +1 -0
- package/lib/features/design/doc/sizes.js +15 -2
- package/lib/features/design/doc/sizes.js.map +1 -1
- package/lib/features/design/editor/ChartDataPanel.js +49 -9
- package/lib/features/design/editor/ChartDataPanel.js.map +1 -1
- package/lib/features/design/editor/CropOverlay.js +1 -1
- package/lib/features/design/editor/DesignCanvas.js +14 -13
- package/lib/features/design/editor/DesignCanvas.js.map +1 -1
- package/lib/features/design/editor/ExportSheet.js +8 -4
- package/lib/features/design/editor/ExportSheet.js.map +1 -1
- package/lib/features/design/editor/LayerTools.js +37 -5
- package/lib/features/design/editor/LayerTools.js.map +1 -1
- package/lib/features/design/editor/Slideshow.js +30 -5
- package/lib/features/design/editor/Slideshow.js.map +1 -1
- package/lib/features/design/editor/useDesignSave.js +21 -36
- package/lib/features/design/editor/useDesignSave.js.map +1 -1
- package/lib/features/design/export/exportDesign.js +3 -1
- package/lib/features/design/export/exportDesign.js.map +1 -1
- package/lib/features/design/home/DesignHome.js +7 -2
- package/lib/features/design/home/DesignHome.js.map +1 -1
- package/lib/features/design/render/DesignPageView.js +1 -1
- package/lib/features/design/render/DesignPageView.js.map +1 -1
- package/lib/features/design/render/PageCapture.js +11 -10
- package/lib/features/design/render/PageCapture.js.map +1 -1
- package/lib/features/design/render/fontRegistry.js +27 -3
- package/lib/features/design/render/fontRegistry.js.map +1 -1
- package/lib/features/design/render/svgParts.js +27 -74
- package/lib/features/design/render/svgParts.js.map +1 -1
- package/lib/features/devices/brands/qnScale.js +7 -2
- package/lib/features/devices/brands/qnScale.js.map +1 -1
- package/lib/features/devices/brands/uuids.js +2 -1
- package/lib/features/devices/brands/uuids.js.map +1 -1
- package/lib/features/devices/devices.js +2 -1
- package/lib/features/devices/devices.js.map +1 -1
- package/lib/features/docs/DocBlockRow.js +1 -1
- package/lib/features/docs/docArtifacts.js +2 -2
- package/lib/features/docs/docArtifacts.js.map +1 -1
- package/lib/features/health/healthSync.js +3 -1
- package/lib/features/health/healthSync.js.map +1 -1
- package/lib/features/health/nativeHealth.js +8 -0
- package/lib/features/health/nativeHealth.js.map +1 -0
- package/lib/features/links/openInApp.js +11 -1
- package/lib/features/links/openInApp.js.map +1 -1
- package/lib/features/webbuilder/WebBuilderExperience.js +135 -28
- package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
- package/lib/features/webbuilder/buildFragments.js +14 -6
- package/lib/features/webbuilder/buildFragments.js.map +1 -1
- package/lib/features/webbuilder/components/PreviewFrame.js +28 -3
- package/lib/features/webbuilder/components/PreviewFrame.js.map +1 -1
- package/lib/features/webbuilder/components/PreviewScreen.js +1 -1
- package/lib/features/webbuilder/components/PreviewScreen.js.map +1 -1
- package/lib/features/webbuilder/components/ProjectChat.js +24 -5
- package/lib/features/webbuilder/components/ProjectChat.js.map +1 -1
- package/lib/features/webbuilder/components/ProjectsScreen.js +18 -2
- package/lib/features/webbuilder/components/ProjectsScreen.js.map +1 -1
- package/lib/features/webbuilder/components/ui.js +20 -6
- package/lib/features/webbuilder/components/ui.js.map +1 -1
- package/lib/features/webbuilder/exportCode.js +52 -0
- package/lib/features/webbuilder/exportCode.js.map +1 -0
- package/lib/features/webbuilder/siteAddress.js +71 -0
- package/lib/features/webbuilder/siteAddress.js.map +1 -0
- package/lib/features/webbuilder/widgetBlocks.js +30 -0
- package/lib/features/webbuilder/widgetBlocks.js.map +1 -0
- package/lib/screens/Chat/index.js +5 -6
- package/lib/screens/Chat/index.js.map +1 -1
- package/lib/screens/ChatHistory/index.js +3 -2
- package/lib/screens/ChatHistory/index.js.map +1 -1
- package/lib/screens/Home/HomeScreen.js +20 -4
- package/lib/screens/Home/HomeScreen.js.map +1 -1
- package/lib/screens/Home/components/WebBuilderCodePrewarm.js +18 -0
- package/lib/screens/Home/components/WebBuilderCodePrewarm.js.map +1 -0
- package/lib/screens/WebBuilderNative/index.js +1 -1
- package/lib/screens/WebBuilderNative/index.js.map +1 -1
- package/lib/screens/WebBuilderNative/keepAlive.js +112 -0
- package/lib/screens/WebBuilderNative/keepAlive.js.map +1 -0
- package/lib/screens/WebBuilderNative/runningBuilds.js +40 -0
- package/lib/screens/WebBuilderNative/runningBuilds.js.map +1 -0
- package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js +57 -0
- package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js.map +1 -0
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js +73 -14
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js.map +1 -1
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js +143 -34
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
- package/lib/screens/WebBuilderNative/useWebBuilderJobs.js +17 -5
- package/lib/screens/WebBuilderNative/useWebBuilderJobs.js.map +1 -1
- package/lib/screens/WebBuilderNative/versionUndo.js +144 -0
- package/lib/screens/WebBuilderNative/versionUndo.js.map +1 -0
- package/lib/screens/WebBuilderNative/webbuilderSnapshotKey.js +1 -0
- package/lib/screens/WebBuilderNative/webbuilderSnapshotKey.js.map +1 -0
- package/lib/screens/WebBuilderNative/webbuilderTransport.js +90 -6
- package/lib/screens/WebBuilderNative/webbuilderTransport.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {jsx,jsxs}from'react/jsx-runtime';import {useState,useRef,useMemo}from'react';import {
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {useState,useRef,useMemo}from'react';import {PanResponder,View,StyleSheet}from'react-native';import Svg,{Rect}from'react-native-svg';import {selectionFromDrag}from'./audioPeaks.js';var __defProp = Object.defineProperty;
|
|
2
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {gql}from'@apollo/client/index.js';import {catalogSearch,PUBLISHED_STATUS}from'./studioCatalog.js';var __defProp = Object.defineProperty;
|
|
1
|
+
import {gql}from'@apollo/client/index.js';import {catalogSearch,PUBLISHED_STATUS}from'./studioCatalog.js';import {templateDisplayTitle}from'./templateSearch.js';var __defProp = Object.defineProperty;
|
|
2
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
@@ -17,7 +17,7 @@ var __spreadValues = (a, b) => {
|
|
|
17
17
|
return a;
|
|
18
18
|
};
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
const DESIGN_CATALOG_GROUPS = ["canvas-flyer", "canvas-presentation", "canvas-business-card", "canvas-carousel", "canvas-logo", "canvas-banner", "canvas-brochure", "canvas-branding", "canvas-certificate", "canvas-worksheet", "canvas-proposal", "canvas-social-post", "canvas-newsletter", "canvas-menu", "canvas-infographic"];
|
|
20
|
+
const DESIGN_CATALOG_GROUPS = ["canvas-flyer", "canvas-presentation", "canvas-business-card", "canvas-carousel", "canvas-logo", "canvas-banner", "canvas-brochure", "canvas-branding", "canvas-certificate", "canvas-worksheet", "canvas-proposal", "canvas-social-post", "canvas-newsletter", "canvas-menu", "canvas-infographic", "canvas-document", "canvas-report", "canvas-letter", "canvas-resume"];
|
|
21
21
|
const DESIGN_GROUP_LISTED_RECORD = {
|
|
22
22
|
"canvas-flyer": "yantra-flyer-templates"
|
|
23
23
|
};
|
|
@@ -50,7 +50,7 @@ function designCardFromRow(row, group) {
|
|
|
50
50
|
return {
|
|
51
51
|
id,
|
|
52
52
|
group,
|
|
53
|
-
title: str(details.title) || id,
|
|
53
|
+
title: templateDisplayTitle(str(details.title)) || id,
|
|
54
54
|
coverUrl,
|
|
55
55
|
aspectRatio: str(design.aspectRatio) || str(obj(formData.generation).aspectRatio),
|
|
56
56
|
pageWidth,
|
|
@@ -83,62 +83,86 @@ function designCatalogFilter(group, opts = {}) {
|
|
|
83
83
|
offset: (_b = opts.offset) != null ? _b : 0
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
const MAX_LISTING_READS = 4;
|
|
87
|
+
async function readDesignCatalogPage(readRows, group, opts = {}) {
|
|
88
|
+
var _a, _b;
|
|
88
89
|
const limit = (_a = opts.limit) != null ? _a : DESIGN_CATALOG_PAGE_SIZE;
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
const offset = (_b = opts.offset) != null ? _b : 0;
|
|
91
|
+
const cards = [];
|
|
92
|
+
let used = 0;
|
|
93
|
+
for (let read = 1; ; read++) {
|
|
94
|
+
const nodes = await readRows(designCatalogFilter(group, __spreadProps(__spreadValues({}, opts), {
|
|
95
|
+
limit,
|
|
96
|
+
offset: offset + used
|
|
97
|
+
})));
|
|
98
|
+
const more = nodes.length === limit;
|
|
99
|
+
for (const [i, node] of nodes.entries()) {
|
|
100
|
+
const card = designCardFromRow(node, group);
|
|
101
|
+
if (card && (opts.anyRecord || isListedDesignCard(card))) cards.push(card);
|
|
102
|
+
if (cards.length === limit) {
|
|
103
|
+
return {
|
|
104
|
+
cards,
|
|
105
|
+
hasMore: i + 1 < nodes.length || more,
|
|
106
|
+
fetched: used + i + 1
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
used += nodes.length;
|
|
111
|
+
if (opts.anyRecord || !more || read >= MAX_LISTING_READS) return {
|
|
112
|
+
cards,
|
|
113
|
+
hasMore: more,
|
|
114
|
+
fetched: used
|
|
115
|
+
};
|
|
116
|
+
}
|
|
95
117
|
}
|
|
96
118
|
const CACHE_TTL_MS = 10 * 6e4;
|
|
97
119
|
const cache = /* @__PURE__ */ new Map();
|
|
98
120
|
function fetchDesignCatalog(graphqlUrl, token, group, opts = {}) {
|
|
99
121
|
const filter = designCatalogFilter(group, opts);
|
|
100
|
-
return cached(`${graphqlUrl}|${JSON.stringify(filter)}`,
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const json = await res.json().catch(() => ({}));
|
|
118
|
-
if ((_a = json.errors) == null ? void 0 : _a.length) {
|
|
119
|
-
throw new Error(json.errors.map((e) => e == null ? void 0 : e.message).filter(Boolean).join("; ") || "Template catalog read failed");
|
|
120
|
-
}
|
|
121
|
-
const nodes = (_c = (_b = json.data) == null ? void 0 : _b.formTemplateSubmissions) == null ? void 0 : _c.nodes;
|
|
122
|
-
return designCatalogPageFromRows(Array.isArray(nodes) ? nodes : [], group, opts);
|
|
122
|
+
return cached(`${graphqlUrl}|${JSON.stringify(filter)}`, () => readDesignCatalogPage((pageFilter) => fetchDesignRows(graphqlUrl, token, pageFilter), group, opts));
|
|
123
|
+
}
|
|
124
|
+
async function fetchDesignRows(graphqlUrl, token, filter) {
|
|
125
|
+
var _a, _b, _c;
|
|
126
|
+
const res = await fetch(graphqlUrl, {
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers: __spreadValues({
|
|
129
|
+
"content-type": "application/json"
|
|
130
|
+
}, token ? {
|
|
131
|
+
authorization: `Bearer ${token}`
|
|
132
|
+
} : {}),
|
|
133
|
+
body: JSON.stringify({
|
|
134
|
+
query: DESIGN_CATALOG_QUERY,
|
|
135
|
+
variables: {
|
|
136
|
+
filter
|
|
137
|
+
}
|
|
138
|
+
})
|
|
123
139
|
});
|
|
140
|
+
if (!res.ok) throw new Error(`Template catalog read failed (${res.status})`);
|
|
141
|
+
const json = await res.json().catch(() => ({}));
|
|
142
|
+
if ((_a = json.errors) == null ? void 0 : _a.length) {
|
|
143
|
+
throw new Error(json.errors.map((e) => e == null ? void 0 : e.message).filter(Boolean).join("; ") || "Template catalog read failed");
|
|
144
|
+
}
|
|
145
|
+
const nodes = (_c = (_b = json.data) == null ? void 0 : _b.formTemplateSubmissions) == null ? void 0 : _c.nodes;
|
|
146
|
+
return Array.isArray(nodes) ? nodes : [];
|
|
124
147
|
}
|
|
125
148
|
const DESIGN_CATALOG_DOC = gql(DESIGN_CATALOG_QUERY);
|
|
126
149
|
function fetchDesignCatalogViaClient(client, group, opts = {}) {
|
|
127
150
|
const filter = designCatalogFilter(group, opts);
|
|
128
|
-
|
|
151
|
+
const readRows = async (pageFilter) => {
|
|
129
152
|
var _a;
|
|
130
153
|
const {
|
|
131
154
|
data
|
|
132
155
|
} = await client.query({
|
|
133
156
|
query: DESIGN_CATALOG_DOC,
|
|
134
157
|
variables: {
|
|
135
|
-
filter
|
|
158
|
+
filter: pageFilter
|
|
136
159
|
},
|
|
137
160
|
fetchPolicy: "no-cache"
|
|
138
161
|
});
|
|
139
162
|
const nodes = (_a = data == null ? void 0 : data.formTemplateSubmissions) == null ? void 0 : _a.nodes;
|
|
140
|
-
return
|
|
141
|
-
}
|
|
163
|
+
return Array.isArray(nodes) ? nodes : [];
|
|
164
|
+
};
|
|
165
|
+
return cached(`apollo|${JSON.stringify(filter)}`, () => readDesignCatalogPage(readRows, group, opts));
|
|
142
166
|
}
|
|
143
167
|
function cached(key, read) {
|
|
144
168
|
const hit = cache.get(key);
|
|
@@ -162,4 +186,4 @@ function interleaveTemplateRows(a, b) {
|
|
|
162
186
|
}
|
|
163
187
|
const midpoint = Math.ceil(cards.length / 2);
|
|
164
188
|
return [cards.slice(0, midpoint), cards.slice(midpoint)];
|
|
165
|
-
}export{DESIGN_CATALOG_GROUPS,DESIGN_CATALOG_PAGE_SIZE,DESIGN_CATALOG_QUERY,DESIGN_GROUP_LISTED_RECORD,SINGLE_PAGE_DESIGN_GROUPS,designCardFromRow,designCatalogFilter,
|
|
189
|
+
}export{DESIGN_CATALOG_GROUPS,DESIGN_CATALOG_PAGE_SIZE,DESIGN_CATALOG_QUERY,DESIGN_GROUP_LISTED_RECORD,MAX_LISTING_READS,SINGLE_PAGE_DESIGN_GROUPS,designCardFromRow,designCatalogFilter,fetchDesignCatalog,fetchDesignCatalogViaClient,groupOfTemplate,interleaveTemplateRows,isListedDesignCard,readDesignCatalogPage,templateDisplayTitle};//# sourceMappingURL=designCatalog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"designCatalog.js","sources":["../../../src/features/canvas/designCatalog.ts"],"sourcesContent":["/**\n * The canvas design catalog (flyers, presentations, business cards, ...) -\n * native twin of surface-kit `templateCatalogs/designCatalog.ts` + `catalogRead.ts`.\n *\n * Marketplace submissions on the app's own backend, one row per template,\n * stamped `canvas-<category>`. Native lists them (home's \"Templates for you\",\n * the category gallery) and the native design studio opens the picked one\n * (features/design/doc/newDoc.ts reads its full pages).\n *\n * Read with plain `fetch` against the backend GraphQL, the same lane\n * `studioLooks.listViaBackendFetch` uses for the studio catalog. Public reads:\n * the bearer only rides along when there is one.\n *\n * A dev host whose backend URL cannot be derived reads through the host's\n * Apollo client instead (`fetchDesignCatalogViaClient`).\n *\n * Pure apart from `fetch`: no RN imports, so it runs under jest as-is.\n */\nimport { gql } from '@apollo/client';\nimport { PUBLISHED_STATUS, catalogSearch } from './studioCatalog';\nimport type { StudioCatalogClient } from './useStudioCatalogTemplates';\n\n/** Every group yantra-designs publishes (surface-kit DESIGN_CATALOG_GROUPS). */\nexport const DESIGN_CATALOG_GROUPS = [\n 'canvas-flyer',\n 'canvas-presentation',\n 'canvas-business-card',\n 'canvas-carousel',\n 'canvas-logo',\n 'canvas-banner',\n 'canvas-brochure',\n 'canvas-branding',\n 'canvas-certificate',\n 'canvas-worksheet',\n 'canvas-proposal',\n 'canvas-social-post',\n 'canvas-newsletter',\n 'canvas-menu',\n 'canvas-infographic',\n] as const;\nexport type DesignCatalogGroup = (typeof DESIGN_CATALOG_GROUPS)[number];\n\n/**\n * The marketplace record a group LISTS, for a group that holds more than it\n * lists: `canvas-flyer` also holds Canva's multi-page \"flyers\" (really decks),\n * so a listing reads only Yantra's own single-page flyers. A read by id does not.\n */\nexport const DESIGN_GROUP_LISTED_RECORD: Readonly<Partial<Record<DesignCatalogGroup, string>>> = {\n 'canvas-flyer': 'yantra-flyer-templates',\n};\n\n/** Groups whose listings show one-page portrait or square designs only. */\nexport const SINGLE_PAGE_DESIGN_GROUPS: ReadonlySet<DesignCatalogGroup> = new Set<DesignCatalogGroup>(['canvas-flyer']);\n\nexport const DESIGN_CATALOG_QUERY = `query TemplateCatalog($filter: FormTemplateSubmissionFilter) {\n formTemplateSubmissions(filter: $filter) { nodes { id name description category tags formData } }\n}`;\n\n/** What native needs of a template: enough to draw its cover at its own shape and open it on the web. */\nexport interface DesignCatalogCard {\n /** Row name: the platform's stable template id (`?design=<id>`). */\n id: string;\n group: DesignCatalogGroup;\n title: string;\n coverUrl: string;\n aspectRatio: string;\n pageWidth: number;\n pageHeight: number;\n pageCount: number;\n tags: string[];\n}\n\nexport interface DesignCatalogFilter {\n group: DesignCatalogGroup;\n status: typeof PUBLISHED_STATUS;\n limit: number;\n offset: number;\n templateId?: string;\n search?: string;\n}\n\nexport interface DesignCatalogOptions {\n search?: string;\n offset?: number;\n limit?: number;\n /** Read any row of the group (a read by id), not only the rows it lists. */\n anyRecord?: boolean;\n}\n\nexport interface DesignCatalogPage {\n cards: DesignCatalogCard[];\n /** The resolver has no total: a full page means there is probably another one. */\n hasMore: boolean;\n /** Rows the server returned, cards or not: the next page starts this far on. */\n fetched: number;\n}\n\nexport const DESIGN_CATALOG_PAGE_SIZE = 24;\n\nconst str = (v: unknown): string => (typeof v === 'string' ? v.trim() : '');\nconst obj = (v: unknown): Record<string, any> =>\n v && typeof v === 'object' && !Array.isArray(v) ? (v as Record<string, any>) : {};\nconst isHttps = (v: unknown): v is string => typeof v === 'string' && /^https:\\/\\//.test(v);\nconst isPage = (p: unknown): boolean =>\n isHttps(p) || (Boolean(p) && typeof p === 'object' && Array.isArray((p as { layers?: unknown }).layers));\n\n/** One row -> one card; a row without a cover, a size or pages is not a usable template. */\nexport function designCardFromRow(row: Record<string, any>, group: DesignCatalogGroup): DesignCatalogCard | null {\n let formData: Record<string, any> = obj(row?.formData);\n if (typeof row?.formData === 'string') {\n try {\n formData = obj(JSON.parse(row.formData));\n } catch {\n return null;\n }\n }\n const details = obj(formData.generationDetails);\n const design = obj(formData.design);\n const pageCount = Array.isArray(design.pages) ? design.pages.filter(isPage).length : 0;\n const pageWidth = Number(design.pageWidth);\n const pageHeight = Number(design.pageHeight);\n const id = str(row?.name);\n const coverUrl = isHttps(details.previewUrl) ? str(details.previewUrl) : '';\n if (!id || !coverUrl || pageCount === 0 || !(pageWidth > 0) || !(pageHeight > 0)) return null;\n return {\n id,\n group,\n title: str(details.title) || id,\n coverUrl,\n aspectRatio: str(design.aspectRatio) || str(obj(formData.generation).aspectRatio),\n pageWidth,\n pageHeight,\n pageCount,\n tags: Array.isArray(row?.tags) ? row.tags.filter((t: unknown): t is string => typeof t === 'string') : [],\n };\n}\n\n/** Does a group's listing show this card? In a single-page group only a one-page portrait or square design. */\nexport function isListedDesignCard(\n card: Pick<DesignCatalogCard, 'group' | 'pageCount' | 'pageWidth' | 'pageHeight'>,\n): boolean {\n if (!SINGLE_PAGE_DESIGN_GROUPS.has(card.group)) return true;\n return card.pageCount === 1 && card.pageHeight >= card.pageWidth;\n}\n\n/** The catalog group a template id (its row name) belongs to. */\nexport function groupOfTemplate(id: string): DesignCatalogGroup | null {\n return DESIGN_CATALOG_GROUPS.find((group) => id.startsWith(`${group}-`)) ?? null;\n}\n\n/** The `formTemplateSubmissions` filter for one page of a group. */\nexport function designCatalogFilter(group: DesignCatalogGroup, opts: DesignCatalogOptions = {}): DesignCatalogFilter {\n const templateId = opts.anyRecord ? undefined : DESIGN_GROUP_LISTED_RECORD[group];\n const search = catalogSearch(opts.search);\n return {\n group,\n status: PUBLISHED_STATUS,\n ...(templateId ? { templateId } : {}),\n ...(search ? { search } : {}),\n limit: opts.limit ?? DESIGN_CATALOG_PAGE_SIZE,\n offset: opts.offset ?? 0,\n };\n}\n\n/** Rows -> the page a listing (or a read by id) shows. */\nexport function designCatalogPageFromRows(\n nodes: ReadonlyArray<Record<string, any>>,\n group: DesignCatalogGroup,\n opts: DesignCatalogOptions = {},\n): DesignCatalogPage {\n const limit = opts.limit ?? DESIGN_CATALOG_PAGE_SIZE;\n const cards = nodes.map((n) => designCardFromRow(n, group)).filter((c): c is DesignCatalogCard => c !== null);\n return {\n cards: opts.anyRecord ? cards : cards.filter(isListedDesignCard),\n hasMore: nodes.length === limit,\n fetched: nodes.length,\n };\n}\n\n/** The catalog changes when a release loads it, not while someone browses. */\nconst CACHE_TTL_MS = 10 * 60_000;\nconst cache = new Map<string, { at: number; page: Promise<DesignCatalogPage> }>();\n\nexport function clearDesignCatalogCache(): void {\n cache.clear();\n}\n\n/**\n * One page of a catalog group straight from the backend, cached in memory for\n * ten minutes per (endpoint, filter). A failed read is not cached.\n */\nexport function fetchDesignCatalog(\n graphqlUrl: string,\n token: string | null | undefined,\n group: DesignCatalogGroup,\n opts: DesignCatalogOptions = {},\n): Promise<DesignCatalogPage> {\n const filter = designCatalogFilter(group, opts);\n return cached(`${graphqlUrl}|${JSON.stringify(filter)}`, async () => {\n const res = await fetch(graphqlUrl, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n ...(token ? { authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({ query: DESIGN_CATALOG_QUERY, variables: { filter } }),\n });\n if (!res.ok) throw new Error(`Template catalog read failed (${res.status})`);\n const json = (await res.json().catch(() => ({}))) as {\n data?: { formTemplateSubmissions?: { nodes?: Array<Record<string, any>> | null } };\n errors?: Array<{ message?: string }>;\n };\n if (json.errors?.length) {\n throw new Error(\n json.errors\n .map((e) => e?.message)\n .filter(Boolean)\n .join('; ') || 'Template catalog read failed',\n );\n }\n const nodes = json.data?.formTemplateSubmissions?.nodes;\n return designCatalogPageFromRows(Array.isArray(nodes) ? nodes : [], group, opts);\n });\n}\n\nconst DESIGN_CATALOG_DOC = gql(DESIGN_CATALOG_QUERY);\n\n/** The same page through the host's Apollo client (no cache write: rows are tens of KB each). */\nexport function fetchDesignCatalogViaClient(\n client: Pick<StudioCatalogClient, 'query'>,\n group: DesignCatalogGroup,\n opts: DesignCatalogOptions = {},\n): Promise<DesignCatalogPage> {\n const filter = designCatalogFilter(group, opts);\n return cached(`apollo|${JSON.stringify(filter)}`, async () => {\n const { data } = await client.query({\n query: DESIGN_CATALOG_DOC,\n variables: { filter },\n fetchPolicy: 'no-cache',\n });\n const nodes = (data as { formTemplateSubmissions?: { nodes?: Array<Record<string, any>> | null } } | null)\n ?.formTemplateSubmissions?.nodes;\n return designCatalogPageFromRows(Array.isArray(nodes) ? nodes : [], group, opts);\n });\n}\n\nfunction cached(key: string, read: () => Promise<DesignCatalogPage>): Promise<DesignCatalogPage> {\n const hit = cache.get(key);\n if (hit && Date.now() - hit.at < CACHE_TTL_MS) return hit.page;\n const page = read();\n cache.set(key, { at: Date.now(), page });\n page.catch(() => {\n if (cache.get(key)?.page === page) cache.delete(key);\n });\n return page;\n}\n\n/** Interleave two rails (flyer, slide, flyer, ...) and split them into two rows, like web TemplateRails. */\nexport function interleaveTemplateRows(\n a: readonly DesignCatalogCard[],\n b: readonly DesignCatalogCard[],\n): [DesignCatalogCard[], DesignCatalogCard[]] {\n const cards: DesignCatalogCard[] = [];\n for (let i = 0; i < Math.max(a.length, b.length); i += 1) {\n if (a[i]) cards.push(a[i]);\n if (b[i]) cards.push(b[i]);\n }\n const midpoint = Math.ceil(cards.length / 2);\n return [cards.slice(0, midpoint), cards.slice(midpoint)];\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"designCatalog.js","sources":["../../../src/features/canvas/designCatalog.ts"],"sourcesContent":["/**\n * The canvas design catalog (flyers, presentations, business cards, ...) -\n * native twin of surface-kit `templateCatalogs/designCatalog.ts` + `catalogRead.ts`.\n *\n * Marketplace submissions on the app's own backend, one row per template,\n * stamped `canvas-<category>`. Native lists them (home's \"Templates for you\",\n * the category gallery) and the native design studio opens the picked one\n * (features/design/doc/newDoc.ts reads its full pages).\n *\n * Read with plain `fetch` against the backend GraphQL, the same lane\n * `studioLooks.listViaBackendFetch` uses for the studio catalog. Public reads:\n * the bearer only rides along when there is one.\n *\n * A dev host whose backend URL cannot be derived reads through the host's\n * Apollo client instead (`fetchDesignCatalogViaClient`).\n *\n * Pure apart from `fetch`: no RN imports, so it runs under jest as-is.\n */\nimport { gql } from '@apollo/client';\nimport { PUBLISHED_STATUS, catalogSearch } from './studioCatalog';\nimport { templateDisplayTitle } from './templateSearch';\n\nexport { templateDisplayTitle };\nimport type { StudioCatalogClient } from './useStudioCatalogTemplates';\n\n/** Every group yantra-designs publishes (surface-kit DESIGN_CATALOG_GROUPS). */\nexport const DESIGN_CATALOG_GROUPS = [\n 'canvas-flyer',\n 'canvas-presentation',\n 'canvas-business-card',\n 'canvas-carousel',\n 'canvas-logo',\n 'canvas-banner',\n 'canvas-brochure',\n 'canvas-branding',\n 'canvas-certificate',\n 'canvas-worksheet',\n 'canvas-proposal',\n 'canvas-social-post',\n 'canvas-newsletter',\n 'canvas-menu',\n 'canvas-infographic',\n 'canvas-document',\n 'canvas-report',\n 'canvas-letter',\n 'canvas-resume',\n] as const;\nexport type DesignCatalogGroup = (typeof DESIGN_CATALOG_GROUPS)[number];\n\n/**\n * The marketplace record a group LISTS, for a group that holds more than it\n * lists: `canvas-flyer` also holds Canva's multi-page \"flyers\" (really decks),\n * so a listing reads only Yantra's own single-page flyers. A read by id does not.\n */\nexport const DESIGN_GROUP_LISTED_RECORD: Readonly<Partial<Record<DesignCatalogGroup, string>>> = {\n 'canvas-flyer': 'yantra-flyer-templates',\n};\n\n/** Groups whose listings show one-page portrait or square designs only. */\nexport const SINGLE_PAGE_DESIGN_GROUPS: ReadonlySet<DesignCatalogGroup> = new Set<DesignCatalogGroup>(['canvas-flyer']);\n\nexport const DESIGN_CATALOG_QUERY = `query TemplateCatalog($filter: FormTemplateSubmissionFilter) {\n formTemplateSubmissions(filter: $filter) { nodes { id name description category tags formData } }\n}`;\n\n/** What native needs of a template: enough to draw its cover at its own shape and open it on the web. */\nexport interface DesignCatalogCard {\n /** Row name: the platform's stable template id (`?design=<id>`). */\n id: string;\n group: DesignCatalogGroup;\n title: string;\n coverUrl: string;\n aspectRatio: string;\n pageWidth: number;\n pageHeight: number;\n pageCount: number;\n tags: string[];\n}\n\nexport interface DesignCatalogFilter {\n group: DesignCatalogGroup;\n status: typeof PUBLISHED_STATUS;\n limit: number;\n offset: number;\n templateId?: string;\n search?: string;\n}\n\nexport interface DesignCatalogOptions {\n search?: string;\n offset?: number;\n limit?: number;\n /** Read any row of the group (a read by id), not only the rows it lists. */\n anyRecord?: boolean;\n}\n\nexport interface DesignCatalogPage {\n cards: DesignCatalogCard[];\n /** The resolver has no total: a full page means there is probably another one. */\n hasMore: boolean;\n /** Rows this page used, cards or not: the next page starts this far on. */\n fetched: number;\n}\n\nexport const DESIGN_CATALOG_PAGE_SIZE = 24;\n\nconst str = (v: unknown): string => (typeof v === 'string' ? v.trim() : '');\nconst obj = (v: unknown): Record<string, any> =>\n v && typeof v === 'object' && !Array.isArray(v) ? (v as Record<string, any>) : {};\nconst isHttps = (v: unknown): v is string => typeof v === 'string' && /^https:\\/\\//.test(v);\nconst isPage = (p: unknown): boolean =>\n isHttps(p) || (Boolean(p) && typeof p === 'object' && Array.isArray((p as { layers?: unknown }).layers));\n\n/** One row -> one card; a row without a cover, a size or pages is not a usable template. */\nexport function designCardFromRow(row: Record<string, any>, group: DesignCatalogGroup): DesignCatalogCard | null {\n let formData: Record<string, any> = obj(row?.formData);\n if (typeof row?.formData === 'string') {\n try {\n formData = obj(JSON.parse(row.formData));\n } catch {\n return null;\n }\n }\n const details = obj(formData.generationDetails);\n const design = obj(formData.design);\n const pageCount = Array.isArray(design.pages) ? design.pages.filter(isPage).length : 0;\n const pageWidth = Number(design.pageWidth);\n const pageHeight = Number(design.pageHeight);\n const id = str(row?.name);\n const coverUrl = isHttps(details.previewUrl) ? str(details.previewUrl) : '';\n if (!id || !coverUrl || pageCount === 0 || !(pageWidth > 0) || !(pageHeight > 0)) return null;\n return {\n id,\n group,\n title: templateDisplayTitle(str(details.title)) || id,\n coverUrl,\n aspectRatio: str(design.aspectRatio) || str(obj(formData.generation).aspectRatio),\n pageWidth,\n pageHeight,\n pageCount,\n tags: Array.isArray(row?.tags) ? row.tags.filter((t: unknown): t is string => typeof t === 'string') : [],\n };\n}\n\n/** Does a group's listing show this card? In a single-page group only a one-page portrait or square design. */\nexport function isListedDesignCard(\n card: Pick<DesignCatalogCard, 'group' | 'pageCount' | 'pageWidth' | 'pageHeight'>,\n): boolean {\n if (!SINGLE_PAGE_DESIGN_GROUPS.has(card.group)) return true;\n return card.pageCount === 1 && card.pageHeight >= card.pageWidth;\n}\n\n/** The catalog group a template id (its row name) belongs to. */\nexport function groupOfTemplate(id: string): DesignCatalogGroup | null {\n return DESIGN_CATALOG_GROUPS.find((group) => id.startsWith(`${group}-`)) ?? null;\n}\n\n/** The `formTemplateSubmissions` filter for one page of a group. */\nexport function designCatalogFilter(group: DesignCatalogGroup, opts: DesignCatalogOptions = {}): DesignCatalogFilter {\n const templateId = opts.anyRecord ? undefined : DESIGN_GROUP_LISTED_RECORD[group];\n const search = catalogSearch(opts.search);\n return {\n group,\n status: PUBLISHED_STATUS,\n ...(templateId ? { templateId } : {}),\n ...(search ? { search } : {}),\n limit: opts.limit ?? DESIGN_CATALOG_PAGE_SIZE,\n offset: opts.offset ?? 0,\n };\n}\n\n/** Rows -> the page a listing (or a read by id) shows. */\nexport function designCatalogPageFromRows(\n nodes: ReadonlyArray<Record<string, any>>,\n group: DesignCatalogGroup,\n opts: DesignCatalogOptions = {},\n): DesignCatalogPage {\n const limit = opts.limit ?? DESIGN_CATALOG_PAGE_SIZE;\n const cards = nodes.map((n) => designCardFromRow(n, group)).filter((c): c is DesignCatalogCard => c !== null);\n return {\n cards: opts.anyRecord ? cards : cards.filter(isListedDesignCard),\n hasMore: nodes.length === limit,\n fetched: nodes.length,\n };\n}\n\n/**\n * Server reads one listing page may make at most. A page whose rows a listing drops reads on until\n * it holds `limit` cards; past this many reads it comes back short and the next page carries on.\n */\nexport const MAX_LISTING_READS = 4;\n\n/** One server read of a group's rows for a filter. */\nexport type DesignCatalogRowsRead = (filter: DesignCatalogFilter) => Promise<ReadonlyArray<Record<string, any>>>;\n\n/**\n * One page of a catalog group (surface-kit `readDesignCatalogPage`). A listing page is full: where\n * it drops rows (a multi-page or landscape flyer, a row with no pages or no cover), it reads on past\n * them until it holds `limit` cards or the group ends, at most MAX_LISTING_READS reads. `fetched`\n * counts the rows it used, up to its last card, so the next page starts right after it and no row\n * is skipped or listed twice. `anyRecord` reads once and keeps every card.\n */\nexport async function readDesignCatalogPage(\n readRows: DesignCatalogRowsRead,\n group: DesignCatalogGroup,\n opts: DesignCatalogOptions = {},\n): Promise<DesignCatalogPage> {\n const limit = opts.limit ?? DESIGN_CATALOG_PAGE_SIZE;\n const offset = opts.offset ?? 0;\n const cards: DesignCatalogCard[] = [];\n let used = 0;\n for (let read = 1; ; read++) {\n const nodes = await readRows(designCatalogFilter(group, { ...opts, limit, offset: offset + used }));\n // The resolver has no total: a full page means there is probably another one.\n const more = nodes.length === limit;\n for (const [i, node] of nodes.entries()) {\n const card = designCardFromRow(node, group);\n if (card && (opts.anyRecord || isListedDesignCard(card))) cards.push(card);\n if (cards.length === limit) {\n // Full: the next page starts at the row after this card, read or not.\n return { cards, hasMore: i + 1 < nodes.length || more, fetched: used + i + 1 };\n }\n }\n used += nodes.length;\n if (opts.anyRecord || !more || read >= MAX_LISTING_READS) return { cards, hasMore: more, fetched: used };\n }\n}\n\n/** The catalog changes when a release loads it, not while someone browses. */\nconst CACHE_TTL_MS = 10 * 60_000;\nconst cache = new Map<string, { at: number; page: Promise<DesignCatalogPage> }>();\n\nexport function clearDesignCatalogCache(): void {\n cache.clear();\n}\n\n/**\n * One page of a catalog group straight from the backend, cached in memory for\n * ten minutes per (endpoint, filter). A failed read is not cached.\n */\nexport function fetchDesignCatalog(\n graphqlUrl: string,\n token: string | null | undefined,\n group: DesignCatalogGroup,\n opts: DesignCatalogOptions = {},\n): Promise<DesignCatalogPage> {\n const filter = designCatalogFilter(group, opts);\n return cached(`${graphqlUrl}|${JSON.stringify(filter)}`, () =>\n readDesignCatalogPage((pageFilter) => fetchDesignRows(graphqlUrl, token, pageFilter), group, opts),\n );\n}\n\nasync function fetchDesignRows(\n graphqlUrl: string,\n token: string | null | undefined,\n filter: DesignCatalogFilter,\n): Promise<ReadonlyArray<Record<string, any>>> {\n const res = await fetch(graphqlUrl, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n ...(token ? { authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({ query: DESIGN_CATALOG_QUERY, variables: { filter } }),\n });\n if (!res.ok) throw new Error(`Template catalog read failed (${res.status})`);\n const json = (await res.json().catch(() => ({}))) as {\n data?: { formTemplateSubmissions?: { nodes?: Array<Record<string, any>> | null } };\n errors?: Array<{ message?: string }>;\n };\n if (json.errors?.length) {\n throw new Error(\n json.errors\n .map((e) => e?.message)\n .filter(Boolean)\n .join('; ') || 'Template catalog read failed',\n );\n }\n const nodes = json.data?.formTemplateSubmissions?.nodes;\n return Array.isArray(nodes) ? nodes : [];\n}\n\nconst DESIGN_CATALOG_DOC = gql(DESIGN_CATALOG_QUERY);\n\n/** The same page through the host's Apollo client (no cache write: rows are tens of KB each). */\nexport function fetchDesignCatalogViaClient(\n client: Pick<StudioCatalogClient, 'query'>,\n group: DesignCatalogGroup,\n opts: DesignCatalogOptions = {},\n): Promise<DesignCatalogPage> {\n const filter = designCatalogFilter(group, opts);\n const readRows: DesignCatalogRowsRead = async (pageFilter) => {\n const { data } = await client.query({\n query: DESIGN_CATALOG_DOC,\n variables: { filter: pageFilter },\n fetchPolicy: 'no-cache',\n });\n const nodes = (data as { formTemplateSubmissions?: { nodes?: Array<Record<string, any>> | null } } | null)\n ?.formTemplateSubmissions?.nodes;\n return Array.isArray(nodes) ? nodes : [];\n };\n return cached(`apollo|${JSON.stringify(filter)}`, () => readDesignCatalogPage(readRows, group, opts));\n}\n\nfunction cached(key: string, read: () => Promise<DesignCatalogPage>): Promise<DesignCatalogPage> {\n const hit = cache.get(key);\n if (hit && Date.now() - hit.at < CACHE_TTL_MS) return hit.page;\n const page = read();\n cache.set(key, { at: Date.now(), page });\n page.catch(() => {\n if (cache.get(key)?.page === page) cache.delete(key);\n });\n return page;\n}\n\n/** Interleave two rails (flyer, slide, flyer, ...) and split them into two rows, like web TemplateRails. */\nexport function interleaveTemplateRows(\n a: readonly DesignCatalogCard[],\n b: readonly DesignCatalogCard[],\n): [DesignCatalogCard[], DesignCatalogCard[]] {\n const cards: DesignCatalogCard[] = [];\n for (let i = 0; i < Math.max(a.length, b.length); i += 1) {\n if (a[i]) cards.push(a[i]);\n if (b[i]) cards.push(b[i]);\n }\n const midpoint = Math.ceil(cards.length / 2);\n return [cards.slice(0, midpoint), cards.slice(midpoint)];\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -170,6 +170,46 @@ const DESIGN_CATEGORIES = [{
|
|
|
170
170
|
waiting: beingAdded("Infographic")
|
|
171
171
|
}],
|
|
172
172
|
sizes: [screen("infographic", "Infographic", 800, 2e3)]
|
|
173
|
+
}, {
|
|
174
|
+
id: "document",
|
|
175
|
+
title: "Documents",
|
|
176
|
+
shelves: [{
|
|
177
|
+
group: "canvas-document",
|
|
178
|
+
title: "Document templates",
|
|
179
|
+
noun: "documents",
|
|
180
|
+
waiting: beingAdded("Document")
|
|
181
|
+
}],
|
|
182
|
+
sizes: [print("document-letter", "Document (US Letter)", 8.5, 11, "in"), print("document-a4", "Document (A4)", 210, 297, "mm")]
|
|
183
|
+
}, {
|
|
184
|
+
id: "report",
|
|
185
|
+
title: "Reports",
|
|
186
|
+
shelves: [{
|
|
187
|
+
group: "canvas-report",
|
|
188
|
+
title: "Report templates",
|
|
189
|
+
noun: "reports",
|
|
190
|
+
waiting: beingAdded("Report")
|
|
191
|
+
}],
|
|
192
|
+
sizes: [print("report-letter", "Report (US Letter)", 8.5, 11, "in"), print("report-a4", "Report (A4)", 210, 297, "mm")]
|
|
193
|
+
}, {
|
|
194
|
+
id: "letter",
|
|
195
|
+
title: "Letters",
|
|
196
|
+
shelves: [{
|
|
197
|
+
group: "canvas-letter",
|
|
198
|
+
title: "Letter templates",
|
|
199
|
+
noun: "letters",
|
|
200
|
+
waiting: beingAdded("Letter")
|
|
201
|
+
}],
|
|
202
|
+
sizes: [print("letter-us", "Letter (US Letter)", 8.5, 11, "in"), print("letter-a4", "Letter (A4)", 210, 297, "mm")]
|
|
203
|
+
}, {
|
|
204
|
+
id: "resume",
|
|
205
|
+
title: "Resumes",
|
|
206
|
+
shelves: [{
|
|
207
|
+
group: "canvas-resume",
|
|
208
|
+
title: "Resume templates",
|
|
209
|
+
noun: "resumes",
|
|
210
|
+
waiting: beingAdded("Resume")
|
|
211
|
+
}],
|
|
212
|
+
sizes: [print("resume-letter", "Resume (US Letter)", 8.5, 11, "in"), print("resume-a4", "Resume (A4)", 210, 297, "mm")]
|
|
173
213
|
}, {
|
|
174
214
|
id: "technology",
|
|
175
215
|
title: "Technology",
|
|
@@ -251,6 +291,22 @@ const SEARCH_SECTIONS = [{
|
|
|
251
291
|
category: "infographic",
|
|
252
292
|
group: "canvas-infographic",
|
|
253
293
|
title: "Infographics"
|
|
294
|
+
}, {
|
|
295
|
+
category: "document",
|
|
296
|
+
group: "canvas-document",
|
|
297
|
+
title: "Documents"
|
|
298
|
+
}, {
|
|
299
|
+
category: "report",
|
|
300
|
+
group: "canvas-report",
|
|
301
|
+
title: "Reports"
|
|
302
|
+
}, {
|
|
303
|
+
category: "letter",
|
|
304
|
+
group: "canvas-letter",
|
|
305
|
+
title: "Letters"
|
|
306
|
+
}, {
|
|
307
|
+
category: "resume",
|
|
308
|
+
group: "canvas-resume",
|
|
309
|
+
title: "Resumes"
|
|
254
310
|
}];
|
|
255
311
|
function categoryIntro(category) {
|
|
256
312
|
var _a, _b;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"designCategories.js","sources":["../../../src/features/canvas/designCategories.ts"],"sourcesContent":["/**\n * Design categories as the category gallery shows them - native twin of\n * canvas-surface `editors/carousel-editor/components/StartPanel.tsx`\n * (CATALOG_CATEGORIES) and `utils/sizes.ts` (DESIGN_SIZES).\n *\n * A category is a Design & write tile id (`flyer`, `business-card`): its blank\n * sizes and its catalog shelves. Pure data: runs under jest as-is.\n */\nimport type { DesignCatalogGroup } from './designCatalog';\n\nexport interface DesignShelf {\n group: DesignCatalogGroup;\n title: string;\n /** \"No flyers match ...\" */\n noun: string;\n /** Only cards carrying this tag (pitch decks inside the presentation catalog). */\n tag?: string;\n /** Shown while the catalog has no templates yet. */\n waiting?: string;\n}\n\nexport interface BlankSize {\n id: string;\n label: string;\n /** Pixels (print sizes at the web's 150 DPI). */\n width: number;\n height: number;\n /** \"1080 × 1350\", \"8.5 × 11 in\" */\n detail: string;\n}\n\n/** A topic searches every format's catalog for its query; it has no sizes of its own. */\nexport interface DesignTopic {\n query: string;\n /** The line under the topic's title. */\n intro: string;\n}\n\nexport interface DesignCategory {\n id: string;\n title: string;\n shelves: DesignShelf[];\n sizes: BlankSize[];\n /** Set on a topic (Technology): previews of every format matching its query. */\n topic?: DesignTopic;\n}\n\n/** The line under a format's title (web StartPanel). */\nexport const FORMAT_INTRO = 'Choose a size to start fresh, or make a template your own.';\n\nfunction beingAdded(what: string): string {\n return `${what} templates are being added. Start from a size above for now.`;\n}\n\nconst DPI = 150;\nconst px = (value: number, unit: 'px' | 'in' | 'mm') =>\n unit === 'in' ? Math.round(value * DPI) : unit === 'mm' ? Math.round((value / 25.4) * DPI) : Math.round(value);\n\nconst screen = (id: string, label: string, width: number, height: number): BlankSize => ({\n id,\n label,\n width,\n height,\n detail: `${width} × ${height}`,\n});\n\nconst print = (id: string, label: string, w: number, h: number, unit: 'in' | 'mm'): BlankSize => ({\n id,\n label,\n width: px(w, unit),\n height: px(h, unit),\n detail: `${w} × ${h} ${unit}`,\n});\n\nexport const DESIGN_CATEGORIES: readonly DesignCategory[] = [\n {\n id: 'social',\n title: 'Social media',\n // Carousels are their own format: the Social media shelf lists social posts only.\n shelves: [{ group: 'canvas-social-post', title: 'Social media templates', noun: 'social posts' }],\n sizes: [\n screen('ig-post-portrait', 'Instagram post (4:5)', 1080, 1350),\n screen('ig-post-square', 'Instagram post (square)', 1080, 1080),\n screen('ig-story', 'Instagram story', 1080, 1920),\n screen('fb-post', 'Facebook post', 1200, 630),\n screen('li-post', 'LinkedIn post', 1200, 627),\n screen('x-post', 'X post', 1600, 900),\n screen('yt-thumb', 'YouTube thumbnail', 1280, 720),\n screen('pin', 'Pinterest pin', 1000, 1500),\n ],\n },\n {\n id: 'carousel',\n title: 'Carousels',\n shelves: [{ group: 'canvas-carousel', title: 'Carousel templates', noun: 'carousels' }],\n sizes: [\n screen('carousel-portrait', 'Carousel (4:5)', 1080, 1350),\n screen('carousel-square', 'Carousel (square)', 1080, 1080),\n screen('carousel-3-4', 'Carousel (3:4)', 1080, 1440),\n screen('carousel-tall', 'Carousel (2:3)', 1080, 1620),\n ],\n },\n {\n id: 'presentation',\n title: 'Presentations',\n shelves: [{ group: 'canvas-presentation', title: 'Presentation templates', noun: 'presentations' }],\n sizes: [\n screen('slides-16-9', 'Presentation (16:9)', 1920, 1080),\n screen('slides-4-3', 'Presentation (4:3)', 1024, 768),\n screen('slides-mobile', 'Presentation (mobile)', 1080, 1920),\n ],\n },\n {\n id: 'pitch-deck',\n title: 'Pitch decks',\n shelves: [\n { group: 'canvas-presentation', title: 'Pitch deck templates', noun: 'pitch decks', tag: 'pitch-deck' },\n ],\n sizes: [screen('slides-16-9', 'Presentation (16:9)', 1920, 1080)],\n },\n {\n id: 'flyer',\n title: 'Flyers',\n shelves: [{ group: 'canvas-flyer', title: 'Flyer templates', noun: 'flyers' }],\n sizes: [\n print('a4', 'A4 document', 210, 297, 'mm'),\n print('letter', 'Flyer (US Letter)', 8.5, 11, 'in'),\n print('a3', 'A3 poster', 297, 420, 'mm'),\n print('a2', 'A2 poster', 420, 594, 'mm'),\n print('poster-18-24', 'Poster', 18, 24, 'in'),\n print('invitation', 'Invitation', 5, 7, 'in'),\n print('postcard', 'Postcard', 6, 4, 'in'),\n ],\n },\n {\n id: 'business-card',\n title: 'Business cards',\n shelves: [{ group: 'canvas-business-card', title: 'Business card templates', noun: 'business cards' }],\n sizes: [\n print('business-card', 'Business card (US)', 3.5, 2, 'in'),\n print('business-card-eu', 'Business card (EU)', 85, 55, 'mm'),\n print('business-card-90x55', 'Business card (AU / NZ)', 90, 55, 'mm'),\n print('business-card-90x50', 'Business card (wide)', 90, 50, 'mm'),\n ],\n },\n {\n id: 'logo',\n title: 'Logos',\n shelves: [{ group: 'canvas-logo', title: 'Logo templates', noun: 'logos' }],\n sizes: [screen('logo', 'Logo', 500, 500), screen('logo-large', 'Logo (large)', 2000, 2000)],\n },\n {\n id: 'banner',\n title: 'Banners',\n shelves: [{ group: 'canvas-banner', title: 'Banner templates', noun: 'banners' }],\n sizes: [\n screen('banner-landscape', 'Banner (landscape)', 4800, 2400),\n screen('banner-portrait', 'Banner (portrait)', 2400, 4800),\n screen('linkedin-banner', 'LinkedIn banner', 1584, 396),\n screen('youtube-banner', 'YouTube banner', 2560, 1440),\n screen('x-header', 'X header', 1500, 500),\n screen('facebook-cover', 'Facebook cover', 1640, 624),\n screen('web-banner', 'Web banner', 728, 90),\n ],\n },\n {\n id: 'brochure',\n title: 'Brochures',\n shelves: [{ group: 'canvas-brochure', title: 'Brochure templates', noun: 'brochures' }],\n sizes: [\n print('brochure-letter', 'Brochure (US Letter)', 11, 8.5, 'in'),\n print('brochure-a4', 'Brochure (A4)', 297, 210, 'mm'),\n print('brochure-tabloid', 'Brochure (tabloid)', 17, 11, 'in'),\n ],\n },\n {\n id: 'branding',\n title: 'Branding',\n shelves: [{ group: 'canvas-branding', title: 'Branding templates', noun: 'letterheads or envelopes' }],\n sizes: [\n print('letterhead-a4', 'Letterhead (A4)', 210, 297, 'mm'),\n print('letterhead-letter', 'Letterhead (US Letter)', 8.5, 11, 'in'),\n print('envelope-10', 'Envelope (#10)', 9.5, 4.125, 'in'),\n print('envelope-dl', 'Envelope (DL)', 220, 110, 'mm'),\n ],\n },\n {\n id: 'certificate',\n title: 'Certificates',\n shelves: [\n {\n group: 'canvas-certificate',\n title: 'Certificate templates',\n noun: 'certificates',\n waiting: beingAdded('Certificate'),\n },\n ],\n sizes: [\n print('certificate-letter', 'Certificate (US Letter)', 11, 8.5, 'in'),\n print('certificate-a4', 'Certificate (A4)', 297, 210, 'mm'),\n print('certificate-portrait', 'Certificate (portrait)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'worksheet',\n title: 'Worksheets',\n shelves: [\n {\n group: 'canvas-worksheet',\n title: 'Worksheet templates',\n noun: 'worksheets',\n waiting: beingAdded('Worksheet'),\n },\n ],\n sizes: [\n print('worksheet-letter', 'Worksheet (US Letter)', 8.5, 11, 'in'),\n print('worksheet-a4', 'Worksheet (A4)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'proposal',\n title: 'Proposals',\n shelves: [\n {\n group: 'canvas-proposal',\n title: 'Proposal templates',\n noun: 'proposals',\n waiting: beingAdded('Proposal'),\n },\n ],\n sizes: [\n print('proposal-letter', 'Proposal (US Letter)', 8.5, 11, 'in'),\n print('proposal-a4', 'Proposal (A4)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'newsletter',\n title: 'Newsletters',\n shelves: [\n {\n group: 'canvas-newsletter',\n title: 'Newsletter templates',\n noun: 'newsletters',\n waiting: beingAdded('Newsletter'),\n },\n ],\n sizes: [\n print('newsletter-letter', 'Newsletter (US Letter)', 8.5, 11, 'in'),\n print('newsletter-a4', 'Newsletter (A4)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'menu',\n title: 'Menus',\n shelves: [{ group: 'canvas-menu', title: 'Menu templates', noun: 'menus', waiting: beingAdded('Menu') }],\n sizes: [\n print('menu-letter', 'Menu (US Letter)', 8.5, 11, 'in'),\n print('menu-a4', 'Menu (A4)', 210, 297, 'mm'),\n print('menu-tabloid', 'Menu (tabloid)', 11, 17, 'in'),\n ],\n },\n {\n id: 'infographic',\n title: 'Infographics',\n shelves: [\n {\n group: 'canvas-infographic',\n title: 'Infographic templates',\n noun: 'infographics',\n waiting: beingAdded('Infographic'),\n },\n ],\n sizes: [screen('infographic', 'Infographic', 800, 2000)],\n },\n {\n id: 'technology',\n title: 'Technology',\n shelves: [],\n sizes: [],\n topic: {\n query: 'technology',\n intro: 'Technology templates in every format: decks, social posts, flyers, logos and more.',\n },\n },\n];\n\n/** Formats: a category with sizes and its own catalog shelves. */\nexport const DESIGN_FORMATS: readonly DesignCategory[] = DESIGN_CATEGORIES.filter((c) => !c.topic);\n/** Topics: a query searched in every format's catalog (Technology). */\nexport const DESIGN_TOPICS: readonly DesignCategory[] = DESIGN_CATEGORIES.filter((c) => c.topic);\n\n/** Category navigation groups, as the web studio lists them: Formats, then Topics. */\nexport const DESIGN_CATEGORY_GROUPS: readonly {\n id: 'formats' | 'topics';\n label: string;\n items: readonly DesignCategory[];\n}[] = [\n { id: 'formats', label: 'Formats', items: DESIGN_FORMATS },\n { id: 'topics', label: 'Topics', items: DESIGN_TOPICS },\n];\n\n/** A search outside any format, and a topic: the top matches of every catalog, in this order. */\nexport const SEARCH_SECTIONS: readonly { category: string; group: DesignCatalogGroup; title: string }[] = [\n { category: 'flyer', group: 'canvas-flyer', title: 'Flyers' },\n { category: 'presentation', group: 'canvas-presentation', title: 'Presentations' },\n { category: 'social', group: 'canvas-social-post', title: 'Social media' },\n { category: 'carousel', group: 'canvas-carousel', title: 'Carousels' },\n { category: 'business-card', group: 'canvas-business-card', title: 'Business cards' },\n { category: 'logo', group: 'canvas-logo', title: 'Logos' },\n { category: 'banner', group: 'canvas-banner', title: 'Banners' },\n { category: 'brochure', group: 'canvas-brochure', title: 'Brochures' },\n { category: 'branding', group: 'canvas-branding', title: 'Branding' },\n { category: 'certificate', group: 'canvas-certificate', title: 'Certificates' },\n { category: 'worksheet', group: 'canvas-worksheet', title: 'Worksheets' },\n { category: 'proposal', group: 'canvas-proposal', title: 'Proposals' },\n { category: 'newsletter', group: 'canvas-newsletter', title: 'Newsletters' },\n { category: 'menu', group: 'canvas-menu', title: 'Menus' },\n { category: 'infographic', group: 'canvas-infographic', title: 'Infographics' },\n];\n\n/** The line under a category's title: a topic's intro, else the format line. */\nexport function categoryIntro(category: DesignCategory): string {\n return category.topic?.intro ?? FORMAT_INTRO;\n}\n\n/** The gallery for a Design & write tile id, or null (doc, custom, t-shirt open straight away). */\nexport function designCategoryFor(tileId: string): DesignCategory | null {\n return DESIGN_CATEGORIES.find((c) => c.id === tileId) ?? null;\n}\n\n/** The category \"See all\" on a template rail opens. */\nexport function categoryOfGroup(group: DesignCatalogGroup): DesignCategory | null {\n return DESIGN_CATEGORIES.find((c) => c.shelves[0]?.group === group && !c.shelves[0].tag) ?? null;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"designCategories.js","sources":["../../../src/features/canvas/designCategories.ts"],"sourcesContent":["/**\n * Design categories as the category gallery shows them - native twin of\n * canvas-surface `editors/carousel-editor/components/StartPanel.tsx`\n * (CATALOG_CATEGORIES) and `utils/sizes.ts` (DESIGN_SIZES).\n *\n * A category is a Design & write tile id (`flyer`, `business-card`): its blank\n * sizes and its catalog shelves. Pure data: runs under jest as-is.\n */\nimport type { DesignCatalogGroup } from './designCatalog';\n\nexport interface DesignShelf {\n group: DesignCatalogGroup;\n title: string;\n /** \"No flyers match ...\" */\n noun: string;\n /** Only cards carrying this tag (pitch decks inside the presentation catalog). */\n tag?: string;\n /** Shown while the catalog has no templates yet. */\n waiting?: string;\n}\n\nexport interface BlankSize {\n id: string;\n label: string;\n /** Pixels (print sizes at the web's 150 DPI). */\n width: number;\n height: number;\n /** \"1080 × 1350\", \"8.5 × 11 in\" */\n detail: string;\n}\n\n/** A topic searches every format's catalog for its query; it has no sizes of its own. */\nexport interface DesignTopic {\n query: string;\n /** The line under the topic's title. */\n intro: string;\n}\n\nexport interface DesignCategory {\n id: string;\n title: string;\n shelves: DesignShelf[];\n sizes: BlankSize[];\n /** Set on a topic (Technology): previews of every format matching its query. */\n topic?: DesignTopic;\n}\n\n/** The line under a format's title (web StartPanel). */\nexport const FORMAT_INTRO = 'Choose a size to start fresh, or make a template your own.';\n\nfunction beingAdded(what: string): string {\n return `${what} templates are being added. Start from a size above for now.`;\n}\n\nconst DPI = 150;\nconst px = (value: number, unit: 'px' | 'in' | 'mm') =>\n unit === 'in' ? Math.round(value * DPI) : unit === 'mm' ? Math.round((value / 25.4) * DPI) : Math.round(value);\n\nconst screen = (id: string, label: string, width: number, height: number): BlankSize => ({\n id,\n label,\n width,\n height,\n detail: `${width} × ${height}`,\n});\n\nconst print = (id: string, label: string, w: number, h: number, unit: 'in' | 'mm'): BlankSize => ({\n id,\n label,\n width: px(w, unit),\n height: px(h, unit),\n detail: `${w} × ${h} ${unit}`,\n});\n\nexport const DESIGN_CATEGORIES: readonly DesignCategory[] = [\n {\n id: 'social',\n title: 'Social media',\n // Carousels are their own format: the Social media shelf lists social posts only.\n shelves: [{ group: 'canvas-social-post', title: 'Social media templates', noun: 'social posts' }],\n sizes: [\n screen('ig-post-portrait', 'Instagram post (4:5)', 1080, 1350),\n screen('ig-post-square', 'Instagram post (square)', 1080, 1080),\n screen('ig-story', 'Instagram story', 1080, 1920),\n screen('fb-post', 'Facebook post', 1200, 630),\n screen('li-post', 'LinkedIn post', 1200, 627),\n screen('x-post', 'X post', 1600, 900),\n screen('yt-thumb', 'YouTube thumbnail', 1280, 720),\n screen('pin', 'Pinterest pin', 1000, 1500),\n ],\n },\n {\n id: 'carousel',\n title: 'Carousels',\n shelves: [{ group: 'canvas-carousel', title: 'Carousel templates', noun: 'carousels' }],\n sizes: [\n screen('carousel-portrait', 'Carousel (4:5)', 1080, 1350),\n screen('carousel-square', 'Carousel (square)', 1080, 1080),\n screen('carousel-3-4', 'Carousel (3:4)', 1080, 1440),\n screen('carousel-tall', 'Carousel (2:3)', 1080, 1620),\n ],\n },\n {\n id: 'presentation',\n title: 'Presentations',\n shelves: [{ group: 'canvas-presentation', title: 'Presentation templates', noun: 'presentations' }],\n sizes: [\n screen('slides-16-9', 'Presentation (16:9)', 1920, 1080),\n screen('slides-4-3', 'Presentation (4:3)', 1024, 768),\n screen('slides-mobile', 'Presentation (mobile)', 1080, 1920),\n ],\n },\n {\n id: 'pitch-deck',\n title: 'Pitch decks',\n shelves: [\n { group: 'canvas-presentation', title: 'Pitch deck templates', noun: 'pitch decks', tag: 'pitch-deck' },\n ],\n sizes: [screen('slides-16-9', 'Presentation (16:9)', 1920, 1080)],\n },\n {\n id: 'flyer',\n title: 'Flyers',\n shelves: [{ group: 'canvas-flyer', title: 'Flyer templates', noun: 'flyers' }],\n sizes: [\n print('a4', 'A4 document', 210, 297, 'mm'),\n print('letter', 'Flyer (US Letter)', 8.5, 11, 'in'),\n print('a3', 'A3 poster', 297, 420, 'mm'),\n print('a2', 'A2 poster', 420, 594, 'mm'),\n print('poster-18-24', 'Poster', 18, 24, 'in'),\n print('invitation', 'Invitation', 5, 7, 'in'),\n print('postcard', 'Postcard', 6, 4, 'in'),\n ],\n },\n {\n id: 'business-card',\n title: 'Business cards',\n shelves: [{ group: 'canvas-business-card', title: 'Business card templates', noun: 'business cards' }],\n sizes: [\n print('business-card', 'Business card (US)', 3.5, 2, 'in'),\n print('business-card-eu', 'Business card (EU)', 85, 55, 'mm'),\n print('business-card-90x55', 'Business card (AU / NZ)', 90, 55, 'mm'),\n print('business-card-90x50', 'Business card (wide)', 90, 50, 'mm'),\n ],\n },\n {\n id: 'logo',\n title: 'Logos',\n shelves: [{ group: 'canvas-logo', title: 'Logo templates', noun: 'logos' }],\n sizes: [screen('logo', 'Logo', 500, 500), screen('logo-large', 'Logo (large)', 2000, 2000)],\n },\n {\n id: 'banner',\n title: 'Banners',\n shelves: [{ group: 'canvas-banner', title: 'Banner templates', noun: 'banners' }],\n sizes: [\n screen('banner-landscape', 'Banner (landscape)', 4800, 2400),\n screen('banner-portrait', 'Banner (portrait)', 2400, 4800),\n screen('linkedin-banner', 'LinkedIn banner', 1584, 396),\n screen('youtube-banner', 'YouTube banner', 2560, 1440),\n screen('x-header', 'X header', 1500, 500),\n screen('facebook-cover', 'Facebook cover', 1640, 624),\n screen('web-banner', 'Web banner', 728, 90),\n ],\n },\n {\n id: 'brochure',\n title: 'Brochures',\n shelves: [{ group: 'canvas-brochure', title: 'Brochure templates', noun: 'brochures' }],\n sizes: [\n print('brochure-letter', 'Brochure (US Letter)', 11, 8.5, 'in'),\n print('brochure-a4', 'Brochure (A4)', 297, 210, 'mm'),\n print('brochure-tabloid', 'Brochure (tabloid)', 17, 11, 'in'),\n ],\n },\n {\n id: 'branding',\n title: 'Branding',\n shelves: [{ group: 'canvas-branding', title: 'Branding templates', noun: 'letterheads or envelopes' }],\n sizes: [\n print('letterhead-a4', 'Letterhead (A4)', 210, 297, 'mm'),\n print('letterhead-letter', 'Letterhead (US Letter)', 8.5, 11, 'in'),\n print('envelope-10', 'Envelope (#10)', 9.5, 4.125, 'in'),\n print('envelope-dl', 'Envelope (DL)', 220, 110, 'mm'),\n ],\n },\n {\n id: 'certificate',\n title: 'Certificates',\n shelves: [\n {\n group: 'canvas-certificate',\n title: 'Certificate templates',\n noun: 'certificates',\n waiting: beingAdded('Certificate'),\n },\n ],\n sizes: [\n print('certificate-letter', 'Certificate (US Letter)', 11, 8.5, 'in'),\n print('certificate-a4', 'Certificate (A4)', 297, 210, 'mm'),\n print('certificate-portrait', 'Certificate (portrait)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'worksheet',\n title: 'Worksheets',\n shelves: [\n {\n group: 'canvas-worksheet',\n title: 'Worksheet templates',\n noun: 'worksheets',\n waiting: beingAdded('Worksheet'),\n },\n ],\n sizes: [\n print('worksheet-letter', 'Worksheet (US Letter)', 8.5, 11, 'in'),\n print('worksheet-a4', 'Worksheet (A4)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'proposal',\n title: 'Proposals',\n shelves: [\n {\n group: 'canvas-proposal',\n title: 'Proposal templates',\n noun: 'proposals',\n waiting: beingAdded('Proposal'),\n },\n ],\n sizes: [\n print('proposal-letter', 'Proposal (US Letter)', 8.5, 11, 'in'),\n print('proposal-a4', 'Proposal (A4)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'newsletter',\n title: 'Newsletters',\n shelves: [\n {\n group: 'canvas-newsletter',\n title: 'Newsletter templates',\n noun: 'newsletters',\n waiting: beingAdded('Newsletter'),\n },\n ],\n sizes: [\n print('newsletter-letter', 'Newsletter (US Letter)', 8.5, 11, 'in'),\n print('newsletter-a4', 'Newsletter (A4)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'menu',\n title: 'Menus',\n shelves: [{ group: 'canvas-menu', title: 'Menu templates', noun: 'menus', waiting: beingAdded('Menu') }],\n sizes: [\n print('menu-letter', 'Menu (US Letter)', 8.5, 11, 'in'),\n print('menu-a4', 'Menu (A4)', 210, 297, 'mm'),\n print('menu-tabloid', 'Menu (tabloid)', 11, 17, 'in'),\n ],\n },\n {\n id: 'infographic',\n title: 'Infographics',\n shelves: [\n {\n group: 'canvas-infographic',\n title: 'Infographic templates',\n noun: 'infographics',\n waiting: beingAdded('Infographic'),\n },\n ],\n sizes: [screen('infographic', 'Infographic', 800, 2000)],\n },\n {\n id: 'document',\n title: 'Documents',\n shelves: [\n {\n group: 'canvas-document',\n title: 'Document templates',\n noun: 'documents',\n waiting: beingAdded('Document'),\n },\n ],\n sizes: [\n print('document-letter', 'Document (US Letter)', 8.5, 11, 'in'),\n print('document-a4', 'Document (A4)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'report',\n title: 'Reports',\n shelves: [\n { group: 'canvas-report', title: 'Report templates', noun: 'reports', waiting: beingAdded('Report') },\n ],\n sizes: [\n print('report-letter', 'Report (US Letter)', 8.5, 11, 'in'),\n print('report-a4', 'Report (A4)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'letter',\n title: 'Letters',\n shelves: [\n { group: 'canvas-letter', title: 'Letter templates', noun: 'letters', waiting: beingAdded('Letter') },\n ],\n sizes: [\n print('letter-us', 'Letter (US Letter)', 8.5, 11, 'in'),\n print('letter-a4', 'Letter (A4)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'resume',\n title: 'Resumes',\n shelves: [\n { group: 'canvas-resume', title: 'Resume templates', noun: 'resumes', waiting: beingAdded('Resume') },\n ],\n sizes: [\n print('resume-letter', 'Resume (US Letter)', 8.5, 11, 'in'),\n print('resume-a4', 'Resume (A4)', 210, 297, 'mm'),\n ],\n },\n {\n id: 'technology',\n title: 'Technology',\n shelves: [],\n sizes: [],\n topic: {\n query: 'technology',\n intro: 'Technology templates in every format: decks, social posts, flyers, logos and more.',\n },\n },\n];\n\n/** Formats: a category with sizes and its own catalog shelves. */\nexport const DESIGN_FORMATS: readonly DesignCategory[] = DESIGN_CATEGORIES.filter((c) => !c.topic);\n/** Topics: a query searched in every format's catalog (Technology). */\nexport const DESIGN_TOPICS: readonly DesignCategory[] = DESIGN_CATEGORIES.filter((c) => c.topic);\n\n/** Category navigation groups, as the web studio lists them: Formats, then Topics. */\nexport const DESIGN_CATEGORY_GROUPS: readonly {\n id: 'formats' | 'topics';\n label: string;\n items: readonly DesignCategory[];\n}[] = [\n { id: 'formats', label: 'Formats', items: DESIGN_FORMATS },\n { id: 'topics', label: 'Topics', items: DESIGN_TOPICS },\n];\n\n/** A search outside any format, and a topic: the top matches of every catalog, in this order. */\nexport const SEARCH_SECTIONS: readonly { category: string; group: DesignCatalogGroup; title: string }[] = [\n { category: 'flyer', group: 'canvas-flyer', title: 'Flyers' },\n { category: 'presentation', group: 'canvas-presentation', title: 'Presentations' },\n { category: 'social', group: 'canvas-social-post', title: 'Social media' },\n { category: 'carousel', group: 'canvas-carousel', title: 'Carousels' },\n { category: 'business-card', group: 'canvas-business-card', title: 'Business cards' },\n { category: 'logo', group: 'canvas-logo', title: 'Logos' },\n { category: 'banner', group: 'canvas-banner', title: 'Banners' },\n { category: 'brochure', group: 'canvas-brochure', title: 'Brochures' },\n { category: 'branding', group: 'canvas-branding', title: 'Branding' },\n { category: 'certificate', group: 'canvas-certificate', title: 'Certificates' },\n { category: 'worksheet', group: 'canvas-worksheet', title: 'Worksheets' },\n { category: 'proposal', group: 'canvas-proposal', title: 'Proposals' },\n { category: 'newsletter', group: 'canvas-newsletter', title: 'Newsletters' },\n { category: 'menu', group: 'canvas-menu', title: 'Menus' },\n { category: 'infographic', group: 'canvas-infographic', title: 'Infographics' },\n { category: 'document', group: 'canvas-document', title: 'Documents' },\n { category: 'report', group: 'canvas-report', title: 'Reports' },\n { category: 'letter', group: 'canvas-letter', title: 'Letters' },\n { category: 'resume', group: 'canvas-resume', title: 'Resumes' },\n];\n\n/** The line under a category's title: a topic's intro, else the format line. */\nexport function categoryIntro(category: DesignCategory): string {\n return category.topic?.intro ?? FORMAT_INTRO;\n}\n\n/** The gallery for a Design & write tile id, or null (doc, custom, t-shirt open straight away). */\nexport function designCategoryFor(tileId: string): DesignCategory | null {\n return DESIGN_CATEGORIES.find((c) => c.id === tileId) ?? null;\n}\n\n/** The category \"See all\" on a template rail opens. */\nexport function categoryOfGroup(group: DesignCatalogGroup): DesignCategory | null {\n return DESIGN_CATEGORIES.find((c) => c.shelves[0]?.group === group && !c.shelves[0].tag) ?? null;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -36,11 +36,12 @@ function DirectorSheet({
|
|
|
36
36
|
value,
|
|
37
37
|
onChange,
|
|
38
38
|
onClose,
|
|
39
|
-
prompt
|
|
39
|
+
prompt,
|
|
40
|
+
initialTab = "camera"
|
|
40
41
|
}) {
|
|
41
42
|
const theme = useCanvasTheme();
|
|
42
43
|
const styles = useMemo(() => makeStyles(theme), [theme]);
|
|
43
|
-
const [tab, setTab] = useState(
|
|
44
|
+
const [tab, setTab] = useState(initialTab);
|
|
44
45
|
const {
|
|
45
46
|
camera,
|
|
46
47
|
cinematic
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DirectorSheet.js","sources":["../../../../src/features/canvas/generator/DirectorSheet.tsx"],"sourcesContent":["/**\n * Camera + cinematic pickers for the video lane (native twin of the web's\n * camera panel and CinematicModal). Bottom-sheet chip grids instead of the\n * web's ring and wheel: the same vocabulary, picked with a thumb. Every pick\n * toggles, and an empty setup adds nothing to the prompt.\n */\nimport React, { useMemo, useState } from 'react';\nimport { StyleSheet, Text, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { useCanvasTheme, themedStyles, type CanvasPalette } from '../canvasTheme';\nimport { Pressable, RADIUS, SPACE, Segmented, TYPE, pressedStyle } from '../canvasUi';\nimport { APERTURES, CAMERA_ANGLES, CAMERA_MOVES, FILM_STOCKS, FOCAL_LENGTHS, SHOT_SIZES } from './cameraVocabulary';\nimport { ERAS, GENRES, LIGHTING, PALETTES, TEMPOS } from './cinematicVocabulary';\nimport { ChipGrid, GeneratorBottomSheet } from './BottomSheet';\nimport { directedPrompt, directionCount, directionSummary, toggleField, type Direction } from './direction';\n\ntype Tab = 'camera' | 'film' | 'look';\nconst TABS: ReadonlyArray<{ id: Tab; label: string }> = [\n { id: 'camera', label: 'Camera' },\n { id: 'film', label: 'Film' },\n { id: 'look', label: 'Look' },\n];\n\nconst labelled = (list: ReadonlyArray<{ label: string; hint?: string }>) =>\n list.map((o) => ({ id: o.label, label: o.label, hint: o.hint }));\n\nexport function DirectorSheet({\n value,\n onChange,\n onClose,\n prompt,\n}: {\n value: Direction;\n onChange: (next: Direction) => void;\n onClose: () => void;\n /** The brief, so the sheet can show what the model will read. */\n prompt?: string;\n}) {\n const theme = useCanvasTheme();\n const styles = useMemo(() => makeStyles(theme), [theme]);\n const [tab, setTab] = useState<Tab>('camera');\n const { camera, cinematic } = value;\n const setCamera = <K extends keyof typeof camera>(key: K, v: (typeof camera)[K]) =>\n onChange({ ...value, camera: toggleField(camera, key, v) });\n const setFilm = <K extends keyof typeof cinematic>(key: K, v: (typeof cinematic)[K]) =>\n onChange({ ...value, cinematic: toggleField(cinematic, key, v) });\n const preview = directedPrompt(prompt?.trim() || 'Your brief', value);\n const count = directionCount(value);\n\n return (\n <GeneratorBottomSheet\n title=\"Direct the shot\"\n onClose={onClose}\n testID=\"director-sheet\"\n footer={\n <View style={styles.footer}>\n <Text style={styles.preview} numberOfLines={3}>\n {count ? preview : 'Nothing set: the prompt goes as you wrote it.'}\n </Text>\n {count ? (\n <Pressable\n onPress={() => onChange({ camera: {}, cinematic: {} })}\n style={({ pressed }) => [styles.reset, pressedStyle(pressed)]}\n accessibilityRole=\"button\"\n >\n <MaterialCommunityIcons name=\"restore\" size={14} color={theme.foreground} />\n <Text style={styles.resetLabel}>Clear</Text>\n </Pressable>\n ) : null}\n </View>\n }\n >\n <Segmented options={TABS} value={tab} onChange={setTab} style={styles.tabs} />\n {tab === 'camera' ? (\n <>\n <ChipGrid\n label=\"Shot size\"\n options={labelled(SHOT_SIZES)}\n value={camera.shot}\n onChange={(v) => setCamera('shot', v)}\n />\n <ChipGrid\n label=\"Move\"\n options={labelled(CAMERA_MOVES)}\n value={camera.move}\n onChange={(v) => setCamera('move', v)}\n />\n <ChipGrid\n label=\"Angle\"\n options={labelled(CAMERA_ANGLES)}\n value={camera.angle}\n onChange={(v) => setCamera('angle', v)}\n />\n <ChipGrid\n label=\"Lens\"\n options={FOCAL_LENGTHS.map((f) => ({ id: f.mm, label: f.label }))}\n value={camera.lensMm}\n onChange={(v) => setCamera('lensMm', v)}\n />\n <ChipGrid\n label=\"Aperture\"\n options={labelled(APERTURES)}\n value={camera.aperture}\n onChange={(v) => setCamera('aperture', v)}\n />\n <ChipGrid\n label=\"Format\"\n options={labelled(FILM_STOCKS)}\n value={camera.stock}\n onChange={(v) => setCamera('stock', v)}\n />\n </>\n ) : tab === 'film' ? (\n <>\n <ChipGrid\n label=\"Genre\"\n options={labelled(GENRES)}\n value={cinematic.genre}\n onChange={(v) => setFilm('genre', v)}\n swatch={(id) => {\n const g = GENRES.find((o) => o.label === id);\n return g ? [g.art.from, g.art.to] : undefined;\n }}\n />\n <ChipGrid\n label=\"Era\"\n options={labelled(ERAS)}\n value={cinematic.era}\n onChange={(v) => setFilm('era', v)}\n swatch={(id) => {\n const e = ERAS.find((o) => o.label === id);\n return e ? [e.art.from, e.art.to] : undefined;\n }}\n />\n <ChipGrid\n label=\"Tempo\"\n options={labelled(TEMPOS)}\n value={cinematic.tempo}\n onChange={(v) => setFilm('tempo', v)}\n />\n </>\n ) : (\n <>\n <ChipGrid\n label=\"Lighting\"\n options={labelled(LIGHTING)}\n value={cinematic.lighting}\n onChange={(v) => setFilm('lighting', v)}\n swatch={(id) => {\n const l = LIGHTING.find((o) => o.label === id);\n return l ? [l.light.key, l.light.ambient] : undefined;\n }}\n />\n <ChipGrid\n label=\"Palette\"\n options={labelled(PALETTES)}\n value={cinematic.palette}\n onChange={(v) => setFilm('palette', v)}\n swatch={(id) => {\n const p = PALETTES.find((o) => o.label === id);\n return p ? [...p.swatches] : undefined;\n }}\n />\n </>\n )}\n </GeneratorBottomSheet>\n );\n}\n\n/** The pill that opens the sheet: \"Direct\" when empty, else what is set. */\nexport function DirectorPill({ value, onPress }: { value: Direction; onPress: () => void }) {\n const theme = useCanvasTheme();\n const styles = useMemo(() => makeStyles(theme), [theme]);\n const summary = directionSummary(value);\n const on = Boolean(summary);\n return (\n <Pressable\n onPress={onPress}\n style={({ pressed }) => [styles.pill, on && styles.pillOn, pressedStyle(pressed)]}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Camera and film direction\"\n >\n <MaterialCommunityIcons\n name=\"movie-open-cog-outline\"\n size={14}\n color={on ? theme.background : theme.mutedForeground}\n />\n <Text style={[styles.pillLabel, on && styles.pillLabelOn]} numberOfLines={1}>\n {summary || 'Direct'}\n </Text>\n </Pressable>\n );\n}\n\nconst makeStyles = themedStyles((theme: CanvasPalette) =>\n StyleSheet.create({\n tabs: { flexGrow: 0, alignSelf: 'flex-start' },\n footer: { flexDirection: 'row', alignItems: 'center', gap: SPACE.sm },\n preview: { ...TYPE.caption, flex: 1, fontWeight: '400', color: theme.mutedForeground },\n reset: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: SPACE.xs,\n minHeight: 32,\n paddingHorizontal: SPACE.md,\n borderRadius: RADIUS.pill,\n backgroundColor: theme.card,\n },\n resetLabel: { ...TYPE.label, color: theme.foreground },\n pill: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: SPACE.sm - 2,\n minHeight: 36,\n paddingHorizontal: SPACE.md + 2,\n borderRadius: RADIUS.pill,\n backgroundColor: theme.card,\n maxWidth: 220,\n },\n pillOn: { backgroundColor: theme.foreground },\n pillLabel: { ...TYPE.label, flexShrink: 1, color: theme.foreground },\n pillLabelOn: { color: theme.background },\n }),\n);\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DirectorSheet.js","sources":["../../../../src/features/canvas/generator/DirectorSheet.tsx"],"sourcesContent":["/**\n * Camera + cinematic pickers for the video lane (native twin of the web's\n * camera panel and CinematicModal). Bottom-sheet chip grids instead of the\n * web's ring and wheel: the same vocabulary, picked with a thumb. Every pick\n * toggles, and an empty setup adds nothing to the prompt.\n */\nimport React, { useMemo, useState } from 'react';\nimport { StyleSheet, Text, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { useCanvasTheme, themedStyles, type CanvasPalette } from '../canvasTheme';\nimport { Pressable, RADIUS, SPACE, Segmented, TYPE, pressedStyle } from '../canvasUi';\nimport { APERTURES, CAMERA_ANGLES, CAMERA_MOVES, FILM_STOCKS, FOCAL_LENGTHS, SHOT_SIZES } from './cameraVocabulary';\nimport { ERAS, GENRES, LIGHTING, PALETTES, TEMPOS } from './cinematicVocabulary';\nimport { ChipGrid, GeneratorBottomSheet } from './BottomSheet';\nimport { directedPrompt, directionCount, directionSummary, toggleField, type Direction } from './direction';\n\ntype Tab = 'camera' | 'film' | 'look';\nexport type DirectorTab = Tab;\nconst TABS: ReadonlyArray<{ id: Tab; label: string }> = [\n { id: 'camera', label: 'Camera' },\n { id: 'film', label: 'Film' },\n { id: 'look', label: 'Look' },\n];\n\nconst labelled = (list: ReadonlyArray<{ label: string; hint?: string }>) =>\n list.map((o) => ({ id: o.label, label: o.label, hint: o.hint }));\n\nexport function DirectorSheet({\n value,\n onChange,\n onClose,\n prompt,\n initialTab = 'camera',\n}: {\n /** Which group the sheet opens on (the hero's Film setup / Camera / Palette / Lighting chips). */\n initialTab?: Tab;\n value: Direction;\n onChange: (next: Direction) => void;\n onClose: () => void;\n /** The brief, so the sheet can show what the model will read. */\n prompt?: string;\n}) {\n const theme = useCanvasTheme();\n const styles = useMemo(() => makeStyles(theme), [theme]);\n const [tab, setTab] = useState<Tab>(initialTab);\n const { camera, cinematic } = value;\n const setCamera = <K extends keyof typeof camera>(key: K, v: (typeof camera)[K]) =>\n onChange({ ...value, camera: toggleField(camera, key, v) });\n const setFilm = <K extends keyof typeof cinematic>(key: K, v: (typeof cinematic)[K]) =>\n onChange({ ...value, cinematic: toggleField(cinematic, key, v) });\n const preview = directedPrompt(prompt?.trim() || 'Your brief', value);\n const count = directionCount(value);\n\n return (\n <GeneratorBottomSheet\n title=\"Direct the shot\"\n onClose={onClose}\n testID=\"director-sheet\"\n footer={\n <View style={styles.footer}>\n <Text style={styles.preview} numberOfLines={3}>\n {count ? preview : 'Nothing set: the prompt goes as you wrote it.'}\n </Text>\n {count ? (\n <Pressable\n onPress={() => onChange({ camera: {}, cinematic: {} })}\n style={({ pressed }) => [styles.reset, pressedStyle(pressed)]}\n accessibilityRole=\"button\"\n >\n <MaterialCommunityIcons name=\"restore\" size={14} color={theme.foreground} />\n <Text style={styles.resetLabel}>Clear</Text>\n </Pressable>\n ) : null}\n </View>\n }\n >\n <Segmented options={TABS} value={tab} onChange={setTab} style={styles.tabs} />\n {tab === 'camera' ? (\n <>\n <ChipGrid\n label=\"Shot size\"\n options={labelled(SHOT_SIZES)}\n value={camera.shot}\n onChange={(v) => setCamera('shot', v)}\n />\n <ChipGrid\n label=\"Move\"\n options={labelled(CAMERA_MOVES)}\n value={camera.move}\n onChange={(v) => setCamera('move', v)}\n />\n <ChipGrid\n label=\"Angle\"\n options={labelled(CAMERA_ANGLES)}\n value={camera.angle}\n onChange={(v) => setCamera('angle', v)}\n />\n <ChipGrid\n label=\"Lens\"\n options={FOCAL_LENGTHS.map((f) => ({ id: f.mm, label: f.label }))}\n value={camera.lensMm}\n onChange={(v) => setCamera('lensMm', v)}\n />\n <ChipGrid\n label=\"Aperture\"\n options={labelled(APERTURES)}\n value={camera.aperture}\n onChange={(v) => setCamera('aperture', v)}\n />\n <ChipGrid\n label=\"Format\"\n options={labelled(FILM_STOCKS)}\n value={camera.stock}\n onChange={(v) => setCamera('stock', v)}\n />\n </>\n ) : tab === 'film' ? (\n <>\n <ChipGrid\n label=\"Genre\"\n options={labelled(GENRES)}\n value={cinematic.genre}\n onChange={(v) => setFilm('genre', v)}\n swatch={(id) => {\n const g = GENRES.find((o) => o.label === id);\n return g ? [g.art.from, g.art.to] : undefined;\n }}\n />\n <ChipGrid\n label=\"Era\"\n options={labelled(ERAS)}\n value={cinematic.era}\n onChange={(v) => setFilm('era', v)}\n swatch={(id) => {\n const e = ERAS.find((o) => o.label === id);\n return e ? [e.art.from, e.art.to] : undefined;\n }}\n />\n <ChipGrid\n label=\"Tempo\"\n options={labelled(TEMPOS)}\n value={cinematic.tempo}\n onChange={(v) => setFilm('tempo', v)}\n />\n </>\n ) : (\n <>\n <ChipGrid\n label=\"Lighting\"\n options={labelled(LIGHTING)}\n value={cinematic.lighting}\n onChange={(v) => setFilm('lighting', v)}\n swatch={(id) => {\n const l = LIGHTING.find((o) => o.label === id);\n return l ? [l.light.key, l.light.ambient] : undefined;\n }}\n />\n <ChipGrid\n label=\"Palette\"\n options={labelled(PALETTES)}\n value={cinematic.palette}\n onChange={(v) => setFilm('palette', v)}\n swatch={(id) => {\n const p = PALETTES.find((o) => o.label === id);\n return p ? [...p.swatches] : undefined;\n }}\n />\n </>\n )}\n </GeneratorBottomSheet>\n );\n}\n\n/** The pill that opens the sheet: \"Direct\" when empty, else what is set. */\nexport function DirectorPill({ value, onPress }: { value: Direction; onPress: () => void }) {\n const theme = useCanvasTheme();\n const styles = useMemo(() => makeStyles(theme), [theme]);\n const summary = directionSummary(value);\n const on = Boolean(summary);\n return (\n <Pressable\n onPress={onPress}\n style={({ pressed }) => [styles.pill, on && styles.pillOn, pressedStyle(pressed)]}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Camera and film direction\"\n >\n <MaterialCommunityIcons\n name=\"movie-open-cog-outline\"\n size={14}\n color={on ? theme.background : theme.mutedForeground}\n />\n <Text style={[styles.pillLabel, on && styles.pillLabelOn]} numberOfLines={1}>\n {summary || 'Direct'}\n </Text>\n </Pressable>\n );\n}\n\nconst makeStyles = themedStyles((theme: CanvasPalette) =>\n StyleSheet.create({\n tabs: { flexGrow: 0, alignSelf: 'flex-start' },\n footer: { flexDirection: 'row', alignItems: 'center', gap: SPACE.sm },\n preview: { ...TYPE.caption, flex: 1, fontWeight: '400', color: theme.mutedForeground },\n reset: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: SPACE.xs,\n minHeight: 32,\n paddingHorizontal: SPACE.md,\n borderRadius: RADIUS.pill,\n backgroundColor: theme.card,\n },\n resetLabel: { ...TYPE.label, color: theme.foreground },\n pill: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: SPACE.sm - 2,\n minHeight: 36,\n paddingHorizontal: SPACE.md + 2,\n borderRadius: RADIUS.pill,\n backgroundColor: theme.card,\n maxWidth: 220,\n },\n pillOn: { backgroundColor: theme.foreground },\n pillLabel: { ...TYPE.label, flexShrink: 1, color: theme.foreground },\n pillLabelOn: { color: theme.background },\n }),\n);\n"],"names":[],"mappings":"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"}
|