ReviewOS

stacks/lastsoulultra

Language switcher is silent for one to two seconds before the page reloads

#19
Open glennmichael123 opened this 3 days ago ·
3 days ago

Clicking a language in the footer switcher does nothing visible for one to two seconds, then the page reloads in the new language. The click reads as ignored, and the obvious response is to click again.

Found while reviewing the LSU installation. The code is in hq.training, resources/components/LanguageSwitch.stx.

Why the gap exists

pickLanguage awaits two separate things before anything on screen changes, and neither reports progress:

async function pickLanguage(event, code) {
  event.preventDefault()
  if (code === uiLocale()) return
  try {
    if (languageSwitchAuth.isAuthenticated?.()) {
      await languageSwitchAuth.authFetch('/api/profile', { method: 'PUT', ... })   // network round trip
    }
  }
  catch { }
  await switchLocale(code)
}

and switchLocale (resources/lang/client.ts:160) awaits a second one before it navigates:

rememberLocale(locale)
try { await refreshKeptPages(locale) }   // refreshes the kept copies
catch { }
location.reload()

So for a signed-in person it is: save the account language, refresh the kept pages, then reload. The preventDefault() means the anchor's own navigation does not happen either, so there is no browser loading indicator to stand in for one.

What it should do

Give the control a pending state from the moment it is clicked:

  • Swap the i-lucide-languages icon for the inline spinner already used elsewhere, which is a border ring rather than an icon and is the same h-3.5 w-3.5 as the icon it replaces, so nothing shifts: <span class="h-3.5 w-3.5 border-2 border-current border-t-transparent rounded-full animate-spin"> (resources/components/CoachAssistantWebsite.stx:407 is the existing example; animate-spin is used 23 times across the templates).
  • Put aria-busy on the role="group" wrapper, which 14 other places already do.
  • Ignore a second click while one is in flight. Today a double click fires two PUT /api/profile calls.
  • Clear the pending state if switchLocale throws, since nothing has navigated and the control would otherwise spin forever.

A spinner needs a label. There is no common.language.* string for it yet, so this wants one new key in en and de.

Not in this issue

The one to two seconds itself. Saving the account language before switching is correct, and refreshKeptPages is doing real work. This is only about the switch being silent while it happens.

Sign in to comment on this issue.