From 1285e1e8799815963e48ae6d387e31de2e6acd13 Mon Sep 17 00:00:00 2001 From: kap1bala <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 00:18:26 +0800 Subject: [PATCH 01/14] feat: add i18n support and chinese translations --- i18n.js | 91 ++++++++++++++++++++ index.htm | 251 ++++++++++++++++++++++++++++++------------------------ script.js | 7 +- 3 files changed, 236 insertions(+), 113 deletions(-) create mode 100644 i18n.js diff --git a/i18n.js b/i18n.js new file mode 100644 index 0000000..0656022 --- /dev/null +++ b/i18n.js @@ -0,0 +1,91 @@ +// i18n.js - Internationalization for WLED Web Installer + +// Translation messages +const i18n_messages = { + "en": { + "maintenance1": "Web Installer under maintenance", + "maintenance2": "The WLED web installer is currently out of service due to maintenance work and will be back online shortly.", + "maintenance3": "In the meantime, you can use the webinstaller provided by Wladi: ", + "welcome": "Welcome to the WLED web installer!", + "unsupported1": "Sorry, your browser is not yet supported!", + "unsupported2": "Please try on Desktop Chrome or Edge.", + "unsupported3": "Find binary files here:", + "step1-1": "Plug in your ESP to a USB port. We will install WLED ", + "step1-2": " to it.", + "step2": "Hit \"Install\" and select the correct COM port.", + "noDeviceFound": "No device found?", + "serialHelp1": "You might be missing the drivers for your board.", + "serialHelp2": "Here are drivers for chips commonly used in ESP boards:", + "serialHelp3": "Make sure your USB cable supports data transfer.", + "chip1": "CP2102 (square chip)", + "chip2": "CH34x (rectangular chip)", + "step3": "Get WLED installed and connected in less than 3 minutes!", + "install": "Install", + "powered1": "Powered by ", + "powered2": " ", + "cors1": "CORS proxy by ", + "cors2": " " + }, + "zh-CN": { + "maintenance1": "网络安装程序正在维护中", + "maintenance2": "由于维护工作,WLED 网络安装程序目前无法使用,但它将很快重新上线。", + "maintenance3": "在此期间,您可以使用 Wladi 提供的网络安装程序:", + "welcome": "欢迎使用 WLED 网络安装程序!", + "unsupported1": "抱歉,尚不支持您使用的浏览器!", + "unsupported2": "请在桌面版 Chrome 或 Edge 上尝试。", + "unsupported3": "在此处查找二进制文件:", + "step1-1": "将您的 ESP 插入 USB 端口。我们将向其安装 WLED ", + "step1-2": " 。", + "step2": "点击“安装”并选择正确的 COM 端口。", + "noDeviceFound": "未找到设备?", + "serialHelp1": "您可能缺少开发板的驱动程序。", + "serialHelp2": "以下是 ESP 开发板常用的芯片驱动程序:", + "serialHelp3": "确保您的 USB 数据线支持数据传输。", + "chip1": "CP2102(正方形芯片)", + "chip2": "CH34x(长方形芯片)", + "step3": "在不到 3 分钟的时间内安装并连接 WLED!", + "install": "安装", + "powered1": " ", + "powered2": " 强力驱动", + "cors1": "CORS 代理由 ", + "cors2": " 提供支持" + } +}; + + +// Function to update text content based on selected language +function i18n() { + document.querySelectorAll('[data-i18n]').forEach(function (elem) { + const key = elem.getAttribute('data-i18n'); + const translation = i18n_messages[document.querySelector('select').value][key]; + if (translation) { + elem.textContent = translation; + } + }); +} + + +// Initialize i18n on page load +function i18nInit() { + // Get saved language from localStorage + let savedLang = localStorage.getItem('Language'); + + // If no saved language or not in the list of supported languages, set default to English + if (!savedLang || !i18n_messages[savedLang]) { + localStorage.setItem('Language', 'en'); + } + + // Set the select element to the saved language + document.getElementById('languageSelect').value = localStorage.getItem('Language'); + + // Apply translations + i18n(); +} + + +// Event for language selection change +function changeLanguage() { + let selectedLang = document.getElementById('languageSelect').value; + localStorage.setItem('Language', selectedLang); + i18n(); +} \ No newline at end of file diff --git a/index.htm b/index.htm index f7c8fe0..0ef4621 100644 --- a/index.htm +++ b/index.htm @@ -1,130 +1,159 @@ + - + - + - Install WLED + Install WLED - + + + +
-
-

Web Installer under maintenance

-
The WLED web installer is currently out of service due to maintenance work and will be back online shortly. -

In the meantime, you can use the webinstaller provided by Wladi: https://wled-install.github.io/ +
+

Web Installer under maintenance


+ The WLED web installer is currently out of service due to maintenance work and will be back online shortly.

+ In the meantime, you can use the webinstaller provided by Wladi: + https://wled-install.github.io/ +
-
- -
-

Welcome to the WLED web installer!

- - - -
- -
    -
  1. Plug in your ESP to a USB port. We will install WLED 0.12.0 to it.
  2. -
  3. Hit "Install" and select the correct COM port. - No device found? - -
  4. + + + -
  5. Get WLED installed and connected in less than 3 minutes!
  6. -


- - -
- -
- - - - - - - - - - - - -
-
-
- - -
-
+
+ + + + +

Welcome to the WLED web installer!

+ + +
+
    +
  1. + Plug in your ESP to a USB port. We will install WLED + 0.12.0 + to it. +
  2. +
  3. + Hit "Install" and select the correct COM port. + No device found? + +
  4. -

    Powered by ESP Web Tools
    -CORS proxy by Corsfix
    -
    GitHubkno.wled.ge +
  5. Get WLED installed and connected in less than 3 minutes!
  6. +
+

- + +
+ +
+ + + + + + + + + + + + +
+
+ +
+ + +
+
+ +

+ Powered by + ESP Web Tools +
+ + CORS proxy by + Corsfix +
+ +
GitHubkno.wled.ge + + + + diff --git a/script.js b/script.js index 06f857b..1b401b9 100644 --- a/script.js +++ b/script.js @@ -24,7 +24,6 @@ function setManifest() { } - function handleCheckbox(manifest, checkboxmanifest, primaryCheckbox) { //Check if specified manifest is available @@ -44,6 +43,7 @@ function handleCheckbox(manifest, checkboxmanifest, primaryCheckbox) { return manifest; } + function resetCheckboxes() { const checkBoxIds = ['ethernet', 'audio', 'test', 'v4', 'debug']; checkBoxIds.forEach(id => { @@ -55,17 +55,20 @@ function resetCheckboxes() { }); } + function checkSupported() { if (document.getElementById('inst').hasAttribute('install-unsupported')) unsupported(); else setManifest(); } + function unsupported() { document.getElementById('flasher').hidden = true; document.getElementById('unsupported').hidden = false; } + function showSerialHelp() { document.getElementById('showSerialHelp').hidden = true; document.getElementById('serialHelp').hidden = false; -} +} \ No newline at end of file From b4635adfa2b2fef7c7d41288379306a3c8fcede5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=A1=E7=9A=AE=E5=B7=B4=E6=8B=89?= <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 00:28:28 +0800 Subject: [PATCH 02/14] perf: improve function i18n Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- i18n.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/i18n.js b/i18n.js index 0656022..45f2d11 100644 --- a/i18n.js +++ b/i18n.js @@ -55,9 +55,12 @@ const i18n_messages = { // Function to update text content based on selected language function i18n() { + const lang = document.getElementById('languageSelect').value; + const messages = i18n_messages[lang] || i18n_messages['en']; // Fallback to English + document.querySelectorAll('[data-i18n]').forEach(function (elem) { const key = elem.getAttribute('data-i18n'); - const translation = i18n_messages[document.querySelector('select').value][key]; + const translation = messages[key]; if (translation) { elem.textContent = translation; } From 044a01ad318f1e2719ab6efdc69d44290b793e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=A1=E7=9A=AE=E5=B7=B4=E6=8B=89?= <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 00:31:45 +0800 Subject: [PATCH 03/14] perf: improve function i18nInit Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- i18n.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/i18n.js b/i18n.js index 45f2d11..8014631 100644 --- a/i18n.js +++ b/i18n.js @@ -75,11 +75,12 @@ function i18nInit() { // If no saved language or not in the list of supported languages, set default to English if (!savedLang || !i18n_messages[savedLang]) { - localStorage.setItem('Language', 'en'); + savedLang = 'en'; + localStorage.setItem('Language', savedLang); } // Set the select element to the saved language - document.getElementById('languageSelect').value = localStorage.getItem('Language'); + document.getElementById('languageSelect').value = savedLang; // Apply translations i18n(); From 09e0823e5908b936d2c5788974c8297969cbe0c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=A1=E7=9A=AE=E5=B7=B4=E6=8B=89?= <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 00:38:42 +0800 Subject: [PATCH 04/14] perf: imporve translation fall back Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- i18n.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n.js b/i18n.js index 8014631..ff8696d 100644 --- a/i18n.js +++ b/i18n.js @@ -60,7 +60,7 @@ function i18n() { document.querySelectorAll('[data-i18n]').forEach(function (elem) { const key = elem.getAttribute('data-i18n'); - const translation = messages[key]; + const translation = messages[key] || (i18n_messages['en'] && i18n_messages['en'][key]); if (translation) { elem.textContent = translation; } From 4201ed05c988fdc44143075be5d5a2d35320fd17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=A1=E7=9A=AE=E5=B7=B4=E6=8B=89?= <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 00:38:59 +0800 Subject: [PATCH 05/14] fix: english translations Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- i18n.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n.js b/i18n.js index ff8696d..19a94ac 100644 --- a/i18n.js +++ b/i18n.js @@ -22,9 +22,9 @@ const i18n_messages = { "step3": "Get WLED installed and connected in less than 3 minutes!", "install": "Install", "powered1": "Powered by ", - "powered2": " ", + "powered2": "", "cors1": "CORS proxy by ", - "cors2": " " + "cors2": "" }, "zh-CN": { "maintenance1": "网络安装程序正在维护中", From 7982991d88519effa83bc5675791906b54cd573d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=A1=E7=9A=AE=E5=B7=B4=E6=8B=89?= <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 00:42:00 +0800 Subject: [PATCH 06/14] perf: add localStorage prefixed key Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- i18n.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n.js b/i18n.js index 19a94ac..2130f58 100644 --- a/i18n.js +++ b/i18n.js @@ -71,12 +71,12 @@ function i18n() { // Initialize i18n on page load function i18nInit() { // Get saved language from localStorage - let savedLang = localStorage.getItem('Language'); + let savedLang = localStorage.getItem('wled-webinstaller:language'); // If no saved language or not in the list of supported languages, set default to English if (!savedLang || !i18n_messages[savedLang]) { savedLang = 'en'; - localStorage.setItem('Language', savedLang); + localStorage.setItem('wled-webinstaller:language', savedLang); } // Set the select element to the saved language From 78158d8cd82cc7d7d470e09695ebb5d64188a028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=A1=E7=9A=AE=E5=B7=B4=E6=8B=89?= <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 00:47:02 +0800 Subject: [PATCH 07/14] perf: add localStorage prefixed key for function changeLanguage Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- i18n.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n.js b/i18n.js index 2130f58..97e6b15 100644 --- a/i18n.js +++ b/i18n.js @@ -90,6 +90,6 @@ function i18nInit() { // Event for language selection change function changeLanguage() { let selectedLang = document.getElementById('languageSelect').value; - localStorage.setItem('Language', selectedLang); + localStorage.setItem('wled-webinstaller:language', selectedLang); i18n(); } \ No newline at end of file From 3864eb0e8c4586cf886811feda88b2c16e59c82d Mon Sep 17 00:00:00 2001 From: kap1bala <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 01:01:42 +0800 Subject: [PATCH 08/14] fix: revert spaces in english translations and use arrow function in function i18n --- i18n.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/i18n.js b/i18n.js index 97e6b15..3abfb52 100644 --- a/i18n.js +++ b/i18n.js @@ -22,9 +22,9 @@ const i18n_messages = { "step3": "Get WLED installed and connected in less than 3 minutes!", "install": "Install", "powered1": "Powered by ", - "powered2": "", + "powered2": " ", "cors1": "CORS proxy by ", - "cors2": "" + "cors2": " " }, "zh-CN": { "maintenance1": "网络安装程序正在维护中", @@ -58,7 +58,7 @@ function i18n() { const lang = document.getElementById('languageSelect').value; const messages = i18n_messages[lang] || i18n_messages['en']; // Fallback to English - document.querySelectorAll('[data-i18n]').forEach(function (elem) { + document.querySelectorAll('[data-i18n]').forEach((elem) => { const key = elem.getAttribute('data-i18n'); const translation = messages[key] || (i18n_messages['en'] && i18n_messages['en'][key]); if (translation) { From c82254f1358fd11a76b499b9292a460b1009cf16 Mon Sep 17 00:00:00 2001 From: kap1bala <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 10:39:06 +0800 Subject: [PATCH 09/14] perf: i18n fallback --- i18n.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/i18n.js b/i18n.js index 3abfb52..d891c18 100644 --- a/i18n.js +++ b/i18n.js @@ -22,9 +22,9 @@ const i18n_messages = { "step3": "Get WLED installed and connected in less than 3 minutes!", "install": "Install", "powered1": "Powered by ", - "powered2": " ", + "powered2": "", "cors1": "CORS proxy by ", - "cors2": " " + "cors2": "" }, "zh-CN": { "maintenance1": "网络安装程序正在维护中", @@ -45,7 +45,7 @@ const i18n_messages = { "chip2": "CH34x(长方形芯片)", "step3": "在不到 3 分钟的时间内安装并连接 WLED!", "install": "安装", - "powered1": " ", + "powered1": "", "powered2": " 强力驱动", "cors1": "CORS 代理由 ", "cors2": " 提供支持" @@ -60,8 +60,8 @@ function i18n() { document.querySelectorAll('[data-i18n]').forEach((elem) => { const key = elem.getAttribute('data-i18n'); - const translation = messages[key] || (i18n_messages['en'] && i18n_messages['en'][key]); - if (translation) { + const translation = messages[key] || i18n_messages['en'][key]; + if (translation || translation === "") { elem.textContent = translation; } }); From 60e901c6cdd991a5d79ed86c6ca79962b1aecf23 Mon Sep 17 00:00:00 2001 From: kap1bala <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 10:41:14 +0800 Subject: [PATCH 10/14] feat: update i18n --- i18n.js | 12 ++++++++++++ index.htm | 12 ++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/i18n.js b/i18n.js index d891c18..334931a 100644 --- a/i18n.js +++ b/i18n.js @@ -20,6 +20,12 @@ const i18n_messages = { "chip1": "CP2102 (square chip)", "chip2": "CH34x (rectangular chip)", "step3": "Get WLED installed and connected in less than 3 minutes!", + "plain": "Plain", + "audioReactive": "Audioreactive", + "ethernet": "Ethernet", + "esp8266Test": "ESP8266 CPU Frequency Test", + "esp32V4": "ESP32 V4", + "debug": "DEBUG", "install": "Install", "powered1": "Powered by ", "powered2": "", @@ -44,6 +50,12 @@ const i18n_messages = { "chip1": "CP2102(正方形芯片)", "chip2": "CH34x(长方形芯片)", "step3": "在不到 3 分钟的时间内安装并连接 WLED!", + "plain": "普通版", + "audioReactive": "音频反应版", + "ethernet": "以太网版", + "esp8266Test": "ESP8266 CPU 频率测试版", + "esp32V4": "ESP32 V4 版", + "debug": "调试版", "install": "安装", "powered1": "", "powered2": " 强力驱动", diff --git a/index.htm b/index.htm index 0ef4621..61478b3 100644 --- a/index.htm +++ b/index.htm @@ -121,17 +121,17 @@

Welcome to the WLED web installer!

- + - + - + - + - + - +

From 47f5301916ec99d837f94ac74ba47662dd3ca4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=A1=E7=9A=AE=E5=B7=B4=E6=8B=89?= <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 10:43:20 +0800 Subject: [PATCH 11/14] perf: const selectedLang Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- i18n.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n.js b/i18n.js index 334931a..eea1a6a 100644 --- a/i18n.js +++ b/i18n.js @@ -101,7 +101,7 @@ function i18nInit() { // Event for language selection change function changeLanguage() { - let selectedLang = document.getElementById('languageSelect').value; + const selectedLang = document.getElementById('languageSelect').value; localStorage.setItem('wled-webinstaller:language', selectedLang); i18n(); } \ No newline at end of file From 0de8ec4aec2e67d96fcbb80b587992b57d2f04dc Mon Sep 17 00:00:00 2001 From: kap1bala <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 10:59:30 +0800 Subject: [PATCH 12/14] feat: add i18n storage key constant and update language handling --- i18n.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/i18n.js b/i18n.js index eea1a6a..552c2dc 100644 --- a/i18n.js +++ b/i18n.js @@ -1,5 +1,8 @@ // i18n.js - Internationalization for WLED Web Installer +const I18N_LANG_STORAGE_KEY = 'wled-webinstaller:language'; + + // Translation messages const i18n_messages = { "en": { @@ -68,6 +71,7 @@ const i18n_messages = { // Function to update text content based on selected language function i18n() { const lang = document.getElementById('languageSelect').value; + document.documentElement.lang = lang; // Set the lang attribute of the HTML document const messages = i18n_messages[lang] || i18n_messages['en']; // Fallback to English document.querySelectorAll('[data-i18n]').forEach((elem) => { @@ -83,12 +87,12 @@ function i18n() { // Initialize i18n on page load function i18nInit() { // Get saved language from localStorage - let savedLang = localStorage.getItem('wled-webinstaller:language'); + let savedLang = localStorage.getItem(I18N_LANG_STORAGE_KEY); // If no saved language or not in the list of supported languages, set default to English if (!savedLang || !i18n_messages[savedLang]) { savedLang = 'en'; - localStorage.setItem('wled-webinstaller:language', savedLang); + localStorage.setItem(I18N_LANG_STORAGE_KEY, savedLang); } // Set the select element to the saved language @@ -102,6 +106,6 @@ function i18nInit() { // Event for language selection change function changeLanguage() { const selectedLang = document.getElementById('languageSelect').value; - localStorage.setItem('wled-webinstaller:language', selectedLang); + localStorage.setItem(I18N_LANG_STORAGE_KEY, selectedLang); i18n(); } \ No newline at end of file From f04d553668f563d27c0ea1cb7d80140459f56084 Mon Sep 17 00:00:00 2001 From: kap1bala <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 11:12:03 +0800 Subject: [PATCH 13/14] fix: streamline translation retrieval in i18n function --- i18n.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/i18n.js b/i18n.js index 552c2dc..7f23ebb 100644 --- a/i18n.js +++ b/i18n.js @@ -76,10 +76,10 @@ function i18n() { document.querySelectorAll('[data-i18n]').forEach((elem) => { const key = elem.getAttribute('data-i18n'); - const translation = messages[key] || i18n_messages['en'][key]; - if (translation || translation === "") { - elem.textContent = translation; - } + messages[key] == undefined ? translation = i18n_messages['en'][key] : translation = messages[key]; + elem.textContent = translation; + + // console.log(`i18n: ${messages[key] || i18n_messages['en'][key]} | ${key} => ${translation}`); }); } From cef9e4503d4b7251c36e3ab5dc2f2c1d00c8cd8e Mon Sep 17 00:00:00 2001 From: kap1bala <243586394+kap1bala@users.noreply.github.com> Date: Mon, 5 Jan 2026 11:17:30 +0800 Subject: [PATCH 14/14] fix: scope --- i18n.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n.js b/i18n.js index 7f23ebb..732636c 100644 --- a/i18n.js +++ b/i18n.js @@ -72,11 +72,11 @@ const i18n_messages = { function i18n() { const lang = document.getElementById('languageSelect').value; document.documentElement.lang = lang; // Set the lang attribute of the HTML document - const messages = i18n_messages[lang] || i18n_messages['en']; // Fallback to English + const messages = i18n_messages[lang] || i18n_messages['en']; // Fallback to English if language not found document.querySelectorAll('[data-i18n]').forEach((elem) => { const key = elem.getAttribute('data-i18n'); - messages[key] == undefined ? translation = i18n_messages['en'][key] : translation = messages[key]; + const translation = messages[key] ?? i18n_messages['en'][key]; // Fallback to English if key not found elem.textContent = translation; // console.log(`i18n: ${messages[key] || i18n_messages['en'][key]} | ${key} => ${translation}`);