Prayer Progress: no hardcoded English left in the map's own chrome

The Driver's localization list, item 4. doxa-simple-map already took its language from profile-config
locale/lang and ?lang= (ProfileLoader) and set dir=rtl for Arabic, but its own strings were English
literals: "Loading map…", "The map could not be loaded." plus a technical init message, the legend
title 'Legend', the default "Prayer" tab label, and the whole "About This Map" help modal. They now
read the catalogs: legend.titleBar.legend, tabs.<id>, allPeopleGroups.loadError, buttons.aboutThisMap,
buttons.close (the close button had no accessible name), and a new simpleMap area in all 11 locales.
A tab label a HOST passes in profileConfig.tabs is still shown as given. The map formats no numbers
itself; the legend, popups and detail panel are library components already translated.
check:i18n-parity PASS; the bundle builds. A library catalog change, so studio lands it (rule 5B).
needs eyes: Prayer Progress with ?lang=ar: the loading line, the tab, the legend title and RTL layout.

(cherry picked from commit c35bc84794)
This commit is contained in:
Doxa Maps 2026-09-26 00:59:05 +00:00
parent 730df6a69a
commit 5ded530b43
12 changed files with 114 additions and 11 deletions

View file

@ -0,0 +1,9 @@
{
"loading": "جارٍ تحميل الخريطة…",
"initFailed": "تعذّر تشغيل الخريطة. هذه مشكلة في رمز الخريطة أو في الاتصال.",
"help": {
"what": "تعرض هذه الخريطة الشعوب غير المُبشَّرة في العالم: مجتمعات لا تصل إلى الإنجيل وصولًا حقيقيًا.",
"how": "استخدم الألسنة (إن ظهرت) للتبديل بين العروض. انقر أي نقطة لمعرفة المزيد عن شعب.",
"source": "البيانات من"
}
}

View file

@ -0,0 +1,9 @@
{
"loading": "Karte wird geladen…",
"initFailed": "Die Karte konnte nicht starten. Das ist ein Problem mit dem Kartenschlüssel oder der Verbindung.",
"help": {
"what": "Diese Karte zeigt die unerreichten Volksgruppen der Welt: Gemeinschaften ohne echten Zugang zum Evangelium.",
"how": "Mit den Reitern (falls sichtbar) wechseln Sie die Ansicht. Klicken Sie auf einen Punkt, um mehr über eine Volksgruppe zu erfahren.",
"source": "Daten von"
}
}

View file

@ -0,0 +1,9 @@
{
"loading": "Loading map…",
"initFailed": "The map could not start. This is a map-token or connection problem.",
"help": {
"what": "This map shows the unreached people groups of the world: communities without meaningful access to the Gospel.",
"how": "Use the tabs (if shown) to switch between views. Click any dot to learn more about a people group.",
"source": "Data from"
}
}

View file

@ -0,0 +1,9 @@
{
"loading": "Cargando mapa…",
"initFailed": "El mapa no pudo iniciarse. Es un problema de la clave del mapa o de la conexión.",
"help": {
"what": "Este mapa muestra los pueblos no alcanzados del mundo: comunidades sin acceso real al Evangelio.",
"how": "Usa las pestañas (si aparecen) para cambiar de vista. Haz clic en cualquier punto para saber más de un pueblo.",
"source": "Datos de"
}
}

View file

@ -0,0 +1,9 @@
{
"loading": "Chargement de la carte…",
"initFailed": "La carte n’a pas pu démarrer. C’est un problème de clé de carte ou de connexion.",
"help": {
"what": "Cette carte montre les peuples non atteints du monde : des communautés sans véritable accès à l’Évangile.",
"how": "Utilisez les onglets (s’ils s’affichent) pour changer de vue. Cliquez sur un point pour en savoir plus sur un peuple.",
"source": "Données :"
}
}

View file

@ -0,0 +1,9 @@
{
"loading": "नक्शा लोड हो रहा है…",
"initFailed": "नक्शा शुरू नहीं हो सका। यह नक्शे की कुंजी या कनेक्शन की समस्या है।",
"help": {
"what": "यह नक्शा दुनिया के अपहुँचे जनसमूह दिखाता है: ऐसे समुदाय जिनकी सुसमाचार तक वास्तविक पहुँच नहीं है।",
"how": "दृश्य बदलने के लिए टैब (यदि दिखें) का उपयोग करें। किसी जनसमूह के बारे में जानने के लिए किसी भी बिंदु पर क्लिक करें।",
"source": "डेटा स्रोत"
}
}

View file

@ -0,0 +1,9 @@
{
"loading": "Caricamento della mappa…",
"initFailed": "La mappa non è partita. È un problema della chiave della mappa o della connessione.",
"help": {
"what": "Questa mappa mostra i popoli non raggiunti del mondo: comunità senza un vero accesso al Vangelo.",
"how": "Usa le schede (se presenti) per cambiare vista. Clicca su un punto per saperne di più su un popolo.",
"source": "Dati da"
}
}

View file

@ -0,0 +1,9 @@
{
"loading": "A carregar o mapa…",
"initFailed": "O mapa não pôde iniciar. É um problema da chave do mapa ou da ligação.",
"help": {
"what": "Este mapa mostra os povos não alcançados do mundo: comunidades sem acesso real ao Evangelho.",
"how": "Use os separadores (se visíveis) para mudar de vista. Clique em qualquer ponto para saber mais sobre um povo.",
"source": "Dados de"
}
}

