'
+ ''
+ '
Toggle the nightmode
'
@@ -1153,14 +968,14 @@ $(function () {
var language = availableLanguages[i],
langCode = (language === 'strings') ? 'us' : language.substr(language.length - 2).toLowerCase();
- $languagesList.append('
');
+ $languagesList.append('
');
}
$layoutSettings.append(''
+ '
'
+ '
'
+ ''
+ '
'
@@ -1170,6 +985,6 @@ $(function () {
$('#control-right-sidebar').after($layoutSettings);
- setup();
+ loadLayout();
});
//#endregion Right Sidebar
diff --git a/ArchiSteamFarm/www/js/i18n.js b/ArchiSteamFarm/www/js/i18n.js
new file mode 100644
index 000000000..79c98279b
--- /dev/null
+++ b/ArchiSteamFarm/www/js/i18n.js
@@ -0,0 +1,84 @@
+const defaultLocale = 'strings',
+ nameRegex = /\.\/(\S+)\.json/i;
+var availableLanguages = [],
+ tmpLanguage = get('language'),
+ myLocal = (tmpLanguage) ? tmpLanguage : getLocale(availableLanguages);
+
+function getLocale(validLocales) {
+ const language = navigator.language || navigator.userLanguage; // If the browser doesn't support this, it will not support other page elements as well
+ if (!language) return defaultLocale; // If the browser doesn't provide the language - return default locale
+ if (language.length !== 2) return validLocales.includes(language) ? language : defaultLocale; // If the language is in `xx-XX` format, check if it's valid
+ if (validLocales.includes(`${language}-${language.toUpperCase()}`)) return `${language}-${language.toUpperCase()}`; // If the language is two letter code, check if corresponding 5 letter code is a valid locale
+
+ const languageRegex = new RegExp(`${language}\-\\\S\\\S`); // Create a regex to match `xx-**` where `*` is a wildcard
+
+ for (const validLocale of validLocales) {
+ if (languageRegex.test(validLocale)) return validLocale; // Check if the locale matches the regex, if so, return it
+ }
+
+ return defaultLocale; // If no match found, return default locale
+}
+
+function loadLocales(language) {
+ var i18n = $.i18n(),
+ langCode = (language === 'strings') ? 'us' : language.substr(language.length - 2).toLowerCase(),
+ translationFile,
+ missing = 0,
+ totalSize = 0;
+
+ i18n.locale = language;
+ translationFile = '../locale/' + i18n.locale + '.json';
+ i18n.load(translationFile, i18n.locale).done(
+ function () {
+ $.getJSON(translationFile, function (obj) {
+ for (var prop in obj) {
+ if (obj.hasOwnProperty(prop)) {
+ totalSize++;
+ if (obj[prop]) {
+ if (prop.substring(0, 12) === 'placeholder-') {
+ $('[data-i18n="' + prop + '"]').attr("placeholder", $.i18n(prop));
+ } else if (prop.substring(0, 6) === 'title-') {
+ $('[data-i18n="' + prop + '"]').attr("title", $.i18n(prop));
+ } else {
+ $('[data-i18n="' + prop + '"]').i18n();
+ }
+
+ } else {
+ missing++;
+ }
+ }
+ }
+
+ store('langMissing', missing);
+ store('langTotal', totalSize);
+ });
+ }
+ );
+
+ store('language', language);
+ store('langCode', langCode);
+}
+
+function loadAllLanguages() {
+ $.ajax({
+ url: '/Api/WWW/Directory/locale',
+ type: 'GET',
+ async: false,
+ success: function (data) {
+ var obj = data['Result'];
+ const languageRegex = new RegExp("strings(.[a-z]{2}-[A-Z]{2})?.json");
+
+ availableLanguages = [];
+
+ for (var prop in obj) {
+ if (obj.hasOwnProperty(prop)) {
+ var language = obj[prop];
+ if (languageRegex.test(language))
+ availableLanguages.push(language.substr(0, language.length - 5));
+ }
+ }
+ }
+ });
+}
+
+loadLocales(myLocal);
\ No newline at end of file
diff --git a/ArchiSteamFarm/www/js/utils.js b/ArchiSteamFarm/www/js/utils.js
new file mode 100644
index 000000000..fc1cb7d33
--- /dev/null
+++ b/ArchiSteamFarm/www/js/utils.js
@@ -0,0 +1,10 @@
+if (typeof Storage === 'undefined')
+ window.alert('Please use a modern browser to properly view ASF GUI!');
+
+function get(name) {
+ return localStorage.getItem(name);
+}
+
+function store(name, val) {
+ localStorage.setItem(name, val);
+}
\ No newline at end of file
diff --git a/ArchiSteamFarm/www/locale/strings.json b/ArchiSteamFarm/www/locale/strings.json
index 396925a2b..bea002f51 100644
--- a/ArchiSteamFarm/www/locale/strings.json
+++ b/ArchiSteamFarm/www/locale/strings.json
@@ -1,20 +1,52 @@
{
+ "auth-ipc-403": "You failed to authenticate properly too many times, try again in an hour.",
+ "auth-ipc-header": "IPC password required",
+ "auth-ipc-pw-saved": "Your IPC password has been saved.",
+ "auth-ipc-pw-wrong": "Your IPC password seems to be wrong, try again!",
+ "auth-ipc-text": "Please enter the correct IPC password",
+ "auth-title": "ASF | Authentication",
+ "bots-confirm-delete": "Yes, delete bot!",
"bots-delete": "Show delete button",
+ "bots-delete-success": "<$1> and all related files have been deleted.",
+ "bots-delimeter": "Delimeter",
"bots-hide": "Hide bots",
"bots-hide-offline": "Offline bots",
"bots-hide-online": "Online bots",
+ "bots-infobox-cards": "Cards Remaining",
+ "bots-infobox-games": "Games Remaining",
+ "bots-infobox-time": "Time Remaining",
+ "bots-in-use": "Bot is currently being used.",
"bots-key": "Show key button",
+ "bots-paused": "Bot is paused.",
+ "bots-pause-success": "<$1> has been paused.",
+ "bots-recover-files": "You will not be able to recover any bot files!",
+ "bots-redeem-button": "Add keys!",
+ "bots-redeem-confirm": "$1 {{PLURAL:$1|Key|Keys}} have been added to <$2> background redeemer.",
+ "bots-redeem-title": "Enter keys!",
+ "bots-resume-success": "<$1> has been resumed.",
"bots-simple": "Simple farming info",
+ "bots-start-success": "<$1> has been started.",
+ "bots-stop-success": "<$1> has been stopped.",
+ "bots-syntax": "Syntax: gameName{Delimeter}cd-key",
"bots-title": "ASF | Bots",
- "command-auto-clear": "Auto clear",
+ "commands-auto-clear": "Auto clear",
+ "commands-response": "$1 Response received: $2",
+ "commands-sent": "$1 Command sent: $2",
"commands-title": "ASF | Commands",
+ "commands-waiting": "$1 Waiting for response...",
"editor-change": "Change bot",
"editor-current": "Currently editing:",
+ "editor-current-bot": "Currently editing:
$1",
"editor-save": "Save",
+ "editor-save-confirm": "$1 and its config file got updated.",
"editor-title": "ASF | Config Editor",
+ "editor-update": "The config will be updated and <$1> will be restarted!",
+ "editor-update-confirm": "Yes, update config!",
"generator-change": "Change mode",
"generator-current": "Current mode:",
+ "generator-current-bot": "Current mode:
$1",
"generator-download": "Download",
+ "generator-name": "You need to enter a name!",
"generator-title": "ASF | Config Generator",
"global-bots": "Bots",
"global-boxed": "Boxed Layout",
@@ -25,19 +57,46 @@
"global-config": "Config",
"global-control-panel": "Control Panel",
"global-editor": "Editor",
+ "global-error-invalid-pw": "You need to enter a valid password!",
+ "global-error-title": "Error!",
"global-generator": "Generator",
"global-home": "Home",
"global-information": "Information",
"global-language": "Language",
+ "global-language-info": "$1% of this language is not translated! Help us
here.",
"global-layout": "Layout",
"global-log": "Log",
"global-navigation": "Toggle navigation",
"global-nightmode": "Nightmode",
"global-nightmode-description": "Toggle the nightmode",
+ "global-question-title": "Are you sure?",
"global-ram-usage": "RAM Usage",
"global-skins": "Skins",
+ "global-success-title": "Success!",
"global-uptime": "Uptime",
"global-version": "Version",
"global-wiki": "Wiki",
- "log-title": "ASF | Log"
-}
+ "log-event-code": "Event code: $1",
+ "log-title": "ASF | Log",
+ "placeholder-auth": "Type your password...",
+ "placeholder-commands": "Type command...",
+ "placeholder-generator": "Name",
+ "title-bots-delete": "Toggle delete button",
+ "title-bots-delete-this": "Delete this bot",
+ "title-bots-games": "Add keys to GamesToRedeemInBackground",
+ "title-bots-key": "Toggle key button",
+ "title-bots-more": "Show more infos",
+ "title-bots-offline": "Toggle offline bots",
+ "title-bots-online": "Toggle online bots",
+ "title-bots-refresh": "Refresh content",
+ "title-bots-simple": "Toggle simple farming info",
+ "title-commands-auto-clear": "Toggle auto clear",
+ "title-commands-send": "Send command",
+ "title-commands-show-all-bots": "Show all bots",
+ "title-commands-show-all-commands": "Show all commands",
+ "title-global-boxed": "Toggle boxed layout",
+ "title-global-language": "Change language",
+ "title-global-never": "Never show again",
+ "title-global-nightmode": "Toggle nightmode",
+ "title-log-auto-scroll": "Toggle auto scroll"
+}
\ No newline at end of file
diff --git a/ArchiSteamFarm/www/pages/bots.html b/ArchiSteamFarm/www/pages/bots.html
index ebe82dd6a..6a5835309 100644
--- a/ArchiSteamFarm/www/pages/bots.html
+++ b/ArchiSteamFarm/www/pages/bots.html
@@ -6,13 +6,12 @@
-
-
+
+
-
@@ -54,8 +53,8 @@
Bots
0
- 0
- 0
+ 0
+ 0
@@ -111,30 +110,23 @@
Hide bots
-
-
-