One rule for countries too large for paper: countrySheet.js's LARGE_SHEETS; whole-India list, packet and cards on a desktop
CORRECTS the previous commit's "no prayer list, packet or cards for whole India": the current direction is that
whole India's poster, list, packet and cards (about a thousand pages) are offered DESKTOP-ONLY, and a phone shows
the existing poster.phoneLimit sentence instead of failing.
countrySheet.js now exports LARGE_SHEETS ({ IND: 60x96, desktopOnly }) and largeSheet(item), and makeCountrySheet
itself prints such a country in its large format (a packet page stays a page) with its "Administrative Areas"
cell from the shared state table ("36 states and union territories"). So every caller gets the same sheet: the
Regions list's India no longer has to disagree with Country Posters (regions-list's own lines follow, from regions).
The wall drops its India-only code and follows the same rule.
This commit is contained in:
parent
1c61cbb926
commit
455fa8ab7d
2 changed files with 36 additions and 22 deletions
|
|
@ -72,6 +72,27 @@ export function seriesFor(countries, item) {
|
|||
return { totalGroups: tier.reduce((a, x) => a + (x.count || 0), 0), totalLists: tier.length, index }
|
||||
}
|
||||
|
||||
/**
|
||||
* ★ COUNTRIES TOO LARGE FOR ANY PAPER SHEET print as ONE LARGE side-lane sheet instead (poster-render's 60x96 /
|
||||
* 66x66 / 36x60: every group named beside the map, crossing-free leaders). ONE source of truth for every caller (the
|
||||
* Country Posters wall, the Regions list), so one country never gets two answers. `desktopOnly`: its poster, list,
|
||||
* packet and cards are offered on a desktop or laptop only (a phone cannot draw a sheet that big).
|
||||
* The data (country-posters.json) still records why no PAPER sheet fits; this table is what prints instead.
|
||||
*/
|
||||
export const LARGE_SHEETS = { IND: { format: '60x96', desktopOnly: true } }
|
||||
export function largeSheet(item) { return (item && LARGE_SHEETS[String(item.iso3 || '').toUpperCase()]) || null }
|
||||
|
||||
// The facts row's "Administrative Areas" cell for a large-sheet country whose divisions we know (India: its states and
|
||||
// union territories, counted from the shared state table). English, like the rest of the sheet.
|
||||
async function adminAreasFor(iso3, base) {
|
||||
if (iso3 !== 'IND') return undefined
|
||||
try {
|
||||
const { loadIndiaStates } = await import('@map/data/indiaStates.js')
|
||||
const n = ((await loadIndiaStates(base)).states || []).length
|
||||
return n ? `${n} states and union territories` : undefined
|
||||
} catch (_) { return undefined } // the cell falls back to the country's name
|
||||
}
|
||||
|
||||
export function makeCountrySheet({ records, assetsBase, countries = null }) {
|
||||
return async function countrySheet(item, format) {
|
||||
const iso3 = item && item.iso3
|
||||
|
|
@ -84,14 +105,16 @@ export function makeCountrySheet({ records, assetsBase, countries = null }) {
|
|||
records({ type: 'country', values: [iso3] }),
|
||||
])
|
||||
if (!rows || !rows.length) return '' // nothing to pin: fall through rather than draw an empty country
|
||||
const big = largeSheet(item)
|
||||
const adminAreas = item.adminAreas || (big ? await adminAreasFor(String(iso3).toUpperCase(), assetsBase()) : undefined)
|
||||
return generateCountrySheet({
|
||||
// region travels: countryZone colours the sheet from it, and a country arriving without one
|
||||
// silently falls back to the old flat teal for that poster alone.
|
||||
country: { id: item.id, iso3, label: item.label, count: item.count, region: item.region, adminAreas: item.adminAreas },
|
||||
country: { id: item.id, iso3, label: item.label, count: item.count, region: item.region, adminAreas },
|
||||
records: rows,
|
||||
assetsBase: assetsBase(),
|
||||
ISO3_NAME,
|
||||
format,
|
||||
format: big && format !== 'packet' ? big.format : format, // a packet's page 1 stays a page
|
||||
series: seriesFor(countries, item),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
import { computed, inject, ref, watch } from 'vue'
|
||||
import PosterWall from '@map/components/poster/PosterWall.vue'
|
||||
import { useOptionalT, useOptionalI18n, pickPluralForm, fillParams } from '@map/composables/useOptionalT.js'
|
||||
import { useOptionalT, useOptionalI18n } from '@map/composables/useOptionalT.js'
|
||||
// A country's name in the reader's language (Intl, joined from our ISO-3 codes).
|
||||
import { countryName } from '@map/utils/countryName.js'
|
||||
import { createPeopleGroupRecords } from '@map/lists/peopleGroupRecords.js'
|
||||
|
|
@ -48,7 +48,8 @@ import { getRuntimeLocale, detectLocale } from '@map/i18n/index.js'
|
|||
// library/. Generated by library/scripts/posters/emit-countries.mjs, which now writes there.
|
||||
import data from '@map/data/country-posters.json'
|
||||
import { resolveAssetsBase } from '@map/utils/embedBase.js'
|
||||
import { makeCountrySheet } from '@map/packet/countrySheet.js'
|
||||
import { makeCountrySheet, largeSheet } from '@map/packet/countrySheet.js'
|
||||
import { isPhonePrint } from '@map/composables/printInPlace.js'
|
||||
// India's states and union territories: the shared table (fetched when the wall shows them) and their sheet.
|
||||
import { loadIndiaStates } from '@map/data/indiaStates.js'
|
||||
import { makeIndiaStateSheet, statesWithPosters } from './src/indiaStateSheet.js'
|
||||
|
|
@ -149,10 +150,12 @@ const recordsFor = createPeopleGroupRecords({
|
|||
lang: () => getRuntimeLocale() || detectLocale(),
|
||||
profileConfig,
|
||||
})
|
||||
// ★ THE WHOLE-INDIA POSTER IS THE POSTER ONLY: no prayer list, packet or cards (855 groups would make a book), so its
|
||||
// card's rows are empty. Its sheet still draws every group: makeCountrySheet fetches them itself.
|
||||
const isWholeIndia = (c) => !c.indiaState && String(c.iso3 || '').toUpperCase() === 'IND'
|
||||
const countryRecords = (c) => (isWholeIndia(c) ? Promise.resolve([]) : c.indiaState
|
||||
// ★ A LARGE-SHEET COUNTRY (India: one 5x8 sheet naming all its groups; countrySheet.js's LARGE_SHEETS) is DESKTOP-ONLY:
|
||||
// its poster, list, packet and cards (about a thousand pages) are offered on a desktop or laptop, and on a phone the
|
||||
// card says so instead of failing. Same rule as the Regions list, from the same table.
|
||||
const ON_PHONE = isPhonePrint()
|
||||
const phoneBlocked = (c) => !c.indiaState && ON_PHONE && Boolean(largeSheet(c)?.desktopOnly)
|
||||
const countryRecords = (c) => (phoneBlocked(c) ? Promise.resolve([]) : c.indiaState
|
||||
? (c.slugs.length ? recordsFor({ type: 'pg_slugs', values: c.slugs }) : Promise.resolve([]))
|
||||
: recordsFor({ type: 'country', values: [c.iso3] }))
|
||||
// ★ GENERATED AT THE CLICK, through the ONE shared path (@map/packet/countrySheet.js, which the Regions
|
||||
|
|
@ -168,19 +171,7 @@ const sheetForRecord = makeCountrySheet({
|
|||
assetsBase: () => assetsBase.value,
|
||||
countries: data.countries || [],
|
||||
})
|
||||
// ★ INDIA PRINTS AS ONE LARGE SIDE-LANE SHEET (60x96: every group named beside the map, one leader per cluster),
|
||||
// whatever paper the wall asks for, until the shared size picker also offers 66x66 and 36x60. Its facts row names
|
||||
// the true count of its divisions, in English like the rest of the sheet, from the same plural key as the wall head.
|
||||
const INDIA_FORMAT = '60x96'
|
||||
const indiaAdminAreas = () => {
|
||||
const n = (indiaStates.value || []).length
|
||||
return n ? fillParams(pickPluralForm(tStatic('countryPosters.indiaItemCount', 'en') || '', n, 'en'), { n }) : undefined
|
||||
}
|
||||
const countryOnlySheet = (card, format) => {
|
||||
const rec = byId.get(card.id) || card
|
||||
if (isWholeIndia(rec) && format !== 'packet') return sheetForRecord({ ...rec, adminAreas: indiaAdminAreas() }, INDIA_FORMAT)
|
||||
return sheetForRecord(rec, format)
|
||||
}
|
||||
const countryOnlySheet = (card, format) => sheetForRecord(byId.get(card.id) || card, format)
|
||||
// A state's sheet through its own ONE path (src/indiaStateSheet.js), in India's hue and the indiaState series.
|
||||
const stateSheet = makeIndiaStateSheet({
|
||||
records: recordsFor, assetsBase: () => assetsBase.value, states: () => indiaStates.value, region: INDIA_REGION,
|
||||
|
|
@ -238,7 +229,7 @@ const collapsedBy = (sec) => sec.total < 60
|
|||
// unsupportedReason is an English note (and a flag), not display text. The card already states the
|
||||
// count above it, so the sentence needs no number and no plural agreement.
|
||||
// A requested country with no poster at all says so in regions-list.vue's words (the regions catalogue).
|
||||
const unsupported = (c) => (c.noGroups ? t('countryPosters.indiaStateNoGroups') : c.noPoster ? tRegions('No poster has been generated for this country yet.') : c.unsupportedReason && !isWholeIndia(c) ? t('messages.countryPosterTooMany') : null)
|
||||
const unsupported = (c) => (c.noGroups ? t('countryPosters.indiaStateNoGroups') : c.noPoster ? tRegions('No poster has been generated for this country yet.') : phoneBlocked(c) ? t('poster.phoneLimit') : c.unsupportedReason && !largeSheet(c) ? t('messages.countryPosterTooMany') : null)
|
||||
|
||||
// ★ THROUGH THE CATALOGUE, like the UPG-100 wall: the heading, the tag, the intro and the counts read
|
||||
// in the page's language. The intro keeps its one emphasis as three plain keys (A, the emphasis, B)
|
||||
|
|
|
|||
Loading…
Reference in a new issue