fix translations extracting

This commit is contained in:
olcxja 2026-09-30 17:59:15 +02:00
commit de75e8d6d0
3 changed files with 44 additions and 10 deletions

View file

@ -56,3 +56,5 @@ The desktop entry (`MimeType` + `Exec %f`) makes PLWL show up in Dolphin/Nautilu
## Translations ## Translations
All UI text comes from JSON files in `files/translations/`. The `data` object carries the language names; `texts` maps keys to strings, with `{0}`, `{1}` ... placeholders filled at runtime. All UI text comes from JSON files in `files/translations/`. The `data` object carries the language names; `texts` maps keys to strings, with `{0}`, `{1}` ... placeholders filled at runtime.
The translations bundled with a release are launcher-owned: on every start they are refreshed into `files/translations/` whenever their content changed, so launcher updates deliver new/changed keys to existing installs. Extra language files the bundle does not ship (user-added) are never touched.

View file

@ -5,9 +5,7 @@
"description": "Portable Linux Wine Launcher", "description": "Portable Linux Wine Launcher",
"main": "src/main.js", "main": "src/main.js",
"scripts": { "scripts": {
"start": "electron .", "start": "electron ."
"test": "node test/import.test.js && node test/prefix-import.test.js && node test/icons.test.js && node test/shortcuts.test.js && node test/wines-portable.test.js && node test/openwith.test.js",
"smoke": "node test/import.test.js && node test/prefix-import.test.js && node test/icons.test.js && node test/shortcuts.test.js && node test/wines-portable.test.js && node test/openwith.test.js"
}, },
"devDependencies": { "devDependencies": {
"@electron/asar": "^3.4.1", "@electron/asar": "^3.4.1",

View file

@ -50,17 +50,51 @@ const DIRS = {
FAKE_STEAM: path.join(DATA, 'fake-steam') FAKE_STEAM: path.join(DATA, 'fake-steam')
} }
// Bundled translation files are launcher-owned: on every start they are
// refreshed in the portable files/translations folder WHENEVER THEIR CONTENT
// CHANGED, so an update shipping new or changed keys reaches existing
// installs too (the old copy-only-if-missing logic froze translations at the
// version that happened to run first). Extra files in the target folder that
// the bundle does not ship (user-added languages) are left untouched.
function filesDiffer(a, b) {
try {
return !fs.readFileSync(a).equals(fs.readFileSync(b))
} catch {
return true // target missing/unreadable -> needs a (re)copy
}
}
function syncBundledTranslations(bundledDir, targetDir) {
let names = []
try {
names = fs.readdirSync(bundledDir)
} catch {
return 0
}
let updated = 0
for (const name of names) {
const src = path.join(bundledDir, name)
const dst = path.join(targetDir, name)
try {
if (!fs.statSync(src).isFile()) continue
} catch {
continue
}
if (!filesDiffer(src, dst)) continue
try {
fs.copyFileSync(src, dst)
updated++
} catch {}
}
return updated
}
function ensureDirs() { function ensureDirs() {
for (const dir of [FILES, DATA, DIRS.WINES, DIRS.PREFIXES, DIRS.APPS, DIRS.TRANSLATIONS, DIRS.FAKE_STEAM]) { for (const dir of [FILES, DATA, DIRS.WINES, DIRS.PREFIXES, DIRS.APPS, DIRS.TRANSLATIONS, DIRS.FAKE_STEAM]) {
fs.mkdirSync(dir, { recursive: true }) fs.mkdirSync(dir, { recursive: true })
} }
if (DIRS.TRANSLATIONS !== DIRS.BUNDLED_TRANSLATIONS) { if (DIRS.TRANSLATIONS !== DIRS.BUNDLED_TRANSLATIONS) {
try { syncBundledTranslations(DIRS.BUNDLED_TRANSLATIONS, DIRS.TRANSLATIONS)
for (const f of fs.readdirSync(DIRS.BUNDLED_TRANSLATIONS)) {
const dst = path.join(DIRS.TRANSLATIONS, f)
if (!fs.existsSync(dst)) fs.copyFileSync(path.join(DIRS.BUNDLED_TRANSLATIONS, f), dst)
}
} catch {}
} }
} }
@ -95,4 +129,4 @@ function writeJson(file, data) {
fs.renameSync(tmp, file) fs.renameSync(tmp, file)
} }
module.exports = { RESOURCES, APP_ROOT, BUILD, FILES, DATA, DIRS, ensureDirs, readJson, writeJson, toPortablePath, resolvePortablePath } module.exports = { RESOURCES, APP_ROOT, BUILD, FILES, DATA, DIRS, ensureDirs, syncBundledTranslations, readJson, writeJson, toPortablePath, resolvePortablePath }