View file

@ -0,0 +1,9 @@
{
"loading": "Se încarcă harta…",
"initFailed": "Harta nu a putut porni. Este o problemă de cheie a hărții sau de conexiune.",
"help": {
"what": "Această hartă arată popoarele neatinse ale lumii: comunități fără acces real la Evanghelie.",
"how": "Folosiți filele (dacă apar) pentru a schimba vederea. Dați clic pe un punct pentru a afla mai multe despre un popor.",
"source": "Date de la"
}
}

View file

@ -0,0 +1,9 @@
{
"loading": "Загрузка карты…",
"initFailed": "Карта не запустилась. Это проблема ключа карты или соединения.",
"help": {
"what": "Эта карта показывает неохваченные народы мира: общины без настоящего доступа к Евангелию.",
"how": "Переключайте виды вкладками (если они показаны). Нажмите на любую точку, чтобы узнать больше о народе.",
"source": "Данные:"
}
}

View file

@ -0,0 +1,9 @@
{
"loading": "正在加载地图…",
"initFailed": "地图无法启动。这是地图密钥或网络连接的问题。",
"help": {
"what": "这张地图显示世界上的未得之民:尚未真正接触福音的群体。",
"how": "使用标签页(如有显示)切换视图。点击任意圆点了解该族群。",
"source": "数据来源"
}
}

View file

@ -208,7 +208,7 @@ useShadowStyles(`
`, 'doxa-simple-map')
// ─── i18n ─────────────────────────────────────────────────────────────────────
const { t, locale } = useI18n()
const { t, te, locale } = useI18n()
// ─── Mapbox basemap localisation ──────────────────────────────────────────────
// On Mapbox Standard / Streets styles, common label layers carry per-locale
@ -282,6 +282,10 @@ const DEFAULT_TABS = [
{ id: 'prayer', label: 'Prayer', colorStrategy: 'prayer', legend: 'prayer', popup: 'prayer' }
]
const tabs = computed(() => profileConfig?.value?.tabs ?? DEFAULT_TABS)
// A built-in tab reads its label from tabs.<id> in the reader's language. A label the HOST passed in
// profileConfig.tabs is the host's own words and is shown as given.
const DEFAULT_LABELS = Object.fromEntries(DEFAULT_TABS.map((d) => [d.id, d.label]))
const tabLabel = (tab) => ((!tab.label || tab.label === DEFAULT_LABELS[tab.id]) && te('tabs.' + tab.id)) ? t('tabs.' + tab.id) : tab.label
const showTabBar = computed(() => tabs.value.length > 1)
// ─── Tab state ────────────────────────────────────────────────────────────────
@ -362,7 +366,7 @@ function _flatItemsToStlNodes(items) {
return out
}
const legendNodes = computed(() => _flatItemsToStlNodes(flatLegend.items.value))
const legendTitle = computed(() => 'Legend')
const legendTitle = computed(() => t('legend.titleBar.legend'))
// Prayer progress bar (header of the prayer legend; Driver 2026-09-16). The payload
// is null on every non-prayer tab → no bar. Passed as a prop to the desktop STL
// below AND provide()d so the MOBILE sheet's embedded <SemanticTreeLegend>
@ -1309,7 +1313,7 @@ onMounted(async () => {
if (!map.value) {
console.error('[doxa-simple-map] Map failed to initialize — check token and container')
mapError.value = 'Map failed to initialize — check token and container'
mapError.value = t('simpleMap.initFailed')
return
}
@ -1354,14 +1358,14 @@ onBeforeUnmount(() => {
:class="{ active: activeTabId === tab.id }"
@click="switchTab(tab.id)"
>
{{ tab.label }}
{{ tabLabel(tab) }}
</button>
</div>
<!-- Map area -->
<div class="dsm-map-area">
<div v-if="!appReady && !mapError" class="dsm-loading">Loading map…</div>
<div v-if="mapError" class="dsm-error">The map could not be loaded. {{ mapError }}</div>
<div v-if="!appReady && !mapError" class="dsm-loading">{{ t('simpleMap.loading') }}</div>
<div v-if="mapError" class="dsm-error">{{ t('allPeopleGroups.loadError') }} {{ mapError }}</div>
<div ref="mapContainer" class="dsm-map-canvas" />
<!-- Geocoder search bar — added to top-left first so hamburger floats right of it.
@ -1469,11 +1473,11 @@ onBeforeUnmount(() => {
<!-- Help popup modal -->
<div v-if="showHelpPopup" class="dsm-help-overlay" @click.self="showHelpPopup = false">
<div class="dsm-help-modal">
<button class="dsm-help-close" @click="showHelpPopup = false">×</button>
<h2>About This Map</h2>
<p>This map displays Unreached People Groups (UPGs) around the world — communities without meaningful access to the Gospel.</p>
<p>Use the tabs (if shown) to switch between Prayer and Engagement views. Click any dot to learn more about a people group.</p>
<p>Data sourced from <strong>pray.doxa.life</strong>.</p>
<button class="dsm-help-close" :aria-label="t('buttons.close')" @click="showHelpPopup = false">×</button>
<h2>{{ t('buttons.aboutThisMap') }}</h2>
<p>{{ t('simpleMap.help.what') }}</p>
<p>{{ t('simpleMap.help.how') }}</p>
<p>{{ t('simpleMap.help.source') }} <strong dir="ltr">pray.doxa.life</strong>.</p>
</div>
</div>
</div>