@pushwoosh/smart-components-kit 1.12.0 → 1.14.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/MediaStorage/GenerateImageTab.d.ts +3 -1
- package/MediaStorage/GenerateImageTab.js +49 -18
- package/MediaStorage/MediaStorage.js +34 -3
- package/MediaStorage/aiGallery.d.ts +10 -0
- package/MediaStorage/aiGallery.js +15 -0
- package/MediaStorage/polyglot/messages_ar.js +4 -1
- package/MediaStorage/polyglot/messages_bn.js +4 -1
- package/MediaStorage/polyglot/messages_de.js +4 -1
- package/MediaStorage/polyglot/messages_en.js +4 -1
- package/MediaStorage/polyglot/messages_es.js +4 -1
- package/MediaStorage/polyglot/messages_fr.js +4 -1
- package/MediaStorage/polyglot/messages_he.js +4 -1
- package/MediaStorage/polyglot/messages_hi.js +4 -1
- package/MediaStorage/polyglot/messages_ja.js +4 -1
- package/MediaStorage/polyglot/messages_ko.js +4 -1
- package/MediaStorage/polyglot/messages_pt.js +4 -1
- package/MediaStorage/polyglot/messages_ru.js +4 -1
- package/MediaStorage/polyglot/messages_th.js +4 -1
- package/MediaStorage/polyglot/messages_zh.js +4 -1
- package/MediaStorage/polyglot/types.d.ts +5 -0
- package/MediaStorage/styles.d.ts +8 -0
- package/MediaStorage/styles.js +11 -1
- package/MediaStorage/types.d.ts +5 -0
- package/package.json +1 -1
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { type FC } from 'react';
|
|
2
2
|
import type { MediaFile } from '@pushwoosh/rpc-v2-http-api-data/media_files';
|
|
3
|
+
import { type PromptContext } from './aiGallery';
|
|
3
4
|
type GenerateImageTabProps = {
|
|
4
5
|
application: string;
|
|
5
6
|
aspectRatios?: string[];
|
|
6
7
|
defaultAspectRatio?: string;
|
|
8
|
+
promptContext?: PromptContext;
|
|
7
9
|
onSelect: (file: MediaFile, alt: string) => void;
|
|
8
10
|
onGenerated: () => void;
|
|
9
11
|
};
|
|
10
|
-
/** Prompt →
|
|
12
|
+
/** Prompt (+ optional message context) → 1–4 variants that onyx stores in the library; each preview is already a library file. */
|
|
11
13
|
export declare const GenerateImageTab: FC<GenerateImageTabProps>;
|
|
12
14
|
export {};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
-
import { Button, NativeSelect } from '@pushwoosh/dumb-components';
|
|
3
|
+
import { Button, Checkbox, NativeSelect } from '@pushwoosh/dumb-components';
|
|
4
4
|
import { useSPAContext } from '@pushwoosh/spa-context';
|
|
5
|
-
import { GENERATE_ASPECT_RATIOS,
|
|
5
|
+
import { GENERATE_ASPECT_RATIOS, GENERATE_VARIANT_COUNTS, storedVariants } from './aiGallery';
|
|
6
6
|
import { useErrorToast } from './hooks';
|
|
7
7
|
import { useLang } from './polyglot';
|
|
8
|
-
import { GenerateControls, GeneratedPreview, GenerateForm, PromptField } from './styles';
|
|
8
|
+
import { GenerateControls, GeneratedGrid, GeneratedPreview, GeneratedVariant, GenerateForm, PromptField } from './styles';
|
|
9
9
|
const ASPECT_LABELS = {
|
|
10
10
|
'1:1': 'SMART.MEDIA_STORAGE.GENERATE.ASPECT_SQUARE',
|
|
11
11
|
'4:3': 'SMART.MEDIA_STORAGE.GENERATE.ASPECT_LANDSCAPE',
|
|
@@ -19,11 +19,12 @@ const generateButtonMessage = (busy, hasResult) => {
|
|
|
19
19
|
if (busy) return 'SMART.MEDIA_STORAGE.GENERATE.GENERATING';
|
|
20
20
|
return hasResult ? 'SMART.MEDIA_STORAGE.GENERATE.AGAIN' : 'SMART.MEDIA_STORAGE.GENERATE.BUTTON';
|
|
21
21
|
};
|
|
22
|
-
/** Prompt →
|
|
22
|
+
/** Prompt (+ optional message context) → 1–4 variants that onyx stores in the library; each preview is already a library file. */
|
|
23
23
|
export const GenerateImageTab = ({
|
|
24
24
|
application,
|
|
25
25
|
aspectRatios,
|
|
26
26
|
defaultAspectRatio,
|
|
27
|
+
promptContext,
|
|
27
28
|
onSelect,
|
|
28
29
|
onGenerated
|
|
29
30
|
}) => {
|
|
@@ -36,6 +37,9 @@ export const GenerateImageTab = ({
|
|
|
36
37
|
const [prompt, setPrompt] = useState('');
|
|
37
38
|
const [aspect, setAspect] = useState(defaultAspectRatio && ratios.includes(defaultAspectRatio) ? defaultAspectRatio : ratios[0]);
|
|
38
39
|
const [busy, setBusy] = useState(false);
|
|
40
|
+
const [count, setCount] = useState(1);
|
|
41
|
+
const hasContext = Boolean(promptContext?.title?.trim() || promptContext?.body?.trim());
|
|
42
|
+
const [useContext, setUseContext] = useState(true);
|
|
39
43
|
const [generated, setGenerated] = useState(null);
|
|
40
44
|
const aspectLabel = ratio => {
|
|
41
45
|
return isLabelledAspect(ratio) ? lang({
|
|
@@ -48,13 +52,19 @@ export const GenerateImageTab = ({
|
|
|
48
52
|
setGenerated(null);
|
|
49
53
|
setBusy(true);
|
|
50
54
|
try {
|
|
51
|
-
const
|
|
55
|
+
const request = {
|
|
52
56
|
application,
|
|
53
57
|
prompt: text,
|
|
54
|
-
aspectRatio: aspect
|
|
55
|
-
|
|
58
|
+
aspectRatio: aspect,
|
|
59
|
+
count,
|
|
60
|
+
...(hasContext && useContext ? {
|
|
61
|
+
contextTitle: promptContext?.title ?? '',
|
|
62
|
+
contextBody: promptContext?.body ?? ''
|
|
63
|
+
} : {})
|
|
64
|
+
};
|
|
65
|
+
const res = await rpcGatewayAIAssistant.aiGen.GenerateMediaImage(request);
|
|
56
66
|
setGenerated({
|
|
57
|
-
|
|
67
|
+
files: storedVariants(res),
|
|
58
68
|
alt: text
|
|
59
69
|
});
|
|
60
70
|
onGenerated();
|
|
@@ -80,6 +90,16 @@ export const GenerateImageTab = ({
|
|
|
80
90
|
value: ratio,
|
|
81
91
|
children: aspectLabel(ratio)
|
|
82
92
|
}, ratio))
|
|
93
|
+
}), _jsx(NativeSelect, {
|
|
94
|
+
value: count,
|
|
95
|
+
onChange: event => setCount(Number(event.target.value)),
|
|
96
|
+
children: GENERATE_VARIANT_COUNTS.map(n => _jsx("option", {
|
|
97
|
+
value: n,
|
|
98
|
+
children: lang({
|
|
99
|
+
message: 'SMART.MEDIA_STORAGE.GENERATE.VARIANTS',
|
|
100
|
+
count: n
|
|
101
|
+
})
|
|
102
|
+
}, n))
|
|
83
103
|
}), _jsx(Button, {
|
|
84
104
|
color: "primary",
|
|
85
105
|
size: "field",
|
|
@@ -88,17 +108,28 @@ export const GenerateImageTab = ({
|
|
|
88
108
|
children: lang({
|
|
89
109
|
message: generateButtonMessage(busy, generated !== null)
|
|
90
110
|
})
|
|
91
|
-
}), generated && _jsx(Button, {
|
|
92
|
-
color: "secondary",
|
|
93
|
-
size: "field",
|
|
94
|
-
onClick: () => onSelect(generated.file, generated.alt),
|
|
95
|
-
children: lang({
|
|
96
|
-
message: 'SMART.MEDIA_STORAGE.GENERATE.SELECT'
|
|
97
|
-
})
|
|
98
111
|
})]
|
|
99
|
-
}),
|
|
100
|
-
|
|
101
|
-
|
|
112
|
+
}), hasContext && _jsx(Checkbox, {
|
|
113
|
+
label: lang({
|
|
114
|
+
message: 'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT'
|
|
115
|
+
}),
|
|
116
|
+
isChecked: useContext,
|
|
117
|
+
onChange: () => setUseContext(value => !value)
|
|
118
|
+
}), generated && _jsx(GeneratedGrid, {
|
|
119
|
+
"$single": generated.files.length === 1,
|
|
120
|
+
children: generated.files.map(file => _jsxs(GeneratedVariant, {
|
|
121
|
+
children: [_jsx(GeneratedPreview, {
|
|
122
|
+
src: file.url,
|
|
123
|
+
alt: generated.alt
|
|
124
|
+
}), _jsx(Button, {
|
|
125
|
+
color: "secondary",
|
|
126
|
+
size: "field",
|
|
127
|
+
onClick: () => onSelect(file, generated.alt),
|
|
128
|
+
children: lang({
|
|
129
|
+
message: 'SMART.MEDIA_STORAGE.GENERATE.SELECT'
|
|
130
|
+
})
|
|
131
|
+
})]
|
|
132
|
+
}, file.uuid))
|
|
102
133
|
})]
|
|
103
134
|
});
|
|
104
135
|
};
|
|
@@ -14,7 +14,7 @@ import { useCanvaEdit, useDeleteMediaFile, useDeleteMediaFiles } from './hooks';
|
|
|
14
14
|
import { formatBytes, getCropCaption, getSourceLabel, getThumbUrl, hasVersions } from './mediaFile.utils';
|
|
15
15
|
import { Lang, useLang } from './polyglot';
|
|
16
16
|
import { StockPhotosTab } from './StockPhotosTab';
|
|
17
|
-
import { CanvaActions, CountBadge, Dropzone, DropzoneRow, EmptyState, Grid, HiddenInput, SelectionBar, SelectionCount, SourceBadge, TabBody, Tile, TileActions, TileBadges, TileCheckbox, TileImage, UsageLine, WarningBadge } from './styles';
|
|
17
|
+
import { CanvaActions, CountBadge, Dropzone, DropzoneRow, EmptyState, Grid, HiddenInput, SelectionBar, SearchField, SearchRow, SelectionCount, SourceBadge, TabBody, Tile, TileActions, TileBadges, TileCheckbox, TileImage, UsageLine, WarningBadge } from './styles';
|
|
18
18
|
const UPLOAD_PATH = '/api/media/upload';
|
|
19
19
|
const ALLOWED_IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];
|
|
20
20
|
const TAB_MESSAGES = {
|
|
@@ -42,6 +42,7 @@ export const MediaStorage = ({
|
|
|
42
42
|
sources,
|
|
43
43
|
aspectRatios,
|
|
44
44
|
defaultAspectRatio,
|
|
45
|
+
promptContext,
|
|
45
46
|
onSuggestAlt
|
|
46
47
|
}) => {
|
|
47
48
|
const lang = useLang();
|
|
@@ -76,6 +77,8 @@ export const MediaStorage = ({
|
|
|
76
77
|
const [selectedUuids, setSelectedUuids] = useState([]);
|
|
77
78
|
const [isBulkDeleteOpen, setIsBulkDeleteOpen] = useState(false);
|
|
78
79
|
const [isBulkDeleting, setIsBulkDeleting] = useState(false);
|
|
80
|
+
const [search, setSearch] = useState('');
|
|
81
|
+
const [searchDraft, setSearchDraft] = useState('');
|
|
79
82
|
// Format filtering belongs to the query, not the response: `total` and the page count come
|
|
80
83
|
// from the filtered set, so a client-side filter would paginate over files it then hides.
|
|
81
84
|
const listAsync = useAsync(async () => {
|
|
@@ -83,14 +86,15 @@ export const MediaStorage = ({
|
|
|
83
86
|
application,
|
|
84
87
|
page,
|
|
85
88
|
perPage,
|
|
86
|
-
extensions
|
|
89
|
+
extensions,
|
|
90
|
+
searchByName: search || undefined
|
|
87
91
|
});
|
|
88
92
|
// protobuf JSON omits empty `repeated` fields, so `files` can be undefined.
|
|
89
93
|
return {
|
|
90
94
|
files: response.files ?? [],
|
|
91
95
|
total: response.total
|
|
92
96
|
};
|
|
93
|
-
}, [rpcGateway, application, page, perPage, extensions, reloadToken]);
|
|
97
|
+
}, [rpcGateway, application, page, perPage, extensions, search, reloadToken]);
|
|
94
98
|
const usageAsync = useAsync(() => rpcGateway.mediaFiles.GetUsage({
|
|
95
99
|
application
|
|
96
100
|
}), [rpcGateway, application, reloadToken, usageToken]);
|
|
@@ -174,6 +178,14 @@ export const MediaStorage = ({
|
|
|
174
178
|
cancelled = true;
|
|
175
179
|
};
|
|
176
180
|
}, [listAsync.value, rpcGateway, application, extensions]);
|
|
181
|
+
const applySearch = value => {
|
|
182
|
+
if (value === search) return;
|
|
183
|
+
setSearch(value);
|
|
184
|
+
if (pageRef.current !== 0) {
|
|
185
|
+
onPageChange(0);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
const commitSearch = () => applySearch(searchDraft.trim());
|
|
177
189
|
const uploadFiles = async selected => {
|
|
178
190
|
if (selected.length === 0) return;
|
|
179
191
|
const images = selected.filter(isAllowedImage);
|
|
@@ -346,6 +358,24 @@ export const MediaStorage = ({
|
|
|
346
358
|
accept: ALLOWED_IMAGE_EXTENSIONS.join(','),
|
|
347
359
|
multiple: true,
|
|
348
360
|
onChange: event => void uploadFiles(Array.from(event.target.files ?? []))
|
|
361
|
+
}), _jsx(SearchRow, {
|
|
362
|
+
children: _jsx(SearchField, {
|
|
363
|
+
type: "search",
|
|
364
|
+
value: searchDraft,
|
|
365
|
+
placeholder: lang({
|
|
366
|
+
message: 'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER'
|
|
367
|
+
}),
|
|
368
|
+
onChange: event => {
|
|
369
|
+
setSearchDraft(event.target.value);
|
|
370
|
+
if (event.target.value === '') {
|
|
371
|
+
applySearch('');
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
onKeyDown: event => {
|
|
375
|
+
if (event.key === 'Enter') commitSearch();
|
|
376
|
+
},
|
|
377
|
+
onBlur: commitSearch
|
|
378
|
+
})
|
|
349
379
|
}), loading && _jsx(EmptyState, {
|
|
350
380
|
children: lang({
|
|
351
381
|
message: 'SMART.MEDIA_STORAGE.LOADING'
|
|
@@ -563,6 +593,7 @@ export const MediaStorage = ({
|
|
|
563
593
|
application: application,
|
|
564
594
|
aspectRatios: aspectRatios,
|
|
565
595
|
defaultAspectRatio: defaultAspectRatio,
|
|
596
|
+
promptContext: promptContext,
|
|
566
597
|
onGenerated: showImportedFirst,
|
|
567
598
|
onSelect: pickStored
|
|
568
599
|
})
|
|
@@ -22,7 +22,15 @@ export type AiGenStoredImage = {
|
|
|
22
22
|
width: number;
|
|
23
23
|
height: number;
|
|
24
24
|
file?: AiGenMediaFile;
|
|
25
|
+
files?: AiGenMediaFile[];
|
|
25
26
|
};
|
|
27
|
+
/** The message an image is generated for; onyx draws for it and keeps its text out of the picture. */
|
|
28
|
+
export type PromptContext = {
|
|
29
|
+
title?: string;
|
|
30
|
+
body?: string;
|
|
31
|
+
};
|
|
32
|
+
/** Variant counts the Generate tab offers; onyx caps a request at 4 and charges each one. */
|
|
33
|
+
export declare const GENERATE_VARIANT_COUNTS: number[];
|
|
26
34
|
/** Aspect ratios onyx accepts for a generated image, in picker order. */
|
|
27
35
|
export declare const GENERATE_ASPECT_RATIOS: string[];
|
|
28
36
|
/** One Pexels hit from `aiGen.SearchStockPhotos`. */
|
|
@@ -47,3 +55,5 @@ export declare const isStockUnconfigured: (error: unknown) => boolean;
|
|
|
47
55
|
export declare const visibleSources: (sources: MediaSource[] | undefined, extensions: string[] | undefined) => MediaSource[];
|
|
48
56
|
/** Media-library file for an image onyx just stored, so `onSelect` gets the same shape as a library pick. */
|
|
49
57
|
export declare const toMediaFile: (stored: AiGenStoredImage, source: "ai" | "stock", fallbackName: string) => MediaFile;
|
|
58
|
+
/** Every image a Generate call stored, as library files; older onyx returns a single image. */
|
|
59
|
+
export declare const storedVariants: (res: AiGenStoredImage) => MediaFile[];
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Variant counts the Generate tab offers; onyx caps a request at 4 and charges each one. */
|
|
2
|
+
export const GENERATE_VARIANT_COUNTS = [1, 2, 4];
|
|
1
3
|
/** Aspect ratios onyx accepts for a generated image, in picker order. */
|
|
2
4
|
export const GENERATE_ASPECT_RATIOS = ['1:1', '4:3', '3:2', '16:9', '21:9', '5:4', '4:5', '3:4', '2:3', '9:16'];
|
|
3
5
|
/** Longest stock query onyx accepts (`stockphotos.MaxQueryChars`); capping the input keeps 400 meaning "not configured". */
|
|
@@ -52,4 +54,17 @@ export const toMediaFile = (stored, source, fallbackName) => {
|
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
};
|
|
57
|
+
};
|
|
58
|
+
/** Every image a Generate call stored, as library files; older onyx returns a single image. */
|
|
59
|
+
export const storedVariants = res => {
|
|
60
|
+
if (!res.files?.length) {
|
|
61
|
+
return [toMediaFile(res, 'ai', `${res.mediaUuid}.png`)];
|
|
62
|
+
}
|
|
63
|
+
return res.files.map(file => toMediaFile({
|
|
64
|
+
url: file.url,
|
|
65
|
+
mediaUuid: file.uuid,
|
|
66
|
+
width: file.width,
|
|
67
|
+
height: file.height,
|
|
68
|
+
file
|
|
69
|
+
}, 'ai', file.filename));
|
|
55
70
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'عريض (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'بانر (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': 'بورتريه (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'طويل (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'طويل (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'ابحث باسم الملف…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'الرسم وفق عنوان الرسالة ونصها',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × صورة'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'চওড়া (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'ব্যানার (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': 'পোর্ট্রেট (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'লম্বা (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'লম্বা (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'ফাইলের নাম দিয়ে অনুসন্ধান করুন…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'বার্তার শিরোনাম ও টেক্সট অনুযায়ী আঁকুন',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × ছবি'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'Breit (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'Banner (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': 'Hochformat (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Hoch (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Hoch (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'Nach Dateinamen suchen…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'Passend zu Titel und Text der Nachricht zeichnen',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × Bild'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'Wide (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'Banner (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': 'Portrait (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Tall (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Tall (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'Search by file name…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'Draw for the message title and text',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × image'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'Ancho (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'Banner (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': 'Vertical (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Alto (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Alto (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'Buscar por nombre de archivo…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'Dibujar según el título y el texto del mensaje',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × imagen'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'Large (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'Bannière (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': 'Portrait (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Haut (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Haut (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'Rechercher par nom de fichier…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'Illustrer le titre et le texte du message',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × image'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'רחב (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'באנר (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': 'לאורך (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'גבוה (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'גבוה (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'חיפוש לפי שם קובץ…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'לצייר לפי הכותרת והטקסט של ההודעה',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × תמונה'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'वाइड (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'बैनर (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': 'पोर्ट्रेट (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'टॉल (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'टॉल (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'फ़ाइल नाम से खोजें…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'संदेश के शीर्षक और टेक्स्ट के अनुसार बनाएं',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × छवि'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'ワイド (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'バナー (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': '縦長 (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': '縦長 (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': '縦長 (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'ファイル名で検索…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'メッセージのタイトルと本文に合わせて描く',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × 画像'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': '와이드 (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': '배너 (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': '세로 (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': '세로형 (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': '세로형 (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': '파일 이름으로 검색…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': '메시지 제목과 본문에 맞춰 그리기',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × 이미지'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'Largo (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'Banner (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': 'Retrato (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Alto (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Alto (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'Buscar por nome do arquivo…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'Desenhar para o título e o texto da mensagem',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × imagem'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'Широкая (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'Баннер (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': 'Портретная (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Вертикальная (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'Вертикальная (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'Поиск по имени файла…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'Рисовать под заголовок и текст сообщения',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × картинка'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': 'แนวนอนกว้าง (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': 'แบนเนอร์ (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': 'แนวตั้ง (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'แนวตั้งสูง (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': 'แนวตั้งสูง (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': 'ค้นหาตามชื่อไฟล์…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': 'วาดตามหัวข้อและข้อความของข้อความ',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × รูปภาพ'
|
|
109
112
|
};
|
|
@@ -105,5 +105,8 @@ export const messages = {
|
|
|
105
105
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_WIDE': '宽 (16:9)',
|
|
106
106
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': '横幅 (21:9)',
|
|
107
107
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': '纵向 (3:4)',
|
|
108
|
-
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': '高 (9:16)'
|
|
108
|
+
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': '高 (9:16)',
|
|
109
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': '按文件名搜索…',
|
|
110
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': '根据消息标题和正文绘制',
|
|
111
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': '{{count}} × 图片'
|
|
109
112
|
};
|
|
@@ -140,4 +140,9 @@ export type MediaStorageMessages = {
|
|
|
140
140
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_BANNER': NoParams;
|
|
141
141
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_PORTRAIT': NoParams;
|
|
142
142
|
'SMART.MEDIA_STORAGE.GENERATE.ASPECT_TALL': NoParams;
|
|
143
|
+
'SMART.MEDIA_STORAGE.SEARCH_PLACEHOLDER': NoParams;
|
|
144
|
+
'SMART.MEDIA_STORAGE.GENERATE.USE_CONTEXT': NoParams;
|
|
145
|
+
'SMART.MEDIA_STORAGE.GENERATE.VARIANTS': {
|
|
146
|
+
count: number;
|
|
147
|
+
};
|
|
143
148
|
};
|
package/MediaStorage/styles.d.ts
CHANGED
|
@@ -164,3 +164,11 @@ export declare const PromptField: import("styled-components/dist/types").IStyled
|
|
|
164
164
|
[key: `--${string}`]: string | number | undefined;
|
|
165
165
|
}) | undefined;
|
|
166
166
|
}> & string;
|
|
167
|
+
export declare const GeneratedGrid: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Merged<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
|
|
168
|
+
style?: import("react").CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
|
|
169
|
+
}, {
|
|
170
|
+
$single?: boolean;
|
|
171
|
+
}>> & string;
|
|
172
|
+
export declare const GeneratedVariant: import("styled-components/dist/types").IStyledComponentBase<"web", Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
|
|
173
|
+
style?: import("react").CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
|
|
174
|
+
}> & string;
|
package/MediaStorage/styles.js
CHANGED
|
@@ -187,4 +187,14 @@ export const SearchField = styled(NativeInput).withConfig({
|
|
|
187
187
|
export const PromptField = styled(NativeTextarea).withConfig({
|
|
188
188
|
displayName: "PromptField",
|
|
189
189
|
componentId: "sc-uu3cbo-40"
|
|
190
|
-
})(["font-family:inherit;resize:vertical;"]);
|
|
190
|
+
})(["font-family:inherit;resize:vertical;"]);
|
|
191
|
+
export const GeneratedGrid = styled.div.withConfig({
|
|
192
|
+
displayName: "GeneratedGrid",
|
|
193
|
+
componentId: "sc-uu3cbo-41"
|
|
194
|
+
})(["display:grid;grid-template-columns:", ";gap:16px;"], ({
|
|
195
|
+
$single
|
|
196
|
+
}) => $single ? '1fr' : 'repeat(2, minmax(0, 1fr))');
|
|
197
|
+
export const GeneratedVariant = styled.div.withConfig({
|
|
198
|
+
displayName: "GeneratedVariant",
|
|
199
|
+
componentId: "sc-uu3cbo-42"
|
|
200
|
+
})(["display:flex;flex-direction:column;align-items:flex-start;gap:8px;"]);
|
package/MediaStorage/types.d.ts
CHANGED
|
@@ -24,6 +24,11 @@ type MediaFileChannelOptions = {
|
|
|
24
24
|
aspectRatios?: string[];
|
|
25
25
|
/** Pre-selected aspect ratio in the Generate tab. */
|
|
26
26
|
defaultAspectRatio?: string;
|
|
27
|
+
/** Title and text of the message being composed; Generate offers to draw for it. */
|
|
28
|
+
promptContext?: {
|
|
29
|
+
title?: string;
|
|
30
|
+
body?: string;
|
|
31
|
+
};
|
|
27
32
|
/** Alt text suggested for a stock or generated pick (provider alt or the prompt). */
|
|
28
33
|
onSuggestAlt?: (file: MediaFile, alt: string) => void;
|
|
29
34
|
};
|