cross-store text: other platforms named in App Store text (2.3.10: Android, Google Play, ...) or Play text (Metadata: iOS, App Store, Game Center, ...) are refused by every text write (apple / play listing, play release / upload notes, listing set, whats-new, storebound edit, desktop editor), blockers in check / validate, scan other-platforms / play-other-platforms; listing.allowPlatformMentions for the owner's functional mentions; whats-new splits [apple] / [play] lines per store; storebound api --yes without a TTY is refused (exit 1, stderr) instead of a silent dry run; pitfalls 77, 78
This commit is contained in:
parent
3e4015b686
commit
edabbec874
32 changed files with 613 additions and 53 deletions
|
|
@ -4,6 +4,33 @@ import type { Language } from './config';
|
|||
import { playCodes } from './config';
|
||||
import { len, PLAY_LIMITS } from './copy';
|
||||
import { jargonFindings, jargonMessage } from './jargon';
|
||||
import { type CrossStore, fieldsMentions, notesForStore, type PlatformAllow, type PlatformHit, textMentions } from './cross-store';
|
||||
|
||||
/** One store's draft from shared notes: tagged lines split ([apple] / [play]), and an untagged line that names the
|
||||
* other side's platform (a "Google Play Games" line for the App Store) left out of this store's draft and reported,
|
||||
* so a draft never carries it into the wrong store (pitfall 77). Tag the line to make it explicit. Pure. */
|
||||
export function draftForStore(text: string, store: CrossStore, allow: readonly PlatformAllow[] = []): { text: string; dropped: string[] } {
|
||||
const dropped: string[] = [];
|
||||
const kept = notesForStore(text, store).split('\n').filter(l => {
|
||||
if (!l.trim() || !textMentions(l, { store, locale: '', field: 'whatsNew', allow }).length) return true;
|
||||
dropped.push(l.trim());
|
||||
return false;
|
||||
});
|
||||
return { text: kept.join('\n').replace(/\n{3,}/g, '\n\n').trim(), dropped };
|
||||
}
|
||||
|
||||
/** Note items for one store (items tagged [apple] / [play] go only there, the tag removed). */
|
||||
export function itemsForStore(items: NoteItem[], store: CrossStore): NoteItem[] {
|
||||
return items.flatMap(i => { const t = notesForStore(i.text, store); return t ? [{ ...i, text: t }] : []; });
|
||||
}
|
||||
|
||||
/** Other-platform hits in the per-store notes of one language (the texts `whats-new apply` would write). Pure. */
|
||||
export function languageNoteMentions(l: Language, text: string, allow: readonly PlatformAllow[] = []): PlatformHit[] {
|
||||
const out: PlatformHit[] = [];
|
||||
for (const code of playCodes(l)) out.push(...fieldsMentions('play', code, { whatsNew: notesForStore(text, 'play') }, allow));
|
||||
if (l.apple) out.push(...fieldsMentions('apple', l.apple, { whatsNew: notesForStore(text, 'apple') }, allow));
|
||||
return out;
|
||||
}
|
||||
|
||||
export const NOTES_LIMITS = { play: PLAY_LIMITS.whatsNew, apple: 4000 } as const;
|
||||
/** Roughly what both stores show before "more" on a phone. */
|
||||
|
|
@ -196,8 +223,10 @@ export interface LangCheck { lang: string; chars: number; play?: { limit: number
|
|||
export function checkLanguageNotes(l: Language, f: NotesFile, sourceText?: string, allow: readonly string[] = []): LangCheck {
|
||||
const chars = len(f.text);
|
||||
const c: LangCheck = { lang: l.id, chars, problems: [], warnings: jargonFindings(f.text, allow).map(jargonMessage) };
|
||||
if (playCodes(l).length) { c.play = { limit: NOTES_LIMITS.play, ok: chars <= NOTES_LIMITS.play }; if (!c.play.ok) c.problems.push(`Google Play: ${chars} > ${NOTES_LIMITS.play} characters`); }
|
||||
if (l.apple) { c.apple = { limit: NOTES_LIMITS.apple, ok: chars <= NOTES_LIMITS.apple }; if (!c.apple.ok) c.problems.push(`App Store: ${chars} > ${NOTES_LIMITS.apple} characters`); }
|
||||
// each store counts its own notes: lines tagged for the other store are not sent there
|
||||
const pn = len(notesForStore(f.text, 'play')), an = len(notesForStore(f.text, 'apple'));
|
||||
if (playCodes(l).length) { c.play = { limit: NOTES_LIMITS.play, ok: pn <= NOTES_LIMITS.play }; if (!c.play.ok) c.problems.push(`Google Play: ${pn} > ${NOTES_LIMITS.play} characters`); }
|
||||
if (l.apple) { c.apple = { limit: NOTES_LIMITS.apple, ok: an <= NOTES_LIMITS.apple }; if (!c.apple.ok) c.problems.push(`App Store: ${an} > ${NOTES_LIMITS.apple} characters`); }
|
||||
if (!f.text) c.problems.push('empty');
|
||||
if (f.status === 'translate') c.problems.push('not translated yet (status=translate)');
|
||||
else if (sourceText !== undefined && f.status !== 'source' && f.text === sourceText.trim()) c.problems.push('identical to the source language: translate it');
|
||||
|
|
@ -206,16 +235,17 @@ export function checkLanguageNotes(l: Language, f: NotesFile, sourceText?: strin
|
|||
return c;
|
||||
}
|
||||
|
||||
/** Writes one language's notes into the listing files (every Play code of the language, its App Store locale). Pure. */
|
||||
/** Writes one language's notes into the listing files (every Play code of the language, its App Store locale); lines
|
||||
* tagged [apple] / [play] go only into that store's notes. Pure. */
|
||||
export function applyLanguageNotes(md: { play?: string; apple?: string }, l: Language, text: string): { play?: string; apple?: string; changed: string[] } {
|
||||
const out: { play?: string; apple?: string; changed: string[] } = { ...md, changed: [] };
|
||||
if (md.play !== undefined) for (const code of playCodes(l)) {
|
||||
const r = setPlayWhatsNew(out.play!, code, text);
|
||||
const r = setPlayWhatsNew(out.play!, code, notesForStore(text, 'play'));
|
||||
out.play = r.md;
|
||||
out.changed.push(...r.changed.map(x => `play:${x}`));
|
||||
}
|
||||
if (md.apple !== undefined && l.apple) {
|
||||
const r = setAppleWhatsNew(out.apple!, l.apple, text);
|
||||
const r = setAppleWhatsNew(out.apple!, l.apple, notesForStore(text, 'apple'));
|
||||
out.apple = r.md;
|
||||
out.changed.push(...r.changed.map(x => `apple:${x}`));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue