From de75e8d6d0d31e875613e8094f2c0613e4b75966 Mon Sep 17 00:00:00 2001 From: olcxja Date: Wed, 30 Sep 2026 17:59:15 +0200 Subject: [PATCH] fix translations extracting --- README.md | 2 ++ package.json | 4 +--- src/paths.js | 48 +++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 614e3e0..0a88a00 100644 --- a/README.md +++ b/README.md @@ -56,3 +56,5 @@ The desktop entry (`MimeType` + `Exec %f`) makes PLWL show up in Dolphin/Nautilu ## 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. + +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. diff --git a/package.json b/package.json index 3180480..1b4f57c 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,7 @@ "description": "Portable Linux Wine Launcher", "main": "src/main.js", "scripts": { - "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" + "start": "electron ." }, "devDependencies": { "@electron/asar": "^3.4.1", diff --git a/src/paths.js b/src/paths.js index 71310c1..b244087 100644 --- a/src/paths.js +++ b/src/paths.js @@ -50,17 +50,51 @@ const DIRS = { 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() { for (const dir of [FILES, DATA, DIRS.WINES, DIRS.PREFIXES, DIRS.APPS, DIRS.TRANSLATIONS, DIRS.FAKE_STEAM]) { fs.mkdirSync(dir, { recursive: true }) } if (DIRS.TRANSLATIONS !== DIRS.BUNDLED_TRANSLATIONS) { - try { - 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 {} + syncBundledTranslations(DIRS.BUNDLED_TRANSLATIONS, DIRS.TRANSLATIONS) } } @@ -95,4 +129,4 @@ function writeJson(file, data) { 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 }