creative assets: <renders>/creative/header.* / search.* fill every language without its own file (art without words needs no copy per locale; one upload, placed per locale)
This commit is contained in:
parent
c03291e7f7
commit
3542b897c8
5 changed files with 21 additions and 8 deletions
|
|
@ -2,8 +2,9 @@
|
|||
// 27+): the product page header (21:9) and the search results asset (3:2), image or video, per locale, with one
|
||||
// universal 16:9 image (5244 x 2950) that can fill either slot. Apple's Creative assets specifications:
|
||||
// https://developer.apple.com/help/app-store-connect/reference/app-information/creative-assets-specifications/
|
||||
// Files: <renders>/<language id>/creative/{header,search}.{png,jpg,jpeg,mov,m4v,mp4}; universal fallback
|
||||
// <renders>/<language id>/creative/universal.png or <renders>/creative/universal.png (every locale).
|
||||
// Files: <renders>/<language id>/creative/{header,search}.{png,jpg,jpeg,mov,m4v,mp4}, else the same names in
|
||||
// <renders>/creative/ for every locale; universal fallback <renders>/<language id>/creative/universal.png or
|
||||
// <renders>/creative/universal.png (every locale).
|
||||
// API: App Asset Library (placement types PRODUCT_PAGE_HEADER_ASSET and APP_STORE_SEARCH_RESULTS_ASSET); see
|
||||
// cli/apple/creative-assets.ts. Play has no such slot: the feature graphic (1024 x 500) and the promo video are its
|
||||
// closest equivalents.
|
||||
|
|
@ -29,16 +30,20 @@ export interface CreativeFile { placement: Placement; file: string; kind: 'image
|
|||
const EXT = /\.(png|jpe?g|mov|m4v|mp4)$/i;
|
||||
const kindOf = (f: string): 'image' | 'video' => (CREATIVE_RULES.video.ext.test(f) ? 'video' : 'image');
|
||||
|
||||
/** The file for each placement of one language: own header / search file first, else the universal image. */
|
||||
/** The file for each placement of one language: its own header / search file first, then a shared one for every
|
||||
* language (<renders>/creative/header.png: art without words needs no copy per locale), then the universal image. */
|
||||
export function creativeFiles(renders: string, lang: string, list: (d: string) => string[] = d => (existsSync(d) ? readdirSync(d) : [])): CreativeFile[] {
|
||||
const dir = join(renders, lang, 'creative');
|
||||
const dir = join(renders, lang, 'creative'), shared = join(renders, 'creative');
|
||||
const own = list(dir).filter(f => EXT.test(f)).sort();
|
||||
const common = list(shared).filter(f => EXT.test(f)).sort();
|
||||
const uni = own.find(f => /^universal\.png$/i.test(f)) ? join(dir, own.find(f => /^universal\.png$/i.test(f))!)
|
||||
: list(join(renders, 'creative')).some(f => f === 'universal.png') ? join(renders, 'creative', 'universal.png') : undefined;
|
||||
: common.includes('universal.png') ? join(shared, 'universal.png') : undefined;
|
||||
const out: CreativeFile[] = [];
|
||||
for (const p of ['header', 'search'] as Placement[]) {
|
||||
const f = own.find(x => x.toLowerCase().startsWith(`${p}.`));
|
||||
const g = common.find(x => x.toLowerCase().startsWith(`${p}.`));
|
||||
if (f) out.push({ placement: p, file: join(dir, f), kind: kindOf(f), universal: false });
|
||||
else if (g) out.push({ placement: p, file: join(shared, g), kind: kindOf(g), universal: false });
|
||||
else if (uni) out.push({ placement: p, file: uni, kind: 'image', universal: true });
|
||||
}
|
||||
return out;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue