diff --git a/plugin-designs/posterverse/posterverse.vue b/plugin-designs/posterverse/posterverse.vue
index 0e2100807..ccb34e9c7 100644
--- a/plugin-designs/posterverse/posterverse.vue
+++ b/plugin-designs/posterverse/posterverse.vue
@@ -57,6 +57,11 @@
+
+
+
+
@@ -66,6 +71,8 @@
import { defineComponent, inject } from 'vue'
import VerticalTabsLayout from '@map/layouts/VerticalTabsLayout.vue'
import BackToTopButton from '@map/components/BackToTopButton.vue'
+import ShellLanguageMenu from '@map/components/ShellLanguageMenu.vue'
+import { saveLocale } from '@map/layouts/app-wrapper-material/languages.js'
import { loadScriptOnce, whenTagDefined } from '@map/utils/embedScript.js'
import { translate, LOCALES } from './src/strings.js'
import { SECTIONS, TABS, resolveTabs } from './src/tabs.js'
@@ -93,7 +100,7 @@ export default defineComponent({
// The host's attributes stay on the host: an inline style copied onto the layout root beats the
// layout's own rules (a styled host once collapsed a nested map to 76px).
inheritAttrs: false,
- components: { VerticalTabsLayout, BackToTopButton },
+ components: { VerticalTabsLayout, BackToTopButton, ShellLanguageMenu },
props: {
treeBase: { type: String, default: '' },
profileConfig: { type: [String, Object], default: '' },
@@ -128,6 +135,11 @@ export default defineComponent({
// The manifest's `runtime` block (the build's apiBaseUrl + public token), for foreign-page embeds.
runtime: {},
hostLang: detectHostLocale(),
+ // A language picked in THIS session through the menu, and the host's language value it was picked
+ // over. The pick wins only while that value is unchanged; the saved choice (loadLocale) is never
+ // read, since it falls back to the browser's language and would override the host page.
+ localPick: '',
+ pickBase: null,
// Until the manifest lands, the rail shows the rows that are expected to exist; provisional rows
// appear only once the manifest proves their bundle is in this tree.
tabs: TABS.filter((d) => !d.provisional).map(freshTab),
@@ -153,10 +165,13 @@ export default defineComponent({
return this.manifestBase ? this.manifestBase.replace(/\/+$/, '') + '/assets' : ''
},
headingText() { return String(this.cfg.heading || this.heading || '').trim() || 'Posterverse' },
- // Language precedence: what the host says, then the host page's own language, then English.
+ // The language the host passed: the `language` prop, else profile-config language / locale / lang.
+ hostLanguage() { return String(this.language || this.cfg.language || this.cfg.locale || this.cfg.lang || '').trim() },
+ // Language precedence: this session's menu pick (while the host's value is the one it was made over),
+ // then what the host says, then the host page's own language, then English.
effectiveLocale() {
- const fromProp = String(this.language || this.cfg.language || this.cfg.locale || this.cfg.lang || '').trim()
- return (fromProp || this.hostLang || 'en').split('-')[0].toLowerCase()
+ if (this.localPick && this.hostLanguage === this.pickBase) return this.localPick
+ return (this.hostLanguage || this.hostLang || 'en').split('-')[0].toLowerCase()
},
uiLocale() { return LOCALES.includes(this.effectiveLocale) ? this.effectiveLocale : 'en' },
uiDir() { return this.uiLocale === 'ar' ? 'rtl' : 'ltr' },
@@ -201,6 +216,8 @@ export default defineComponent({
this.mountElement(this.activeIndex)
},
tab(id) { if (id) this.onSelect(id) },
+ // A host that sets a new language takes over again: the session pick is dropped.
+ hostLanguage(v) { if (v !== this.pickBase) { this.localPick = ''; this.pickBase = null } },
},
mounted() {
this.watchHostLang()
@@ -213,6 +230,12 @@ export default defineComponent({
},
methods: {
tr(key, params) { return translate(this.uiLocale, key, params) },
+ // The menu's 'switch': no host cancelled the request, so the shell switches itself.
+ setLocale(code) {
+ this.pickBase = this.hostLanguage
+ this.localPick = code
+ saveLocale(code)
+ },
tabLabel(t) { return this.tr('tab.' + t.id) },
tabSub(t) { return t.section === 'experimental' ? this.tr('experimentalSub') : this.tr('sub.' + t.id) },
setSlot(i, el) { if (el) this._slots = Object.assign(this._slots || {}, { [i]: el }) },