All failure paths of the download/extract/swap flow displayed the same
generic ERROR_DOWNLOADING popup, which made user reports impossible to
map to an actual cause (the recent .DS_Store swap failure surfaced as a
plain "download error" even though the download and extraction had both
succeeded).
- Replace the magic error indices with a DownloadError enum, so call
sites read _show_error(DownloadError.REPLACE_FAILED) instead of
_show_error(2) with a comment.
- Add three specific messages with fr/es/pt_BR/it translations:
- ERROR_EXTRACTING_PACKAGE: archive missing or extraction failed
- ERROR_INVALID_PACKAGE: extracted pack failed the validity check
(kept distinct from INVALID_LANGUAGE_DIRECTORY, which describes the
local pack found while offline)
- ERROR_REPLACING_PACKAGE: previous pack could not be removed or the
new one could not be renamed into place; tells the user to restart
and retry rather than suggesting a download problem
- ERROR_DOWNLOADING is now used only for actual download/server
failures.
Localization completeness check, naming lint and GUT suite (65/65) all
pass.
Reorders the left sidebar so risky actions sit at the bottom with a gap:
Dashboard, Synchronize, Logout | Change Language (red), Delete Account.
The new Change Language button opens a warning popup with a language
dropdown. On confirm, if the selected locale differs from the current
one, the client calls POST /reset_language. On success it wipes the
local teacher folder (progression, remediation, confusion matrix…),
applies the new language to device and teacher settings, logs out and
reloads from the splash screen. On error the user sees an error popup
and nothing local changes.
- Disable reset button while awaiting server response to prevent duplicate requests
- Show CHECK_YOUR_EMAIL message on success (was previously only logged, never shown)
- Show RESET_PASSWORD_FAILED message on failure instead of incorrectly showing CHECK_YOUR_EMAIL
- Re-enable the reset button only on failure so the user can try again
- Add RESET_PASSWORD_FAILED localization key in all supported languages (fr, es, pt_BR, it)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>