From bfb8e69b399f259dbbaf038925e42d8d5de6d522 Mon Sep 17 00:00:00 2001 From: L1Q Date: Mon, 12 Oct 2020 02:44:40 +0300 Subject: [PATCH] Add language override feature - refactor Messages.js - expose refreshLang for easy translations reloading - update settings version with new setting - update settings page with new option - make all pages refresh language before rendering --- package-lock.json | 161 ++--- package/_locales/en/messages.json | 12 + src/Filters.js | 2 +- src/LocaleFormat.js | 2 +- src/Messages.js | 1029 ++++++++++------------------- src/Sounds.js | 2 +- src/background/Expiration.js | 26 +- src/background/History.js | 2 +- src/background/Menu.js | 2 +- src/background/Observers.js | 51 +- src/background/Settings.js | 12 +- src/background/main.js | 20 +- src/countdown/Countdown.vue | 2 +- src/countdown/main.js | 13 +- src/expire/Expire.vue | 13 +- src/expire/main.js | 15 +- src/options/CountdownSettings.vue | 2 +- src/options/DayDistribution.vue | 2 +- src/options/Heatmap.vue | 2 +- src/options/History.vue | 2 +- src/options/LanguageSelect.vue | 17 + src/options/Settings.vue | 16 +- src/options/WeekDistribution.vue | 2 +- src/options/main.js | 22 +- src/options/router.js | 2 +- 25 files changed, 560 insertions(+), 871 deletions(-) create mode 100644 src/options/LanguageSelect.vue diff --git a/package-lock.json b/package-lock.json index 2de56884..568090a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1346,15 +1346,6 @@ "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==", "dev": true }, - "@types/mini-css-extract-plugin": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@types/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.1.tgz", - "integrity": "sha512-+mN04Oszdz9tGjUP/c1ReVwJXxSniLd7lF++sv+8dkABxVNthg6uccei+4ssKxRHGoMmPxdn7uBdJWONSJGTGQ==", - "dev": true, - "requires": { - "@types/webpack": "*" - } - }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -1805,6 +1796,17 @@ "unique-filename": "^1.1.1" } }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -1918,6 +1920,13 @@ "slash": "^2.0.0" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -1930,6 +1939,18 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "optional": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2028,6 +2049,16 @@ "strip-ansi": "^6.0.0" } }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + }, "terser-webpack-plugin": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", @@ -2045,6 +2076,18 @@ "webpack-sources": "^1.4.3" } }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.0.0-beta.8", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.8.tgz", + "integrity": "sha512-oouKUQWWHbSihqSD7mhymGPX1OQ4hedzAHyvm8RdyHh6m3oIvoRF+NM45i/bhNOlo8jCnuJhaSUf/6oDjv978g==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + } + }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -4200,9 +4243,9 @@ "dev": true }, "copy-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz", + "integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==", "dev": true, "requires": { "cacache": "^12.0.3", @@ -4215,7 +4258,7 @@ "normalize-path": "^3.0.0", "p-limit": "^2.2.1", "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.2", + "serialize-javascript": "^4.0.0", "webpack-log": "^2.0.0" }, "dependencies": { @@ -4304,12 +4347,6 @@ "ajv-keywords": "^3.1.0" } }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -9427,9 +9464,9 @@ } }, "node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", "dev": true }, "node-gyp": { @@ -11757,12 +11794,12 @@ "dev": true }, "selfsigned": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", - "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", + "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", "dev": true, "requires": { - "node-forge": "0.9.0" + "node-forge": "^0.10.0" } }, "semver": { @@ -13318,78 +13355,6 @@ } } }, - "vue-loader-v16": { - "version": "npm:vue-loader@16.0.0-beta.5", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.5.tgz", - "integrity": "sha512-ciWfzNefqWlmzKznCWY9hl+fPP4KlQ0A9MtHbJ/8DpyY+dAM8gDrjufIdxwTgC4szE4EZC3A6ip/BbrqM84GqA==", - "dev": true, - "requires": { - "@types/mini-css-extract-plugin": "^0.9.1", - "chalk": "^3.0.0", - "hash-sum": "^2.0.0", - "loader-utils": "^1.2.3", - "merge-source-map": "^1.1.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "vue-router": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.3.tgz", diff --git a/package/_locales/en/messages.json b/package/_locales/en/messages.json index 1585bebb..37fe79fd 100644 --- a/package/_locales/en/messages.json +++ b/package/_locales/en/messages.json @@ -1043,6 +1043,18 @@ "message": "White Noise", "description": "Timer sound name. Shown in the timer sound dropdown in settings." }, + "language": { + "message": "Language", + "description": "Language section header. Shown on the settings page." + }, + "override_language": { + "message": "Override language:", + "description": "Language override settings label. Shown on the settings page." + }, + "browser_default": { + "message": "Browser default", + "description": "Default option for language override settings. Shown on the settings page." + }, "settings_saved": { "message": "Settings Saved", "description": "Settings Saved notification shown on settings page when settings are saved." diff --git a/src/Filters.js b/src/Filters.js index 175aa8ed..c49a8534 100644 --- a/src/Filters.js +++ b/src/Filters.js @@ -1,4 +1,4 @@ -import M from './Messages'; +import { M } from './Messages'; import { formatter } from './LocaleFormat'; function integer(value) { diff --git a/src/LocaleFormat.js b/src/LocaleFormat.js index f2ceb346..ef3c672c 100644 --- a/src/LocaleFormat.js +++ b/src/LocaleFormat.js @@ -1,4 +1,4 @@ -import M from './Messages'; +import { M } from './Messages'; import { timeFormatLocale } from 'd3'; const monthIds = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december']; diff --git a/src/Messages.js b/src/Messages.js index 3464b3c7..bf1d4794 100644 --- a/src/Messages.js +++ b/src/Messages.js @@ -1,698 +1,335 @@ -class Messages -{ - get airplane() { - return chrome.i18n.getMessage('airplane', []); - } - get analog_alarm_clock() { - return chrome.i18n.getMessage('analog_alarm_clock', []); - } - get and() { - return chrome.i18n.getMessage('and', []); - } - get antique_clock() { - return chrome.i18n.getMessage('antique_clock', []); - } - get app_desc() { - return chrome.i18n.getMessage('app_desc', []); - } - get app_name() { - return chrome.i18n.getMessage('app_name', []); - } - get app_name_short() { - return chrome.i18n.getMessage('app_name_short', []); - } - get april() { - return chrome.i18n.getMessage('april', []); - } - get april_short() { - return chrome.i18n.getMessage('april_short', []); - } - get attributions() { - return chrome.i18n.getMessage('attributions', []); - } - get august() { - return chrome.i18n.getMessage('august', []); - } - get august_short() { - return chrome.i18n.getMessage('august_short', []); - } - get autostart_description() { - return chrome.i18n.getMessage('autostart_description', []); - } - get autostart_notification_message() { - return chrome.i18n.getMessage('autostart_notification_message', []); - } - get autostart_notification_title() { - return chrome.i18n.getMessage('autostart_notification_title', []); - } - get autostart_title() { - return chrome.i18n.getMessage('autostart_title', []); - } - average_stat(average) { - return chrome.i18n.getMessage('average_stat', [average]); - } - get battle_horn() { - return chrome.i18n.getMessage('battle_horn', []); - } - get bell_ring() { - return chrome.i18n.getMessage('bell_ring', []); - } - get bike_horn() { - return chrome.i18n.getMessage('bike_horn', []); - } - get bpm() { - return chrome.i18n.getMessage('bpm', []); - } - get brown_noise() { - return chrome.i18n.getMessage('brown_noise', []); - } - browser_action_tooltip(title, text) { - return chrome.i18n.getMessage('browser_action_tooltip', [title, text]); - } - get chrome_web_store_description() { - return chrome.i18n.getMessage('chrome_web_store_description', []); - } - get clear_history() { - return chrome.i18n.getMessage('clear_history', []); - } - get clear_history_confirmation() { - return chrome.i18n.getMessage('clear_history_confirmation', []); - } - get clear_history_description() { - return chrome.i18n.getMessage('clear_history_description', []); - } - get clock() { - return chrome.i18n.getMessage('clock', []); - } - get completed_today() { - return chrome.i18n.getMessage('completed_today', []); - } - get computer_magic() { - return chrome.i18n.getMessage('computer_magic', []); - } - get contributors() { - return chrome.i18n.getMessage('contributors', []); - } - get countdown() { - return chrome.i18n.getMessage('countdown', []); - } - get countdown_autoclose_tab() { - return chrome.i18n.getMessage('countdown_autoclose_tab', []); - } - get countdown_autoclose_window() { - return chrome.i18n.getMessage('countdown_autoclose_window', []); - } - get countdown_timer() { - return chrome.i18n.getMessage('countdown_timer', []); - } - get custom() { - return chrome.i18n.getMessage('custom', []); - } - get daily_distribution() { - return chrome.i18n.getMessage('daily_distribution', []); - } - get daily_empty_placeholder() { - return chrome.i18n.getMessage('daily_empty_placeholder', []); - } - daily_tooltip(pomodoros, start, end) { - return chrome.i18n.getMessage('daily_tooltip', [pomodoros, start, end]); - } - get date_format() { - return chrome.i18n.getMessage('date_format', []); - } - get date_time_format() { - return chrome.i18n.getMessage('date_time_format', []); - } - get december() { - return chrome.i18n.getMessage('december', []); - } - get december_short() { - return chrome.i18n.getMessage('december_short', []); - } - get decimal_separator() { - return chrome.i18n.getMessage('decimal_separator', []); - } - get desk_clock() { - return chrome.i18n.getMessage('desk_clock', []); - } - get digital_alarm_clock() { - return chrome.i18n.getMessage('digital_alarm_clock', []); - } - get digital_watch() { - return chrome.i18n.getMessage('digital_watch', []); - } - get ding() { - return chrome.i18n.getMessage('ding', []); - } - get ding_dong() { - return chrome.i18n.getMessage('ding_dong', []); - } - get disclaimer() { - return chrome.i18n.getMessage('disclaimer', []); - } - get do_not_show() { - return chrome.i18n.getMessage('do_not_show', []); - } - get dong() { - return chrome.i18n.getMessage('dong', []); - } - get duration() { - return chrome.i18n.getMessage('duration', []); - } - get duration_seconds() { - return chrome.i18n.getMessage('duration_seconds', []); - } - get electronic_chime() { - return chrome.i18n.getMessage('electronic_chime', []); - } - get end_date() { - return chrome.i18n.getMessage('end_date', []); - } - get end_iso_8601() { - return chrome.i18n.getMessage('end_iso_8601', []); - } - get end_time() { - return chrome.i18n.getMessage('end_time', []); - } - get end_timestamp() { - return chrome.i18n.getMessage('end_timestamp', []); - } - get end_timezone() { - return chrome.i18n.getMessage('end_timezone', []); - } - error_saving_settings(message) { - return chrome.i18n.getMessage('error_saving_settings', [message]); - } - get every_10th_break() { - return chrome.i18n.getMessage('every_10th_break', []); - } - get every_2nd_break() { - return chrome.i18n.getMessage('every_2nd_break', []); - } - get every_3rd_break() { - return chrome.i18n.getMessage('every_3rd_break', []); - } - get every_4th_break() { - return chrome.i18n.getMessage('every_4th_break', []); - } - get every_5th_break() { - return chrome.i18n.getMessage('every_5th_break', []); - } - get every_6th_break() { - return chrome.i18n.getMessage('every_6th_break', []); - } - get every_7th_break() { - return chrome.i18n.getMessage('every_7th_break', []); - } - get every_8th_break() { - return chrome.i18n.getMessage('every_8th_break', []); - } - get every_9th_break() { - return chrome.i18n.getMessage('every_9th_break', []); - } - get expire_title() { - return chrome.i18n.getMessage('expire_title', []); - } - get export() { - return chrome.i18n.getMessage('export', []); - } - get export_description() { - return chrome.i18n.getMessage('export_description', []); - } - get february() { - return chrome.i18n.getMessage('february', []); - } - get february_short() { - return chrome.i18n.getMessage('february_short', []); - } - get feedback() { - return chrome.i18n.getMessage('feedback', []); - } - get fire_pager() { - return chrome.i18n.getMessage('fire_pager', []); - } - get focus() { - return chrome.i18n.getMessage('focus', []); - } - get friday() { - return chrome.i18n.getMessage('friday', []); - } - get friday_short() { - return chrome.i18n.getMessage('friday_short', []); - } - get fullscreen() { - return chrome.i18n.getMessage('fullscreen', []); - } - get glass_ping() { - return chrome.i18n.getMessage('glass_ping', []); - } - get gong_1() { - return chrome.i18n.getMessage('gong_1', []); - } - get gong_2() { - return chrome.i18n.getMessage('gong_2', []); - } - group_pomodoros_hour_buckets(count) { - return chrome.i18n.getMessage('group_pomodoros_hour_buckets', [count]); - } - group_pomodoros_minute_buckets(count) { - return chrome.i18n.getMessage('group_pomodoros_minute_buckets', [count]); - } - get heatmap_date_format() { - return chrome.i18n.getMessage('heatmap_date_format', []); - } - heatmap_tooltip(pomodoros, date) { - return chrome.i18n.getMessage('heatmap_tooltip', [pomodoros, date]); - } - get height() { - return chrome.i18n.getMessage('height', []); - } - get help_translate() { - return chrome.i18n.getMessage('help_translate', []); - } - get history() { - return chrome.i18n.getMessage('history', []); - } - get history_empty_placeholder() { - return chrome.i18n.getMessage('history_empty_placeholder', []); - } - get hour_format() { - return chrome.i18n.getMessage('hour_format', []); - } - get hour_minute_format() { - return chrome.i18n.getMessage('hour_minute_format', []); - } - get hover_preview() { - return chrome.i18n.getMessage('hover_preview', []); - } - hr_suffix(count) { - return chrome.i18n.getMessage('hr_suffix', [count]); - } - get import() { - return chrome.i18n.getMessage('import', []); - } - get import_confirmation() { - return chrome.i18n.getMessage('import_confirmation', []); - } - get import_description() { - return chrome.i18n.getMessage('import_description', []); - } - import_failed(error) { - return chrome.i18n.getMessage('import_failed', [error]); - } - in_month(month) { - return chrome.i18n.getMessage('in_month', [month]); - } - get invalid_duration_data() { - return chrome.i18n.getMessage('invalid_duration_data', []); - } - get invalid_pomodoro_data() { - return chrome.i18n.getMessage('invalid_pomodoro_data', []); - } - get invalid_timezone_data() { - return chrome.i18n.getMessage('invalid_timezone_data', []); - } - get january() { - return chrome.i18n.getMessage('january', []); - } - get january_short() { - return chrome.i18n.getMessage('january_short', []); - } - get july() { - return chrome.i18n.getMessage('july', []); - } - get july_short() { - return chrome.i18n.getMessage('july_short', []); - } - get june() { - return chrome.i18n.getMessage('june', []); - } - get june_short() { - return chrome.i18n.getMessage('june_short', []); - } - get large_clock() { - return chrome.i18n.getMessage('large_clock', []); - } - last_9_months(count) { - return chrome.i18n.getMessage('last_9_months', [count]); - } - get less_than_minute() { - return chrome.i18n.getMessage('less_than_minute', []); - } - get license() { - return chrome.i18n.getMessage('license', []); - } - get long_break() { - return chrome.i18n.getMessage('long_break', []); - } - get march() { - return chrome.i18n.getMessage('march', []); - } - get march_short() { - return chrome.i18n.getMessage('march_short', []); - } - get marinara_pomodoro_assistant() { - return chrome.i18n.getMessage('marinara_pomodoro_assistant', []); - } - get may() { - return chrome.i18n.getMessage('may', []); - } - get may_short() { - return chrome.i18n.getMessage('may_short', []); - } - get metronome() { - return chrome.i18n.getMessage('metronome', []); - } - min_suffix(count) { - return chrome.i18n.getMessage('min_suffix', [count]); - } - get minutes() { - return chrome.i18n.getMessage('minutes', []); - } - get mismatched_pomodoro_duration_data() { - return chrome.i18n.getMessage('mismatched_pomodoro_duration_data', []); - } - get mismatched_pomodoro_timezone_data() { - return chrome.i18n.getMessage('mismatched_pomodoro_timezone_data', []); - } - get missing_duration_data() { - return chrome.i18n.getMessage('missing_duration_data', []); - } - get missing_pomodoro_data() { - return chrome.i18n.getMessage('missing_pomodoro_data', []); - } - get missing_timezone_data() { - return chrome.i18n.getMessage('missing_timezone_data', []); - } - get monday() { - return chrome.i18n.getMessage('monday', []); - } - get monday_short() { - return chrome.i18n.getMessage('monday_short', []); - } - get music_box() { - return chrome.i18n.getMessage('music_box', []); - } - n_minutes(count) { - return chrome.i18n.getMessage('n_minutes', [count]); - } - get never() { - return chrome.i18n.getMessage('never', []); - } - get noise() { - return chrome.i18n.getMessage('noise', []); - } - get none() { - return chrome.i18n.getMessage('none', []); - } - get november() { - return chrome.i18n.getMessage('november', []); - } - get november_short() { - return chrome.i18n.getMessage('november_short', []); - } - get october() { - return chrome.i18n.getMessage('october', []); - } - get october_short() { - return chrome.i18n.getMessage('october_short', []); - } - get pause_timer() { - return chrome.i18n.getMessage('pause_timer', []); - } - get periodic_beat() { - return chrome.i18n.getMessage('periodic_beat', []); - } - get pin_drop() { - return chrome.i18n.getMessage('pin_drop', []); - } - get pink_noise() { - return chrome.i18n.getMessage('pink_noise', []); - } - get play_audio_notification() { - return chrome.i18n.getMessage('play_audio_notification', []); - } - get pomodoro_assistant() { - return chrome.i18n.getMessage('pomodoro_assistant', []); - } - pomodoro_count_many(count) { - return chrome.i18n.getMessage('pomodoro_count_many', [count]); - } - get pomodoro_count_one() { - return chrome.i18n.getMessage('pomodoro_count_one', []); - } - get pomodoro_count_zero() { - return chrome.i18n.getMessage('pomodoro_count_zero', []); - } - get pomodoro_history() { - return chrome.i18n.getMessage('pomodoro_history', []); - } - pomodoros_completed_today(pomodoros) { - return chrome.i18n.getMessage('pomodoros_completed_today', [pomodoros]); - } - pomodoros_imported(pomodoros) { - return chrome.i18n.getMessage('pomodoros_imported', [pomodoros]); - } - pomodoros_until_long_break(pomodoros) { - return chrome.i18n.getMessage('pomodoros_until_long_break', [pomodoros]); - } - get pulse() { - return chrome.i18n.getMessage('pulse', []); - } - get reception_bell() { - return chrome.i18n.getMessage('reception_bell', []); - } - get release_notes() { - return chrome.i18n.getMessage('release_notes', []); - } - get report_an_issue() { - return chrome.i18n.getMessage('report_an_issue', []); - } - get restart_pomodoro_cycle() { - return chrome.i18n.getMessage('restart_pomodoro_cycle', []); - } - get restart_timer() { - return chrome.i18n.getMessage('restart_timer', []); - } - get resume_timer() { - return chrome.i18n.getMessage('resume_timer', []); - } - get robot_blip_1() { - return chrome.i18n.getMessage('robot_blip_1', []); - } - get robot_blip_2() { - return chrome.i18n.getMessage('robot_blip_2', []); - } - get saturday() { - return chrome.i18n.getMessage('saturday', []); - } - get saturday_short() { - return chrome.i18n.getMessage('saturday_short', []); - } - get save_as_csv() { - return chrome.i18n.getMessage('save_as_csv', []); - } - get save_as_csv_description() { - return chrome.i18n.getMessage('save_as_csv_description', []); - } - get september() { - return chrome.i18n.getMessage('september', []); - } - get september_short() { - return chrome.i18n.getMessage('september_short', []); - } - get settings() { - return chrome.i18n.getMessage('settings', []); - } - get settings_saved() { - return chrome.i18n.getMessage('settings_saved', []); - } - get ship_bell() { - return chrome.i18n.getMessage('ship_bell', []); - } - get short_break() { - return chrome.i18n.getMessage('short_break', []); - } - get show_desktop_notification() { - return chrome.i18n.getMessage('show_desktop_notification', []); - } - get show_in_tab() { - return chrome.i18n.getMessage('show_in_tab', []); - } - get show_in_window() { - return chrome.i18n.getMessage('show_in_window', []); - } - get show_new_tab_notification() { - return chrome.i18n.getMessage('show_new_tab_notification', []); - } - get small_clock() { - return chrome.i18n.getMessage('small_clock', []); - } - get source_code() { - return chrome.i18n.getMessage('source_code', []); - } - get speed_label() { - return chrome.i18n.getMessage('speed_label', []); - } - get start_break() { - return chrome.i18n.getMessage('start_break', []); - } - get start_break_now() { - return chrome.i18n.getMessage('start_break_now', []); - } - get start_focusing() { - return chrome.i18n.getMessage('start_focusing', []); - } - get start_focusing_now() { - return chrome.i18n.getMessage('start_focusing_now', []); - } - get start_long_break() { - return chrome.i18n.getMessage('start_long_break', []); - } - get start_long_break_now() { - return chrome.i18n.getMessage('start_long_break_now', []); - } - get start_pomodoro_cycle() { - return chrome.i18n.getMessage('start_pomodoro_cycle', []); - } - get start_short_break() { - return chrome.i18n.getMessage('start_short_break', []); - } - get start_short_break_now() { - return chrome.i18n.getMessage('start_short_break_now', []); - } - get stop_timer() { - return chrome.i18n.getMessage('stop_timer', []); - } - get stopwatch() { - return chrome.i18n.getMessage('stopwatch', []); - } - get sunday() { - return chrome.i18n.getMessage('sunday', []); - } - get sunday_short() { - return chrome.i18n.getMessage('sunday_short', []); - } - get take_a_break() { - return chrome.i18n.getMessage('take_a_break', []); - } - get take_a_long_break() { - return chrome.i18n.getMessage('take_a_long_break', []); - } - get take_a_long_break_setting() { - return chrome.i18n.getMessage('take_a_long_break_setting', []); - } - get take_a_short_break() { - return chrome.i18n.getMessage('take_a_short_break', []); - } - get this_month() { - return chrome.i18n.getMessage('this_month', []); - } - get this_week() { - return chrome.i18n.getMessage('this_week', []); - } - get thousands_separator() { - return chrome.i18n.getMessage('thousands_separator', []); - } - get thursday() { - return chrome.i18n.getMessage('thursday', []); - } - get thursday_short() { - return chrome.i18n.getMessage('thursday_short', []); - } - get time() { - return chrome.i18n.getMessage('time', []); - } - get time_format() { - return chrome.i18n.getMessage('time_format', []); - } - get time_period_am() { - return chrome.i18n.getMessage('time_period_am', []); - } - get time_period_pm() { - return chrome.i18n.getMessage('time_period_pm', []); - } - time_remaining(time) { - return chrome.i18n.getMessage('time_remaining', [time]); - } - get timer_paused() { - return chrome.i18n.getMessage('timer_paused', []); - } - get timer_sound_label() { - return chrome.i18n.getMessage('timer_sound_label', []); - } - get toaster_oven() { - return chrome.i18n.getMessage('toaster_oven', []); - } - get today() { - return chrome.i18n.getMessage('today', []); - } - get tone() { - return chrome.i18n.getMessage('tone', []); - } - get total() { - return chrome.i18n.getMessage('total', []); - } - get train_horn() { - return chrome.i18n.getMessage('train_horn', []); - } - get tuesday() { - return chrome.i18n.getMessage('tuesday', []); - } - get tuesday_short() { - return chrome.i18n.getMessage('tuesday_short', []); - } - get version() { - return chrome.i18n.getMessage('version', []); - } - get view() { - return chrome.i18n.getMessage('view', []); - } - get view_history() { - return chrome.i18n.getMessage('view_history', []); - } - get wall_clock() { - return chrome.i18n.getMessage('wall_clock', []); - } - get wednesday() { - return chrome.i18n.getMessage('wednesday', []); - } - get wednesday_short() { - return chrome.i18n.getMessage('wednesday_short', []); - } - get weekly_distribution() { - return chrome.i18n.getMessage('weekly_distribution', []); - } - get weekly_empty_placeholder() { - return chrome.i18n.getMessage('weekly_empty_placeholder', []); - } - weekly_tooltip(pomodoros, day) { - return chrome.i18n.getMessage('weekly_tooltip', [pomodoros, day]); - } - get when_complete() { - return chrome.i18n.getMessage('when_complete', []); - } - get white_noise() { - return chrome.i18n.getMessage('white_noise', []); - } - get width() { - return chrome.i18n.getMessage('width', []); - } - get wind_up_clock() { - return chrome.i18n.getMessage('wind_up_clock', []); - } - get wood_block() { - return chrome.i18n.getMessage('wood_block', []); - } - get wristwatch() { - return chrome.i18n.getMessage('wristwatch', []); - } - get write_a_review() { - return chrome.i18n.getMessage('write_a_review', []); - } - get your_history() { - return chrome.i18n.getMessage('your_history', []); - } +const languages = { + "ar": "Arabic", + "bn": "Bengali", + "ca": "Catalan", + "cs": "Czech", + "da": "Danish", + "de": "German", + "el": "Greek", + "en": "English", + "en_GB": "English (Great Britain)", + "es": "Spanish", + "fa": "Persian", + "fi": "Finnish", + "fr": "French", + "he": "Hebrew", + "id": "Indonesian", + "it": "Italian", + "ja": "Japanese", + "lt": "Lithuanian", + "ms": "Malay", + "nl": "Dutch", + "no": "Norwegian", + "pl": "Polish", + "pt_BR": "Portuguese (Brazil)", + "pt_PT": "Portuguese (Portugal)", + "ro": "Romanian", + "ru": "Russian", + "sr": "Serbian", + "sv": "Swedish", + "sw": "Swahili", + "te": "Telugu", + "th": "Thai", + "tr": "Turkish", + "uk": "Ukrainian", + "vi": "Vietnamese", + "zh_CN": "Chinese (China)", + "zh_TW": "Chinese (Taiwan)" + }; + +const messages_static = + ["airplane" + ,"analog_alarm_clock" + ,"and" + ,"antique_clock" + ,"app_desc" + ,"app_name" + ,"app_name_short" + ,"april" + ,"april_short" + ,"attributions" + ,"august" + ,"august_short" + ,"autostart_description" + ,"autostart_notification_message" + ,"autostart_notification_title" + ,"autostart_title" + ,"battle_horn" + ,"bell_ring" + ,"bike_horn" + ,"bpm" + ,"brown_noise" + ,"browser_default" + ,"chrome_web_store_description" + ,"clear_history" + ,"clear_history_confirmation" + ,"clear_history_description" + ,"clock" + ,"completed_today" + ,"computer_magic" + ,"contributors" + ,"countdown" + ,"countdown_autoclose_tab" + ,"countdown_autoclose_window" + ,"countdown_timer" + ,"custom" + ,"daily_distribution" + ,"daily_empty_placeholder" + ,"date_format" + ,"date_time_format" + ,"december" + ,"december_short" + ,"decimal_separator" + ,"desk_clock" + ,"digital_alarm_clock" + ,"digital_watch" + ,"ding" + ,"ding_dong" + ,"disclaimer" + ,"do_not_show" + ,"dong" + ,"duration" + ,"duration_seconds" + ,"electronic_chime" + ,"end_date" + ,"end_iso_8601" + ,"end_time" + ,"end_timestamp" + ,"end_timezone" + ,"every_10th_break" + ,"every_2nd_break" + ,"every_3rd_break" + ,"every_4th_break" + ,"every_5th_break" + ,"every_6th_break" + ,"every_7th_break" + ,"every_8th_break" + ,"every_9th_break" + ,"expire_title" + ,"export" + ,"export_description" + ,"february" + ,"february_short" + ,"feedback" + ,"fire_pager" + ,"focus" + ,"friday" + ,"friday_short" + ,"fullscreen" + ,"glass_ping" + ,"gong_1" + ,"gong_2" + ,"heatmap_date_format" + ,"height" + ,"help_translate" + ,"history" + ,"history_empty_placeholder" + ,"hour_format" + ,"hour_minute_format" + ,"hover_preview" + ,"import" + ,"import_confirmation" + ,"import_description" + ,"invalid_duration_data" + ,"invalid_pomodoro_data" + ,"invalid_timezone_data" + ,"january" + ,"january_short" + ,"july" + ,"july_short" + ,"june" + ,"june_short" + ,"language" + ,"large_clock" + ,"less_than_minute" + ,"license" + ,"long_break" + ,"march" + ,"march_short" + ,"marinara_pomodoro_assistant" + ,"may" + ,"may_short" + ,"metronome" + ,"minutes" + ,"mismatched_pomodoro_duration_data" + ,"mismatched_pomodoro_timezone_data" + ,"missing_duration_data" + ,"missing_pomodoro_data" + ,"missing_timezone_data" + ,"monday" + ,"monday_short" + ,"music_box" + ,"never" + ,"noise" + ,"none" + ,"november" + ,"november_short" + ,"october" + ,"october_short" + ,"override_language" + ,"pause_timer" + ,"periodic_beat" + ,"pin_drop" + ,"pink_noise" + ,"play_audio_notification" + ,"pomodoro_assistant" + ,"pomodoro_count_one" + ,"pomodoro_count_zero" + ,"pomodoro_history" + ,"pulse" + ,"reception_bell" + ,"release_notes" + ,"report_an_issue" + ,"restart_pomodoro_cycle" + ,"restart_timer" + ,"resume_timer" + ,"robot_blip_1" + ,"robot_blip_2" + ,"saturday" + ,"saturday_short" + ,"save_as_csv" + ,"save_as_csv_description" + ,"september" + ,"september_short" + ,"settings" + ,"settings_saved" + ,"ship_bell" + ,"short_break" + ,"show_desktop_notification" + ,"show_in_tab" + ,"show_in_window" + ,"show_new_tab_notification" + ,"small_clock" + ,"source_code" + ,"speed_label" + ,"start_break" + ,"start_break_now" + ,"start_focusing" + ,"start_focusing_now" + ,"start_long_break" + ,"start_long_break_now" + ,"start_pomodoro_cycle" + ,"start_short_break" + ,"start_short_break_now" + ,"stop_timer" + ,"stopwatch" + ,"sunday" + ,"sunday_short" + ,"take_a_break" + ,"take_a_long_break" + ,"take_a_long_break_setting" + ,"take_a_short_break" + ,"this_month" + ,"this_week" + ,"thousands_separator" + ,"thursday" + ,"thursday_short" + ,"time" + ,"time_format" + ,"time_period_am" + ,"time_period_pm" + ,"timer_paused" + ,"timer_sound_label" + ,"toaster_oven" + ,"today" + ,"tone" + ,"total" + ,"train_horn" + ,"tuesday" + ,"tuesday_short" + ,"version" + ,"view" + ,"view_history" + ,"wall_clock" + ,"wednesday" + ,"wednesday_short" + ,"weekly_distribution" + ,"weekly_empty_placeholder" + ,"when_complete" + ,"white_noise" + ,"width" + ,"wind_up_clock" + ,"wood_block" + ,"wristwatch" + ,"write_a_review" + ,"your_history" + ]; + +const messages_dynamic = + [ + ,"average_stat" // average + ,"browser_action_tooltip" // title, text + ,"daily_tooltip" // pomodoros, start, end + ,"error_saving_settings" // message + ,"group_pomodoros_hour_buckets" // count + ,"group_pomodoros_minute_buckets" // count + ,"heatmap_tooltip" // pomodoros, date + ,"hr_suffix" // count + ,"import_failed" // error + ,"in_month" // month + ,"last_9_months" // count + ,"min_suffix" // count + ,"n_minutes" // count + ,"pomodoro_count_many" // count + ,"pomodoros_completed_today" // pomodoros + ,"pomodoros_imported" // pomodoros + ,"pomodoros_until_long_break" // pomodoros + ,"time_remaining" // time + ,"weekly_tooltip" // pomodoros, day + ]; + +let latest_language_fetched = ''; +let messages_kv = {}; + +async function refreshLang(settings) { + const locale = settings.language_override; + if(!locale.length) { + latest_language_fetched = ''; + return true; + } + if(!Object.keys(languages).includes(locale)) + return false; + if(locale == latest_language_fetched) + return true; + return fetch("../_locales/"+locale+"/messages.json") + .then( response => response.json() ) + .then( json => { + messages_kv = json; + latest_language_fetched = locale; + return true; + } ) } -export default new Messages(); +function filter_apply(string_key, substitutes) { + if(!latest_language_fetched.length) + return chrome.i18n.getMessage(string_key, substitutes); + const string = messages_kv[string_key]?.message || undefined; + let replacement_index = 0; + return typeof string === 'undefined' + ? chrome.i18n.getMessage(string_key, substitutes) + : string.replace(/\$[A-z_-]+\$/g + ,() => substitutes[replacement_index++] ?? "" + ); +} + +const message_accessors_static = messages_static + .map( key => ({[key]: + {get: () => filter_apply(key) } + }) ); +const message_accessors_dynamic = messages_dynamic + .map( key => ({[key]: + {value: (...args) => filter_apply(key, args) } + }) ); + +const M = {}; +Object.defineProperties(M, + [...message_accessors_static + ,...message_accessors_dynamic + ].reduce( (carry, kv) => ({...carry,...kv}), ({}) ) +); + +export { + M, + refreshLang, + languages +}; diff --git a/src/Sounds.js b/src/Sounds.js index 4b62788a..7fe29196 100644 --- a/src/Sounds.js +++ b/src/Sounds.js @@ -1,5 +1,5 @@ import Chrome from './Chrome'; -import M from './Messages'; +import { M } from './Messages'; function createNotificationSounds() { let sounds = [ diff --git a/src/background/Expiration.js b/src/background/Expiration.js index 6ad309e4..6fc3ac70 100644 --- a/src/background/Expiration.js +++ b/src/background/Expiration.js @@ -1,5 +1,7 @@ import { SingletonPage, PageHost } from './SingletonPage'; import { Service, ServiceBroker } from '../Service'; +import { pomodoroCount } from '../Filters'; +import { M } from '../Messages'; class ExpirationService extends Service { @@ -17,17 +19,28 @@ class ExpirationService extends Service } } +function ExpirationMessages(pomodorosRemaining, pomodorosToday) { + let messages = []; + if (pomodorosRemaining > 0) { + messages.push(M.pomodoros_until_long_break(pomodoroCount(pomodorosRemaining))); + } + messages.push(M.pomodoros_completed_today(pomodoroCount(pomodorosToday))); + + return messages.filter(m => !!m); +} + + class ExpirationPage { - static async show(title, messages, action, pomodoros, phase) { + static async show(title_key, pomodorosRemaining, pomodorosToday, action_key, pomodoros, phase) { let page = await SingletonPage.show(chrome.extension.getURL('modules/expire.html'), PageHost.Tab); - return new ExpirationPage(page, title, messages, action, pomodoros, phase); + return new ExpirationPage(page, title_key, pomodorosRemaining, pomodorosToday, action_key, pomodoros, phase); } - constructor(page, title, messages, action, pomodoros, phase) { + constructor(page, title_key, pomodorosRemaining, pomodorosToday, action_key, pomodoros, phase) { this.page = page; - const properties = { title, messages, pomodoros, action, phase }; + const properties = { title_key, pomodorosRemaining, pomodorosToday, pomodoros, action_key, phase }; this.service = new ExpirationService(properties, page); ServiceBroker.register(this.service); @@ -52,5 +65,6 @@ const ExpirationClient = ExpirationService.proxy; export { ExpirationPage, - ExpirationClient -}; \ No newline at end of file + ExpirationClient, + ExpirationMessages +}; diff --git a/src/background/History.js b/src/background/History.js index 25fa05c8..b3d1cac3 100644 --- a/src/background/History.js +++ b/src/background/History.js @@ -2,7 +2,7 @@ import Chrome from '../Chrome'; import StorageManager from './StorageManager'; import RLE from './RLE'; import Mutex from '../Mutex'; -import M from '../Messages'; +import { M } from '../Messages'; import moment from 'moment'; class History diff --git a/src/background/Menu.js b/src/background/Menu.js index 4839c1d3..4f3b7a41 100644 --- a/src/background/Menu.js +++ b/src/background/Menu.js @@ -1,4 +1,4 @@ -import M from '../Messages'; +import { M } from '../Messages'; import { OptionsClient } from './Services'; class Menu diff --git a/src/background/Observers.js b/src/background/Observers.js index 5d94c1b3..f331196a 100644 --- a/src/background/Observers.js +++ b/src/background/Observers.js @@ -1,9 +1,8 @@ -import M from '../Messages'; +import { M } from '../Messages'; import { Phase } from './Timer'; -import { pomodoroCount } from '../Filters'; import * as Sounds from '../Sounds'; import Notification from './Notification'; -import { ExpirationPage } from './Expiration'; +import { ExpirationPage, ExpirationMessages } from './Expiration'; import Mutex from '../Mutex'; import createTimerSound from '../TimerSound'; import { SingletonPage, PageHost } from './SingletonPage'; @@ -161,39 +160,32 @@ class NotificationObserver }[phase]]; let hasLongBreak = this.timer.hasLongBreak; - let title = { - [Phase.Focus]: M.start_focusing, - [Phase.ShortBreak]: hasLongBreak ? M.take_a_short_break : M.take_a_break, - [Phase.LongBreak]: M.take_a_long_break + let title_key = { + [Phase.Focus]: 'start_focusing', + [Phase.ShortBreak]: hasLongBreak ? 'take_a_short_break' : 'take_a_break', + [Phase.LongBreak]: 'take_a_long_break' }[nextPhase]; - let buttonText = { - [Phase.Focus]: M.start_focusing_now, - [Phase.ShortBreak]: hasLongBreak ? M.start_short_break_now : M.start_break_now, - [Phase.LongBreak]: M.start_long_break_now + let buttonText_key = { + [Phase.Focus]: 'start_focusing_now', + [Phase.ShortBreak]: hasLongBreak ? 'start_short_break_now' : 'start_break_now', + [Phase.LongBreak]: 'start_long_break_now' }[nextPhase]; - let action = { - [Phase.Focus]: M.start_focusing, - [Phase.ShortBreak]: hasLongBreak ? M.start_short_break : M.start_break, - [Phase.LongBreak]: M.start_long_break + let action_key = { + [Phase.Focus]: 'start_focusing', + [Phase.ShortBreak]: hasLongBreak ? 'start_short_break' : 'start_break', + [Phase.LongBreak]: 'start_long_break' }[nextPhase]; - let messages = []; - let remaining = this.timer.pomodorosUntilLongBreak; - if (remaining > 0) { - messages.push(M.pomodoros_until_long_break(pomodoroCount(remaining))); - } - + let pomodorosRemaining = this.timer.pomodorosUntilLongBreak; let pomodorosToday = await this.history.countToday(); - messages.push(M.pomodoros_completed_today(pomodoroCount(pomodorosToday))); - - messages = messages.filter(m => !!m); + let messages = ExpirationMessages(pomodorosRemaining, pomodorosToday) await this.mutex.exclusive(async () => { if (settings.notifications.desktop) { - this.notification = new Notification(title, messages.join('\n'), () => this.timer.start()); - this.notification.addButton(buttonText, () => this.timer.start()); + this.notification = new Notification(M[title_key], messages.join('\n'), () => this.timer.start()); + this.notification.addButton(M[buttonText_key], () => this.timer.start()); await this.notification.show(); } @@ -205,9 +197,10 @@ class NotificationObserver }[nextPhase]; this.expiration = await ExpirationPage.show( - title, - messages, - action, + title_key, + pomodorosRemaining, + pomodorosToday, + action_key, pomodorosToday, phaseId ); diff --git a/src/background/Settings.js b/src/background/Settings.js index 05931612..636e298d 100644 --- a/src/background/Settings.js +++ b/src/background/Settings.js @@ -20,7 +20,7 @@ function clone(obj) { class SettingsSchema { get version() { - return 7; + return 8; } get default() { @@ -71,6 +71,7 @@ class SettingsSchema autostart: { time: null, }, + language_override: null, version: this.version }; } @@ -204,6 +205,15 @@ class SettingsSchema return v7; } + + from7To8(v7) { + let v8 = clone(v7); + v8.version = 8; + + v8.language_override = null; + + return v8; + } } class PersistentSettings diff --git a/src/background/main.js b/src/background/main.js index d0f34b31..effc60f4 100644 --- a/src/background/main.js +++ b/src/background/main.js @@ -1,3 +1,4 @@ +import { refreshLang } from '../Messages'; import { PomodoroTimer } from './Timer'; import Chrome from '../Chrome'; import { createPomodoroMenu } from './Menu'; @@ -22,6 +23,12 @@ async function run() { let timer = new PomodoroTimer(settings); let history = new History(); + ServiceBroker.register(new HistoryService(history)); + ServiceBroker.register(new SoundsService()); + ServiceBroker.register(new SettingsService(settingsManager)); + ServiceBroker.register(new PomodoroService(timer)); + ServiceBroker.register(new OptionsService()); + let menu = createPomodoroMenu(timer); timer.observe(new HistoryObserver(history)); timer.observe(new BadgeObserver()); @@ -31,8 +38,11 @@ async function run() { timer.observe(new CountdownObserver(settings)); timer.observe(new MenuObserver(menu)); - menu.apply(); - settingsManager.on('change', () => menu.apply()); + const menu_apply = async (settings) => refreshLang(settings) + .then( () => menu.apply() ) + + menu_apply(settings) + settingsManager.on('change', menu_apply) Alarms.install(timer, settingsManager); chrome.browserAction.onClicked.addListener(() => { @@ -44,12 +54,6 @@ async function run() { timer.start(); } }); - - ServiceBroker.register(new HistoryService(history)); - ServiceBroker.register(new SoundsService()); - ServiceBroker.register(new SettingsService(settingsManager)); - ServiceBroker.register(new PomodoroService(timer)); - ServiceBroker.register(new OptionsService()); } run(); \ No newline at end of file diff --git a/src/countdown/Countdown.vue b/src/countdown/Countdown.vue index ad005a5f..0c83ea28 100644 --- a/src/countdown/Countdown.vue +++ b/src/countdown/Countdown.vue @@ -112,7 +112,7 @@ import Sprite from '../Sprite'; import { TimerState, Phase } from '../background/Timer'; import { OptionsClient, SettingsClient, PomodoroClient } from '../background/Services'; import { mmss } from '../Filters'; -import M from '../Messages'; +import { M } from '../Messages'; export default { mixins: [TimerStats], diff --git a/src/countdown/main.js b/src/countdown/main.js index 99fed52a..4d331443 100644 --- a/src/countdown/main.js +++ b/src/countdown/main.js @@ -1,6 +1,7 @@ import Vue from 'vue'; import Countdown from './Countdown'; -import M from '../Messages'; +import { M, refreshLang } from '../Messages'; +import { SettingsClient } from '../background/Services'; Vue.config.productionTip = false; Vue.config.devtools = false; @@ -13,6 +14,10 @@ Vue.mixin({ } }); -new Vue({ - render: h => h(Countdown) -}).$mount('#app'); \ No newline at end of file +new SettingsClient().getSettings().then( settings => { + refreshLang(settings).then(() => { + new Vue({ + render: h => h(Countdown) + }).$mount('#app'); + }) +} ) diff --git a/src/expire/Expire.vue b/src/expire/Expire.vue index e8da9666..9521f7d8 100644 --- a/src/expire/Expire.vue +++ b/src/expire/Expire.vue @@ -136,9 +136,9 @@ body { diff --git a/src/options/Settings.vue b/src/options/Settings.vue index 4a41aa0b..2c91d9cf 100644 --- a/src/options/Settings.vue +++ b/src/options/Settings.vue @@ -163,6 +163,15 @@ +
+

{{ M.language }}

+

+ +

+

{{ M.autostart_title }}

{{ M.autostart_description }}

@@ -247,8 +256,9 @@ input[type="number"] { import { SettingsClient, SoundsClient } from '../background/Services'; import Mutex from '../Mutex'; import SoundSelect from './SoundSelect'; +import LanguageSelect from './LanguageSelect'; import CountdownSettings from './CountdownSettings'; -import M from '../Messages'; +import { languages } from '../Messages'; import createTimerSound from '../TimerSound'; import { focus } from '../Directives'; @@ -261,6 +271,7 @@ export default { showSettingsSaved: false, showSettingsSavedTimeout: null, notificationSounds: null, + languages: languages, timerSounds: null, timerSound: null, timerSoundMutex: new Mutex() @@ -376,7 +387,8 @@ export default { }, components: { CountdownSettings, - SoundSelect + SoundSelect, + LanguageSelect } }; \ No newline at end of file diff --git a/src/options/WeekDistribution.vue b/src/options/WeekDistribution.vue index a1a6a1c1..9eb20953 100644 --- a/src/options/WeekDistribution.vue +++ b/src/options/WeekDistribution.vue @@ -5,7 +5,7 @@