From 58c6bb28af5e57742f09813c18d741195d04a828 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Fri, 2 Oct 2026 13:32:19 +0000 Subject: [PATCH] Poster Design names sizes, and plugins' designs, in the reader's language Styles and Sizes now name every size the one way (src/sizeText.js, shared): templates.js carries each size as data (inches, side lanes, panels, paper), and posterDesign.sizes gains sideLanes, packetPage1, panels and anySize in all 11 locales, so Arabic readers no longer see "5 x 8 ft, side lanes" or "Letter, portrait". A plugin's declared size (a ladder key, letter, a4) is named through the shared ladder. A plugin's design title came from its labelKey, but Poster Design's bundle ships only the catalogue areas its own code names, so a plugin's own area (upgMap, ...) read English. internal/profile-meta.mjs now resolves each block's labelKey in every locale at build time and carries the titles in manifest.json (posterDesignLabels, only beside a posterDesign block), and Styles reads the reader's language from there. --- internal/profile-meta.mjs | 39 +++++++++++++++++-- library/i18n/locales/ar/posterDesign.json | 6 ++- library/i18n/locales/de/posterDesign.json | 6 ++- library/i18n/locales/en/posterDesign.json | 6 ++- library/i18n/locales/es/posterDesign.json | 6 ++- library/i18n/locales/fr/posterDesign.json | 6 ++- library/i18n/locales/hi/posterDesign.json | 6 ++- library/i18n/locales/it/posterDesign.json | 6 ++- library/i18n/locales/pt/posterDesign.json | 6 ++- library/i18n/locales/ro/posterDesign.json | 6 ++- library/i18n/locales/ru/posterDesign.json | 6 ++- library/i18n/locales/zh/posterDesign.json | 6 ++- plugin-designs/poster-design/poster-sizes.vue | 13 ++----- .../poster-design/poster-styles.vue | 21 +++++++--- .../poster-design/src/FullDetailsDialog.vue | 2 +- .../poster-design/src/pluginDesigns.js | 2 + plugin-designs/poster-design/src/sizeText.js | 39 +++++++++++++++++++ plugin-designs/poster-design/src/templates.js | 25 ++++++------ 18 files changed, 165 insertions(+), 42 deletions(-) create mode 100644 plugin-designs/poster-design/src/sizeText.js diff --git a/internal/profile-meta.mjs b/internal/profile-meta.mjs index 3da0f7b94..57e9b2a71 100644 --- a/internal/profile-meta.mjs +++ b/internal/profile-meta.mjs @@ -12,9 +12,42 @@ * posterDesign { family, name, size, mobileFriendly, labelKey?, instance? } or an array of them: the poster * design(s) this profile shows, listed by Poster Design's Styles. Carried as written, ONLY when present * (every other manifest keeps its bytes); check:poster-design-catalogue validates it. + * posterDesignLabels GENERATED beside it: { : { : title } } for every block with a labelKey, + * resolved here from library/i18n/locales//.json. Poster Design's bundle ships only the + * catalogue areas its own code names, so a plugin's own area (upgMap, …) would be missing there and the card + * would read English; carrying the titles in the manifest works for any area, with no Poster Design rebuild. */ -import { readFileSync } from 'node:fs' -import { join } from 'node:path' +import { readFileSync, readdirSync, existsSync } from 'node:fs' +import { join, dirname } from 'node:path' +import { fileURLToPath } from 'node:url' + +const LOCALES = join(dirname(fileURLToPath(import.meta.url)), '..', 'library', 'i18n', 'locales') +// A catalogue key ("area.a.b") in every locale that has it: { en: '…', ar: '…' }; {} when no locale does. +function catalogueTitles(key) { + const [area, ...path] = String(key || '').split('.') + const out = {} + if (!area || !path.length || !existsSync(LOCALES)) return out + for (const loc of readdirSync(LOCALES)) { + const f = join(LOCALES, loc, `${area}.json`) + if (!existsSync(f)) continue + try { + let o = JSON.parse(readFileSync(f, 'utf8')) + for (const p of path) o = o && typeof o === 'object' ? o[p] : undefined + if (typeof o === 'string' && o.trim()) out[loc] = o + } catch { /* a locale file that does not parse names nothing */ } + } + return out +} +function posterDesignLabels(pd) { + const out = {} + for (const b of Array.isArray(pd) ? pd : [pd]) { + if (b && typeof b.name === 'string' && typeof b.labelKey === 'string') { + const titles = catalogueTitles(b.labelKey) + if (Object.keys(titles).length) out[b.name] = titles + } + } + return out +} const CORNERS = ['bottom-right', 'bottom-left', 'top-right', 'top-left'] @@ -82,7 +115,7 @@ export function profileMetaFields(dir, profileName) { const m = readProfileMeta(dir, profileName) // visibility is emitted ONLY when it is "public": absent means team, so every manifest in the // tree today keeps the bytes it has and nothing becomes visible by upgrading the generator. - return { stage: m.stage, ...(m.visibility === 'public' ? { visibility: 'public' } : {}), ...(m.label ? { label: m.label } : {}), ...(m.targets ? { targets: m.targets } : {}), ...(m.heavy ? { heavy: true } : {}), ...(m.widget ? { widget: m.widget } : {}), ...(m.mobile ? { mobile: m.mobile } : {}), ...(m.posterDesign ? { posterDesign: m.posterDesign } : {}) } + return { stage: m.stage, ...(m.visibility === 'public' ? { visibility: 'public' } : {}), ...(m.label ? { label: m.label } : {}), ...(m.targets ? { targets: m.targets } : {}), ...(m.heavy ? { heavy: true } : {}), ...(m.widget ? { widget: m.widget } : {}), ...(m.mobile ? { mobile: m.mobile } : {}), ...(m.posterDesign ? { posterDesign: m.posterDesign } : {}), ...(m.posterDesign && Object.keys(posterDesignLabels(m.posterDesign)).length ? { posterDesignLabels: posterDesignLabels(m.posterDesign) } : {}) } } /** A bundle is production if ANY of its profiles says so. */ diff --git a/library/i18n/locales/ar/posterDesign.json b/library/i18n/locales/ar/posterDesign.json index 284c2d1cc..9b0f3fed2 100644 --- a/library/i18n/locales/ar/posterDesign.json +++ b/library/i18n/locales/ar/posterDesign.json @@ -28,7 +28,11 @@ "no": "لا", "printHome": "أي طابعة منزلية", "printShop": "مطبعة (ملف PDF، صفحة لكل ورقة)", - "layoutNote": "تعرض الأوراق تخطيط ملصق الدولة بمقاس 3 × 3 أقدام في كل مقاس: الترويسة والخريطة والأسماء والجدول وتذييل الآية. سيظهر الملصق المرسوم بكل مقاس في الأنماط عند توفره." + "layoutNote": "تعرض الأوراق تخطيط ملصق الدولة بمقاس 3 × 3 أقدام في كل مقاس: الترويسة والخريطة والأسماء والجدول وتذييل الآية. سيظهر الملصق المرسوم بكل مقاس في الأنماط عند توفره.", + "sideLanes": "{dims}، أعمدة جانبية", + "packetPage1": "{paper} (الصفحة 1 من حزمة الصلاة)", + "panels": "{dims}، عدد الألواح: {n}", + "anySize": "أي حجم من جدول الأحجام المشترك" }, "family": { "mapSheet": "صفحات الخرائط", diff --git a/library/i18n/locales/de/posterDesign.json b/library/i18n/locales/de/posterDesign.json index 20a0879b7..5c07f781e 100644 --- a/library/i18n/locales/de/posterDesign.json +++ b/library/i18n/locales/de/posterDesign.json @@ -28,7 +28,11 @@ "no": "Nein", "printHome": "Jeder Drucker zu Hause", "printShop": "Eine Druckerei (ein PDF, eine Seite pro Bogen)", - "layoutNote": "Die Bögen zeigen das Layout des 3 × 3 ft Länderposters in jeder Größe: Kopfzeile, Karte, Namen, Tabelle und die Fußzeile mit dem Bibelvers. Das in jeder Größe gezeichnete Poster erscheint unter Stile, sobald es verfügbar ist." + "layoutNote": "Die Bögen zeigen das Layout des 3 × 3 ft Länderposters in jeder Größe: Kopfzeile, Karte, Namen, Tabelle und die Fußzeile mit dem Bibelvers. Das in jeder Größe gezeichnete Poster erscheint unter Stile, sobald es verfügbar ist.", + "sideLanes": "{dims}, seitliche Namensspalten", + "packetPage1": "{paper} (Seite 1 der Gebetsmappe)", + "panels": "{dims}, Tafeln: {n}", + "anySize": "Jede Größe aus der gemeinsamen Größentabelle" }, "family": { "mapSheet": "Kartenblätter", diff --git a/library/i18n/locales/en/posterDesign.json b/library/i18n/locales/en/posterDesign.json index b970eaa7e..b37b07769 100644 --- a/library/i18n/locales/en/posterDesign.json +++ b/library/i18n/locales/en/posterDesign.json @@ -28,7 +28,11 @@ "no": "No", "printHome": "Any home printer", "printShop": "A print shop (a PDF, one page per sheet)", - "layoutNote": "The sheets show the layout of the 3 × 3 ft country poster at each size: the header, the map, the names, the table and the scripture footer. The poster drawn at each size appears in Styles as it becomes available." + "layoutNote": "The sheets show the layout of the 3 × 3 ft country poster at each size: the header, the map, the names, the table and the scripture footer. The poster drawn at each size appears in Styles as it becomes available.", + "sideLanes": "{dims}, side lanes", + "packetPage1": "{paper} (packet page 1)", + "panels": "{dims}, {n} panels", + "anySize": "Any size from the shared size table" }, "family": { "mapSheet": "Map sheets", diff --git a/library/i18n/locales/es/posterDesign.json b/library/i18n/locales/es/posterDesign.json index 2edc7e748..57d10b7bd 100644 --- a/library/i18n/locales/es/posterDesign.json +++ b/library/i18n/locales/es/posterDesign.json @@ -28,7 +28,11 @@ "no": "No", "printHome": "Cualquier impresora doméstica", "printShop": "Una imprenta (un PDF, una página por hoja)", - "layoutNote": "Las hojas muestran el diseño del póster de país de 3 × 3 ft en cada tamaño: el encabezado, el mapa, los nombres, la tabla y el pie con la Escritura. El póster dibujado en cada tamaño aparecerá en Estilos a medida que esté disponible." + "layoutNote": "Las hojas muestran el diseño del póster de país de 3 × 3 ft en cada tamaño: el encabezado, el mapa, los nombres, la tabla y el pie con la Escritura. El póster dibujado en cada tamaño aparecerá en Estilos a medida que esté disponible.", + "sideLanes": "{dims}, columnas laterales", + "packetPage1": "{paper} (página 1 del paquete de oración)", + "panels": "{dims}, paneles: {n}", + "anySize": "Cualquier tamaño de la tabla de tamaños compartida" }, "family": { "mapSheet": "Hojas de mapa", diff --git a/library/i18n/locales/fr/posterDesign.json b/library/i18n/locales/fr/posterDesign.json index 79c66a6b8..cfab7c740 100644 --- a/library/i18n/locales/fr/posterDesign.json +++ b/library/i18n/locales/fr/posterDesign.json @@ -28,7 +28,11 @@ "no": "Non", "printHome": "N'importe quelle imprimante", "printShop": "Un imprimeur (un PDF, une page par feuille)", - "layoutNote": "Les feuilles montrent la mise en page de l'affiche pays de 3 × 3 ft à chaque format : l'en-tête, la carte, les noms, le tableau et le pied avec l'Écriture. L'affiche dessinée à chaque format apparaîtra dans Styles dès qu'elle sera disponible." + "layoutNote": "Les feuilles montrent la mise en page de l'affiche pays de 3 × 3 ft à chaque format : l'en-tête, la carte, les noms, le tableau et le pied avec l'Écriture. L'affiche dessinée à chaque format apparaîtra dans Styles dès qu'elle sera disponible.", + "sideLanes": "{dims}, colonnes latérales", + "packetPage1": "{paper} (page 1 du dossier de prière)", + "panels": "{dims}, panneaux : {n}", + "anySize": "Toute taille du tableau de tailles commun" }, "family": { "mapSheet": "Feuilles de carte", diff --git a/library/i18n/locales/hi/posterDesign.json b/library/i18n/locales/hi/posterDesign.json index d17457e22..60b700f86 100644 --- a/library/i18n/locales/hi/posterDesign.json +++ b/library/i18n/locales/hi/posterDesign.json @@ -28,7 +28,11 @@ "no": "नहीं", "printHome": "कोई भी घरेलू प्रिंटर", "printShop": "प्रिंटिंग प्रेस (PDF, हर शीट के लिए एक पेज)", - "layoutNote": "शीटें हर आकार में 3 × 3 फ़ुट देश पोस्टर का लेआउट दिखाती हैं: शीर्षक, मानचित्र, नाम, तालिका और पवित्रशास्त्र वाला फ़ुटर। हर आकार में बना असली पोस्टर उपलब्ध होते ही शैलियाँ में दिखेगा।" + "layoutNote": "शीटें हर आकार में 3 × 3 फ़ुट देश पोस्टर का लेआउट दिखाती हैं: शीर्षक, मानचित्र, नाम, तालिका और पवित्रशास्त्र वाला फ़ुटर। हर आकार में बना असली पोस्टर उपलब्ध होते ही शैलियाँ में दिखेगा।", + "sideLanes": "{dims}, किनारे के कॉलम", + "packetPage1": "{paper} (प्रार्थना पैकेट का पेज 1)", + "panels": "{dims}, पैनल: {n}", + "anySize": "साझा आकार तालिका का कोई भी आकार" }, "family": { "mapSheet": "मानचित्र पृष्ठ", diff --git a/library/i18n/locales/it/posterDesign.json b/library/i18n/locales/it/posterDesign.json index 4aec62b44..8ef668a29 100644 --- a/library/i18n/locales/it/posterDesign.json +++ b/library/i18n/locales/it/posterDesign.json @@ -28,7 +28,11 @@ "no": "No", "printHome": "Qualsiasi stampante di casa", "printShop": "Una tipografia (un PDF, una pagina per foglio)", - "layoutNote": "I fogli mostrano l'impaginazione del poster di paese da 3 × 3 ft in ogni formato: intestazione, mappa, nomi, tabella e il piè di pagina con la Scrittura. Il poster disegnato in ogni formato comparirà in Stili appena disponibile." + "layoutNote": "I fogli mostrano l'impaginazione del poster di paese da 3 × 3 ft in ogni formato: intestazione, mappa, nomi, tabella e il piè di pagina con la Scrittura. Il poster disegnato in ogni formato comparirà in Stili appena disponibile.", + "sideLanes": "{dims}, colonne laterali", + "packetPage1": "{paper} (pagina 1 del fascicolo di preghiera)", + "panels": "{dims}, pannelli: {n}", + "anySize": "Qualsiasi formato dalla tabella dei formati comune" }, "family": { "mapSheet": "Fogli mappa", diff --git a/library/i18n/locales/pt/posterDesign.json b/library/i18n/locales/pt/posterDesign.json index 69af6993a..6cc35a844 100644 --- a/library/i18n/locales/pt/posterDesign.json +++ b/library/i18n/locales/pt/posterDesign.json @@ -28,7 +28,11 @@ "no": "Não", "printHome": "Qualquer impressora doméstica", "printShop": "Uma gráfica (um PDF, uma página por folha)", - "layoutNote": "As folhas mostram o layout do pôster de país de 3 × 3 ft em cada tamanho: o cabeçalho, o mapa, os nomes, a tabela e o rodapé com a Escritura. O pôster desenhado em cada tamanho aparecerá em Estilos quando estiver disponível." + "layoutNote": "As folhas mostram o layout do pôster de país de 3 × 3 ft em cada tamanho: o cabeçalho, o mapa, os nomes, a tabela e o rodapé com a Escritura. O pôster desenhado em cada tamanho aparecerá em Estilos quando estiver disponível.", + "sideLanes": "{dims}, colunas laterais", + "packetPage1": "{paper} (página 1 do pacote de oração)", + "panels": "{dims}, painéis: {n}", + "anySize": "Qualquer tamanho da tabela de tamanhos compartilhada" }, "family": { "mapSheet": "Folhas de mapa", diff --git a/library/i18n/locales/ro/posterDesign.json b/library/i18n/locales/ro/posterDesign.json index 86183bb77..e49d992a4 100644 --- a/library/i18n/locales/ro/posterDesign.json +++ b/library/i18n/locales/ro/posterDesign.json @@ -28,7 +28,11 @@ "no": "Nu", "printHome": "Orice imprimantă de acasă", "printShop": "O tipografie (un PDF, o pagină pe coală)", - "layoutNote": "Colile arată machetarea afișului de țară de 3 × 3 ft la fiecare dimensiune: antetul, harta, numele, tabelul și subsolul cu versetul din Scriptură. Afișul desenat la fiecare dimensiune va apărea în Stiluri când va fi disponibil." + "layoutNote": "Colile arată machetarea afișului de țară de 3 × 3 ft la fiecare dimensiune: antetul, harta, numele, tabelul și subsolul cu versetul din Scriptură. Afișul desenat la fiecare dimensiune va apărea în Stiluri când va fi disponibil.", + "sideLanes": "{dims}, coloane laterale", + "packetPage1": "{paper} (pagina 1 a pachetului de rugăciune)", + "panels": "{dims}, panouri: {n}", + "anySize": "Orice dimensiune din tabelul comun de dimensiuni" }, "family": { "mapSheet": "Foi de hartă", diff --git a/library/i18n/locales/ru/posterDesign.json b/library/i18n/locales/ru/posterDesign.json index d5f05a992..9ef47bbe0 100644 --- a/library/i18n/locales/ru/posterDesign.json +++ b/library/i18n/locales/ru/posterDesign.json @@ -28,7 +28,11 @@ "no": "Нет", "printHome": "Любой домашний принтер", "printShop": "Типография (PDF, одна страница на лист)", - "layoutNote": "На листах показан макет плаката страны 3 × 3 фута в каждом размере: заголовок, карта, названия, таблица и нижняя полоса со стихом из Писания. Плакат, нарисованный в каждом размере, появится в разделе «Стили», когда будет готов." + "layoutNote": "На листах показан макет плаката страны 3 × 3 фута в каждом размере: заголовок, карта, названия, таблица и нижняя полоса со стихом из Писания. Плакат, нарисованный в каждом размере, появится в разделе «Стили», когда будет готов.", + "sideLanes": "{dims}, боковые колонки", + "packetPage1": "{paper} (страница 1 молитвенного пакета)", + "panels": "{dims}, панелей: {n}", + "anySize": "Любой размер из общей таблицы размеров" }, "family": { "mapSheet": "Листы карт", diff --git a/library/i18n/locales/zh/posterDesign.json b/library/i18n/locales/zh/posterDesign.json index f54ea4e85..242396f13 100644 --- a/library/i18n/locales/zh/posterDesign.json +++ b/library/i18n/locales/zh/posterDesign.json @@ -28,7 +28,11 @@ "no": "否", "printHome": "任何家用打印机", "printShop": "印刷店(PDF,每张纸一页)", - "layoutNote": "纸张显示的是 3 × 3 英尺国家海报在各尺寸下的版式:标题、地图、名称、表格和经文页脚。各尺寸实际绘制的海报完成后会出现在“样式”中。" + "layoutNote": "纸张显示的是 3 × 3 英尺国家海报在各尺寸下的版式:标题、地图、名称、表格和经文页脚。各尺寸实际绘制的海报完成后会出现在“样式”中。", + "sideLanes": "{dims},两侧名单栏", + "packetPage1": "{paper}(祷告资料包第 1 页)", + "panels": "{dims},展板数:{n}", + "anySize": "共享尺寸表中的任意尺寸" }, "family": { "mapSheet": "地图页", diff --git a/plugin-designs/poster-design/poster-sizes.vue b/plugin-designs/poster-design/poster-sizes.vue index ec2c674b2..19f031522 100644 --- a/plugin-designs/poster-design/poster-sizes.vue +++ b/plugin-designs/poster-design/poster-sizes.vue @@ -20,19 +20,14 @@ import { POSTER_LADDER, POSTER_LADDER_ORDER, paperFor } from '@map/constants/pos import { useOptionalT, useOptionalI18n } from '@map/composables/useOptionalT.js' import { useShadowStyles } from '@map/composables/useShadowStyles.js' import { layoutSvgUrl } from './src/layoutSvg.js' +import { num, dimsText } from './src/sizeText.js' const t = useOptionalT('') const { locale } = useOptionalI18n('') -// A number as the sizes are spoken: whole, or one decimal place (5.5). -const n = (x) => (Number.isInteger(x) ? String(x) : String(Math.round(x * 10) / 10)) -// Feet once a side reaches a yard and both sides are whole or half feet (3 × 5.5 ft); inches below that (18 × 24 in). -function dims(w, h) { - const ft = (x) => x / 12 - const halfFeet = (x) => Number.isInteger(ft(x) * 2) - if (Math.min(w, h) >= 36 && halfFeet(w) && halfFeet(h)) return t('posterDesign.sizes.dimsFt', { w: n(ft(w)), h: n(ft(h)) }) - return t('posterDesign.sizes.dimsIn', { w: n(w), h: n(h) }) -} +// Sizes are named the one way Poster Design names them (src/sizeText.js, shared with Styles). +const n = num +const dims = (w, h) => dimsText(w, h, t) // Standard printer paper is Letter or A4 by the reader's region, as the print picker decides it. const paperIsA4 = computed(() => { const l = locale && (locale.value ?? locale) diff --git a/plugin-designs/poster-design/poster-styles.vue b/plugin-designs/poster-design/poster-styles.vue index 217031190..1fe3febbe 100644 --- a/plugin-designs/poster-design/poster-styles.vue +++ b/plugin-designs/poster-design/poster-styles.vue @@ -32,6 +32,7 @@ import { resolvePosterSize } from '@map/constants/posterSizes.js' import { listConfigurations, FAMILY_KEYS, SAMPLE_COUNTRY_ID } from './src/templates.js' import FullDetailsDialog from './src/FullDetailsDialog.vue' import { loadPluginDesigns } from './src/pluginDesigns.js' +import { sizeText, declaredSizeText } from './src/sizeText.js' const profileConfig = inject('profileConfig', ref(null)) const instanceId = computed(() => profileConfig.value?.instanceId || 'poster-design-styles') @@ -49,7 +50,7 @@ function stockLabel(s) { const dims = `${s.w} × ${s.h} in` return s.side ? `${noun} ${dims} (${t('wall.stockLandscape')})` : `${noun} ${dims}` } -const labelOf = (c) => (c.stock ? `${t(c.labelKey)}: ${stockLabel(c.stock)}` : `${t(c.labelKey)}: ${c.size}`) +const labelOf = (c) => (c.stock ? `${t(c.labelKey)}: ${stockLabel(c.stock)}` : `${t(c.labelKey)}: ${sizeText(c.size, t)}`) // Designs other plugins declare (their meta's posterDesign, via manifest.json): the built tree's manifest, or the dev // server's. A name already in templates.js stays the library's (the check refuses the clash; the page never doubles it). @@ -60,9 +61,17 @@ onMounted(async () => { const { designs } = await loadPluginDesigns(urls) pluginDesigns.value = designs.filter((d) => !byName.has(d.name)) }) -const pluginLabel = (d) => { +// The design's title in the reader's language: the build's per-locale titles (posterDesignLabels; any catalogue +// area), then this bundle's own catalogue, then English, then the profile's label. +const pluginTitle = (d) => { + const lang = String(getRuntimeLocale() || detectLocale() || 'en').split('-')[0] + if (d.titles && d.titles[lang]) return d.titles[lang] const v = d.labelKey ? t(d.labelKey) : '' - return `${v && v !== d.labelKey ? v : d.label}: ${d.size}` + if (v && v !== d.labelKey) return v + return (d.titles && d.titles.en) || d.label +} +const pluginLabel = (d) => { + return `${pluginTitle(d)}: ${declaredSizeText(d.size, t)}` } // No `count`: these are templates, not lists of people, so the sticker reads "Show full details" alone. @@ -175,15 +184,15 @@ async function sheet(item) { // ── "Show full details" ─────────────────────────────────────────────────────────────────────── const open = ref(null) -const openLabel = computed(() => (!open.value ? '' : open.value.design ? pluginLabel(open.value.design) : labelOf(open.value))) +const openLabel = computed(() => (!open.value ? '' : open.value.design ? pluginLabel(open.value.design) : labelOf(byName.get(open.value.name)))) // A plugin's design opens in the same dialog, as a configuration: its renderer is the plugin's page, and the dialog // shows that page live. function showDetails(item) { const d = byPluginName.value.get(item.id) open.value = d - ? { name: d.name, size: d.size, settings: { family: d.family, mobileFriendly: d.mobileFriendly, ...(d.instance ? { preset: d.instance } : {}) }, + ? { name: d.name, size: declaredSizeText(d.size, t), settings: { family: d.family, mobileFriendly: d.mobileFriendly, ...(d.instance ? { preset: d.instance } : {}) }, renderer: `plugin-designs/${d.bundle}/${d.profile}.vue`, pageUrl: d.pageUrl, design: d } - : byName.get(item.id) || null + : byName.has(item.id) ? { ...byName.get(item.id), size: sizeText(byName.get(item.id).size, t) } : null } const heading = computed(() => t('posterDesign.styles.heading')) diff --git a/plugin-designs/poster-design/src/FullDetailsDialog.vue b/plugin-designs/poster-design/src/FullDetailsDialog.vue index 06d73ab3a..cdf6d3e42 100644 --- a/plugin-designs/poster-design/src/FullDetailsDialog.vue +++ b/plugin-designs/poster-design/src/FullDetailsDialog.vue @@ -63,7 +63,7 @@ async function copyName() {
{{ config.name }}
{{ t('posterDesign.details.size') }}
-
{{ config.size }} · {{ config.px[0] }} × {{ config.px[1] }} px
+
{{ config.size }} · {{ ltr(`${config.px[0]} × ${config.px[1]} px`) }}