diff --git a/ayanova/devdocs/todo.txt b/ayanova/devdocs/todo.txt index 055a9894..4374b12f 100644 --- a/ayanova/devdocs/todo.txt +++ b/ayanova/devdocs/todo.txt @@ -48,12 +48,29 @@ CURRENT TODOs SHELL / NAV / MENUS / LAYOUT TODO: LOCALIZATION + - NEED to accept and display numbers and dates and times, nothing else really matters + - NUMBER FORMATTING REQUIRED INFO + - USEROPTIONS: Currency symbol + - USEROPTIONS: digit grouping symbol (thousands separator) + - USEROPTIONS: decimal symbol + - DATE TIME FORMATTING REQUIRED INFO + - LOCALETEXT: Month names in full + - Month abbreviations 3 characters maybe can just use first 3 of names above + - LOCALETEXT: Day of week + - First letter of day of week and first three letters of day of week are used in date input + - LOCALETEXT: AM / PM symbols + - USEROPTIONS: Short date template + - USEROPTIONS: Short time template + + + - All major browsers support Intl api now: + - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl - IDENTIFY: what needs to be localized besides display titles? - Currency input, display - decimal number input, display - Date and times MONTH names in input (and some ancillary text maybe like "year") - Date and time display - + - INPUT currency / decimal can a german user input a currency as 1.234,56 ? (comma is the decimal separator and decimal is the thousands separator) - vuetify currency field: https://gist.github.com/Christilut/1143d453ea070f7e8fa345f7ada1b999 - Not vuetify specifically but may have stealable code: https://dm4t2.github.io/vue-currency-input/ diff --git a/ayanova/src/api/initialize.js b/ayanova/src/api/initialize.js index d3805863..9561f67a 100644 --- a/ayanova/src/api/initialize.js +++ b/ayanova/src/api/initialize.js @@ -785,7 +785,8 @@ export default function initialize() { shortDate: "YYYY-MM-DD", shortTime: "hh:mm:ss A", shortDateAndTime: "YYYY-MM-DD hh:mm:ss A", - timeZoneOffset: res.data.timeZoneOffset + timeZoneOffset: res.data.timeZoneOffset, + tag: res.data.tag || "en-US" }); resolve(); diff --git a/ayanova/src/api/locale.js b/ayanova/src/api/locale.js index 33873565..d546ed39 100644 --- a/ayanova/src/api/locale.js +++ b/ayanova/src/api/locale.js @@ -190,5 +190,55 @@ export default { ret = ret.replace(foundMatch, newValue); } return ret; + }, + //////////////////////////////////////////////////////// + // attempt to determine user's preferred first browser language setting + // https://stackoverflow.com/a/46514247/8939 + // + // + getFirstBrowserLanguage() { + var nav = window.navigator, + browserLanguagePropertyKeys = [ + "language", + "browserLanguage", + "systemLanguage", + "userLanguage" + ], + i, + language, + len, + shortLanguage = null; + + // support for HTML 5.1 "navigator.languages" + if (Array.isArray(nav.languages)) { + for (i = 0; i < nav.languages.length; i++) { + language = nav.languages[i]; + len = language.length; + if (!shortLanguage && len) { + shortLanguage = language; + } + if (language && len > 2) { + return language; + } + } + } + + // support for other well known properties in browsers + for (i = 0; i < browserLanguagePropertyKeys.length; i++) { + language = nav[browserLanguagePropertyKeys[i]]; + //skip this loop iteration if property is null/undefined. IE11 fix. + if (language == null) { + continue; + } + len = language.length; + if (!shortLanguage && len) { + shortLanguage = language; + } + if (language && len > 2) { + return language; + } + } + + return shortLanguage; } }; diff --git a/ayanova/src/store.js b/ayanova/src/store.js index d8f681ce..982c4d4d 100644 --- a/ayanova/src/store.js +++ b/ayanova/src/store.js @@ -21,6 +21,7 @@ export default new Vuex.Store({ homePage: undefined, localeText: {}, locale: { + tag: "en-US", decimalSeparator: ".", currencySymbol: "$", shortDate: "YYYY-MM-DD", @@ -56,6 +57,7 @@ export default new Vuex.Store({ state.localeText = {}; state.formCustomTemplate = {}; state.apiUrl = ""; + state.locale.tag = "en-US"; state.locale.decimalSeparator = "."; state.locale.currencySymbol = "$"; state.locale.shortDate = "YYYY-MM-DD"; @@ -82,6 +84,7 @@ export default new Vuex.Store({ state.locale.shortTime = data.shortTime; state.locale.shortDateAndTime = data.shortDateAndTime; state.locale.timeZoneOffset = data.timeZoneOffset; + state.locale.tag = data.tag; }, setAPIURL(state, data) { state.apiUrl = data; diff --git a/ayanova/src/views/ay-about.vue b/ayanova/src/views/ay-about.vue index 1dd24c0b..e8fb5524 100644 --- a/ayanova/src/views/ay-about.vue +++ b/ayanova/src/views/ay-about.vue @@ -24,6 +24,13 @@ {{ this.$store.state.userName }} +
+ {{ lt("Language") }}: + + {{ ltFormat().tag }} + +
+
{{ lt("UserTimeZoneOffset") }}: diff --git a/ayanova/src/views/home-user-settings.vue b/ayanova/src/views/home-user-settings.vue index 7cf82140..b8f1aee3 100644 --- a/ayanova/src/views/home-user-settings.vue +++ b/ayanova/src/views/home-user-settings.vue @@ -1,14 +1,20 @@