diff --git a/src/MobileApp.vue b/src/MobileApp.vue index a153b41d..7a3338fb 100644 --- a/src/MobileApp.vue +++ b/src/MobileApp.vue @@ -10,6 +10,8 @@ import { f7ready } from 'framework7-vue'; import routes from './router/mobile.js'; import { mapStores } from 'pinia'; +import { useSettingsStore } from '@/stores/setting.js'; +import { useUserStore } from '@/stores/user.js'; import { useTokensStore } from '@/stores/token.js'; import { useExchangeRatesStore } from '@/stores/exchangeRates.js'; @@ -89,17 +91,21 @@ export default { } }, computed: { - ...mapStores(useTokensStore, useExchangeRatesStore), + ...mapStores(useSettingsStore, useUserStore, useTokensStore, useExchangeRatesStore), }, created() { const self = this; + let localeDefaultSettings = self.$locale.initLocale(self.userStore.currentUserLanguage); + self.settingsStore.updateLocalizedDefaultSettings(localeDefaultSettings); + if (self.$user.isUserLogined()) { if (!self.$settings.isEnableApplicationLock()) { // refresh token if user is logined self.tokensStore.refreshTokenAndRevokeOldToken().then(response => { if (response.user && response.user.language) { - self.$locale.setLanguage(response.user.language); + localeDefaultSettings = self.$locale.setLanguage(response.user.language); + self.settingsStore.updateLocalizedDefaultSettings(localeDefaultSettings); } }); diff --git a/src/lib/i18n.js b/src/lib/i18n.js index e320f745..ea605369 100644 --- a/src/lib/i18n.js +++ b/src/lib/i18n.js @@ -1,23 +1,32 @@ +import moment from 'moment-timezone'; + import { defaultLanguage, allLanguages } from '@/locales/index.js'; import datetime from '@/consts/datetime.js'; import timezone from '@/consts/timezone.js'; import currency from '@/consts/currency.js'; -import settings from './settings.js'; + import { isString, isNumber } from './common.js'; + import { + formatUnixTime, formatTime, getCurrentDateTime, getTimezoneOffset, getTimezoneOffsetMinutes, getDateTimeFormatType } from './datetime.js'; + import { numericCurrencyToString } from './currency.js'; +import logger from './logger.js'; +import settings from './settings.js'; +import services from './services.js'; + const apiNotFoundErrorCode = 100001; const specifiedApiNotFoundErrors = { '/api/register.json': { @@ -139,15 +148,15 @@ const parameterizedErrors = [ } ]; -export function getAllLanguageInfos() { +function getAllLanguageInfos() { return allLanguages; } -export function getLanguageInfo(locale) { +function getLanguageInfo(locale) { return allLanguages[locale]; } -export function getDefaultLanguage() { +function getDefaultLanguage() { if (!window || !window.navigator) { return defaultLanguage; } @@ -195,15 +204,44 @@ export function getDefaultLanguage() { return browserLocale; } -export function transateIf(text, isTranslate, translateFn) { - if (isTranslate) { - return translateFn(text); +function getLocaleFromLanguageAlias(alias) { + for (let locale in allLanguages) { + if (!Object.prototype.hasOwnProperty.call(allLanguages, locale)) { + continue; + } + + if (locale.toLowerCase() === alias.toLowerCase()) { + return locale; + } + + const lang = allLanguages[locale]; + const aliases = lang.aliases; + + if (!aliases || aliases.length < 1) { + continue; + } + + for (let i = 0; i < aliases.length; i++) { + if (aliases[i].toLowerCase() === alias.toLowerCase()) { + return locale; + } + } } - return text; + return null; } -export function getAllLongMonthNames(translateFn) { +function getCurrentLanguageInfo(i18nGlobal) { + const locale = getLanguageInfo(i18nGlobal.locale); + + if (locale) { + return locale; + } + + return getDefaultLanguage(); +} + +function getAllLongMonthNames(translateFn) { return [ translateFn('datetime.January.long'), translateFn('datetime.February.long'), @@ -220,7 +258,7 @@ export function getAllLongMonthNames(translateFn) { ]; } -export function getAllShortMonthNames(translateFn) { +function getAllShortMonthNames(translateFn) { return [ translateFn('datetime.January.short'), translateFn('datetime.February.short'), @@ -237,7 +275,7 @@ export function getAllShortMonthNames(translateFn) { ]; } -export function getAllLongWeekdayNames(translateFn) { +function getAllLongWeekdayNames(translateFn) { return [ translateFn('datetime.Sunday.long'), translateFn('datetime.Monday.long'), @@ -249,7 +287,7 @@ export function getAllLongWeekdayNames(translateFn) { ]; } -export function getAllShortWeekdayNames(translateFn) { +function getAllShortWeekdayNames(translateFn) { return [ translateFn('datetime.Sunday.short'), translateFn('datetime.Monday.short'), @@ -261,7 +299,7 @@ export function getAllShortWeekdayNames(translateFn) { ]; } -export function getAllMinWeekdayNames(translateFn) { +function getAllMinWeekdayNames(translateFn) { return [ translateFn('datetime.Sunday.min'), translateFn('datetime.Monday.min'), @@ -273,89 +311,120 @@ export function getAllMinWeekdayNames(translateFn) { ]; } -export function getAllLongDateFormats(translateFn) { +function getAllLongDateFormats(translateFn) { const defaultLongDateFormatTypeName = translateFn('default.longDateFormat'); return getDateTimeFormats(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longDate', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat); } -export function getAllShortDateFormats(translateFn) { +function getAllShortDateFormats(translateFn) { const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat'); return getDateTimeFormats(translateFn, datetime.allShortDateFormat, datetime.allShortDateFormatArray, 'format.shortDate', defaultShortDateFormatTypeName, datetime.defaultShortDateFormat); } -export function getAllLongTimeFormats(translateFn) { +function getAllLongTimeFormats(translateFn) { const defaultLongTimeFormatTypeName = translateFn('default.longTimeFormat'); return getDateTimeFormats(translateFn, datetime.allLongTimeFormat, datetime.allLongTimeFormatArray, 'format.longTime', defaultLongTimeFormatTypeName, datetime.defaultLongTimeFormat); } -export function getAllShortTimeFormats(translateFn) { +function getAllShortTimeFormats(translateFn) { const defaultShortTimeFormatTypeName = translateFn('default.shortTimeFormat'); return getDateTimeFormats(translateFn, datetime.allShortTimeFormat, datetime.allShortTimeFormatArray, 'format.shortTime', defaultShortTimeFormatTypeName, datetime.defaultShortTimeFormat); } -export function getI18nLongDateFormat(translateFn, formatTypeValue) { +function getI18nLongDateFormat(translateFn, formatTypeValue) { const defaultLongDateFormatTypeName = translateFn('default.longDateFormat'); return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longDate', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue); } -export function getI18nShortDateFormat(translateFn, formatTypeValue) { +function getI18nShortDateFormat(translateFn, formatTypeValue) { const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat'); return getDateTimeFormat(translateFn, datetime.allShortDateFormat, datetime.allShortDateFormatArray, 'format.shortDate', defaultShortDateFormatTypeName, datetime.defaultShortDateFormat, formatTypeValue); } -export function getI18nLongYearFormat(translateFn, formatTypeValue) { +function getI18nLongYearFormat(translateFn, formatTypeValue) { const defaultLongDateFormatTypeName = translateFn('default.longDateFormat'); return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longYear', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue); } -export function getI18nShortYearFormat(translateFn, formatTypeValue) { +function getI18nShortYearFormat(translateFn, formatTypeValue) { const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat'); return getDateTimeFormat(translateFn, datetime.allShortDateFormat, datetime.allShortDateFormatArray, 'format.shortYear', defaultShortDateFormatTypeName, datetime.defaultShortDateFormat, formatTypeValue); } -export function getI18nLongYearMonthFormat(translateFn, formatTypeValue) { +function getI18nLongYearMonthFormat(translateFn, formatTypeValue) { const defaultLongDateFormatTypeName = translateFn('default.longDateFormat'); return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longYearMonth', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue); } -export function getI18nShortYearMonthFormat(translateFn, formatTypeValue) { +function getI18nShortYearMonthFormat(translateFn, formatTypeValue) { const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat'); return getDateTimeFormat(translateFn, datetime.allShortDateFormat, datetime.allShortDateFormatArray, 'format.shortYearMonth', defaultShortDateFormatTypeName, datetime.defaultShortDateFormat, formatTypeValue); } -export function getI18nLongMonthDayFormat(translateFn, formatTypeValue) { +function getI18nLongMonthDayFormat(translateFn, formatTypeValue) { const defaultLongDateFormatTypeName = translateFn('default.longDateFormat'); return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longMonthDay', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue); } -export function getI18nShortMonthDayFormat(translateFn, formatTypeValue) { +function getI18nShortMonthDayFormat(translateFn, formatTypeValue) { const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat'); return getDateTimeFormat(translateFn, datetime.allShortDateFormat, datetime.allShortDateFormatArray, 'format.shortMonthDay', defaultShortDateFormatTypeName, datetime.defaultShortDateFormat, formatTypeValue); } -export function getI18nLongTimeFormat(translateFn, formatTypeValue) { +function getI18nLongTimeFormat(translateFn, formatTypeValue) { const defaultLongTimeFormatTypeName = translateFn('default.longTimeFormat'); return getDateTimeFormat(translateFn, datetime.allLongTimeFormat, datetime.allLongTimeFormatArray, 'format.longTime', defaultLongTimeFormatTypeName, datetime.defaultLongTimeFormat, formatTypeValue); } -export function getI18nShortTimeFormat(translateFn, formatTypeValue) { +function getI18nShortTimeFormat(translateFn, formatTypeValue) { const defaultShortTimeFormatTypeName = translateFn('default.shortTimeFormat'); return getDateTimeFormat(translateFn, datetime.allShortTimeFormat, datetime.allShortTimeFormatArray, 'format.shortTime', defaultShortTimeFormatTypeName, datetime.defaultShortTimeFormat, formatTypeValue); } -export function isLongTime24HourFormat(translateFn, formatTypeValue) { +function isLongTime24HourFormat(translateFn, formatTypeValue) { const defaultLongTimeFormatTypeName = translateFn('default.longTimeFormat'); const type = getDateTimeFormatType(datetime.allLongTimeFormat, datetime.allLongTimeFormatArray, defaultLongTimeFormatTypeName, datetime.defaultLongTimeFormat, formatTypeValue); return type.is24HourFormat; } -export function isShortTime24HourFormat(translateFn, formatTypeValue) { +function isShortTime24HourFormat(translateFn, formatTypeValue) { const defaultShortTimeFormatTypeName = translateFn('default.shortTimeFormat'); const type = getDateTimeFormatType(datetime.allShortTimeFormat, datetime.allShortTimeFormatArray, defaultShortTimeFormatTypeName, datetime.defaultShortTimeFormat, formatTypeValue); return type.is24HourFormat; } -export function getAllTimezones(includeSystemDefault, translateFn) { +function getDateTimeFormats(translateFn, allFormatMap, allFormatArray, localeFormatPathPrefix, localeDefaultFormatTypeName, systemDefaultFormatType) { + const defaultFormat = getDateTimeFormat(translateFn, allFormatMap, allFormatArray, + localeFormatPathPrefix, localeDefaultFormatTypeName, systemDefaultFormatType, datetime.defaultDateTimeFormatValue); + const ret = []; + + ret.push({ + type: datetime.defaultDateTimeFormatValue, + format: defaultFormat, + displayName: `${translateFn('Language Default')} (${formatTime(getCurrentDateTime(), defaultFormat)})` + }); + + for (let i = 0; i < allFormatArray.length; i++) { + const formatType = allFormatArray[i]; + const format = translateFn(`${localeFormatPathPrefix}.${formatType.key}`); + + ret.push({ + type: formatType.type, + format: format, + displayName: formatTime(getCurrentDateTime(), format) + }); + } + + return ret; +} + +function getDateTimeFormat(translateFn, allFormatMap, allFormatArray, localeFormatPathPrefix, localeDefaultFormatTypeName, systemDefaultFormatType, formatTypeValue) { + const type = getDateTimeFormatType(allFormatMap, allFormatArray, + localeDefaultFormatTypeName, systemDefaultFormatType, formatTypeValue); + return translateFn(`${localeFormatPathPrefix}.${type.key}`); +} + +function getAllTimezones(includeSystemDefault, translateFn) { const defaultTimezoneOffset = getTimezoneOffset(); const defaultTimezoneOffsetMinutes = getTimezoneOffsetMinutes(); const allTimezones = timezone.all; @@ -393,7 +462,7 @@ export function getAllTimezones(includeSystemDefault, translateFn) { return allTimezoneInfos; } -export function getAllCurrencies(translateFn) { +function getAllCurrencies(translateFn) { const allCurrencyCodes = currency.all; const allCurrencies = []; @@ -415,7 +484,7 @@ export function getAllCurrencies(translateFn) { return allCurrencies; } -export function getDisplayCurrency(value, currencyCode, notConvertValue, translateFn) { +function getDisplayCurrency(value, currencyCode, notConvertValue, translateFn) { if (!isNumber(value) && !isString(value)) { return value; } @@ -464,6 +533,86 @@ export function getDisplayCurrency(value, currencyCode, notConvertValue, transla } } +function setLanguage(i18nGlobal, locale, force) { + if (!locale) { + locale = getDefaultLanguage(); + logger.info(`No specified language, use browser default language ${locale}`); + } + + if (!getLanguageInfo(locale)) { + locale = getDefaultLanguage(); + logger.warn(`Not found language ${locale}, use browser default language ${locale}`); + } + + if (!force && i18nGlobal.locale === locale) { + logger.info(`Current locale is already ${locale}`); + return null; + } + + logger.info(`Apply current language to ${locale}`); + + i18nGlobal.locale = locale; + moment.updateLocale(locale, { + months : getAllLongMonthNames(i18nGlobal.t), + monthsShort : getAllShortMonthNames(i18nGlobal.t), + weekdays : getAllLongWeekdayNames(i18nGlobal.t), + weekdaysShort : getAllShortWeekdayNames(i18nGlobal.t), + weekdaysMin : getAllMinWeekdayNames(i18nGlobal.t), + meridiem: function (hours) { + if (hours > 11) { + return i18nGlobal.t('datetime.PM.upperCase'); + } else { + return i18nGlobal.t('datetime.AM.upperCase'); + } + } + }); + services.setLocale(locale); + document.querySelector('html').setAttribute('lang', locale); + + const defaultCurrency = i18nGlobal.t('default.currency'); + const defaultFirstDayOfWeekName = i18nGlobal.t('default.firstDayOfWeek'); + let defaultFirstDayOfWeek = datetime.defaultFirstDayOfWeek; + + if (datetime.allWeekDays[defaultFirstDayOfWeekName]) { + defaultFirstDayOfWeek = datetime.allWeekDays[defaultFirstDayOfWeekName].type; + } + + return { + defaultCurrency: defaultCurrency, + defaultFirstDayOfWeek: defaultFirstDayOfWeek + }; +} + +function setTimezone(timezone) { + if (timezone) { + settings.setTimezone(timezone); + moment.tz.setDefault(timezone); + } else { + settings.setTimezone(''); + moment.tz.setDefault(); + } +} + +function initLocale(i18nGlobal, lastUserLanguage) { + let localeDefaultSettings = null; + + if (lastUserLanguage && getLanguageInfo(lastUserLanguage)) { + logger.info(`Last user language is ${lastUserLanguage}`); + localeDefaultSettings = setLanguage(i18nGlobal, lastUserLanguage, true); + } else { + localeDefaultSettings = setLanguage(i18nGlobal, null, true); + } + + if (settings.getTimezone()) { + logger.info(`Current timezone is ${settings.getTimezone()}`); + setTimezone(settings.getTimezone()); + } else { + logger.info(`No timezone is set, use browser default ${getTimezoneOffset()} (maybe ${moment.tz.guess(true)})`); + } + + return localeDefaultSettings; +} + export function getI18nOptions() { return { legacy: true, @@ -487,6 +636,14 @@ export function getI18nOptions() { }; } +export function transateIf(text, isTranslate, translateFn) { + if (isTranslate) { + return translateFn(text); + } + + return text; +} + export function getLocalizedError(error) { if (error.errorCode === apiNotFoundErrorCode && specifiedApiNotFoundErrors[error.path]) { return { @@ -541,60 +698,43 @@ export function getLocalizedErrorParameters(parameters, i18nFunc) { return localizedParameters; } -function getLocaleFromLanguageAlias(alias) { - for (let locale in allLanguages) { - if (!Object.prototype.hasOwnProperty.call(allLanguages, locale)) { - continue; - } - - if (locale.toLowerCase() === alias.toLowerCase()) { - return locale; - } - - const lang = allLanguages[locale]; - const aliases = lang.aliases; - - if (!aliases || aliases.length < 1) { - continue; - } - - for (let i = 0; i < aliases.length; i++) { - if (aliases[i].toLowerCase() === alias.toLowerCase()) { - return locale; - } - } - } - - return null; -} - -function getDateTimeFormats(translateFn, allFormatMap, allFormatArray, localeFormatPathPrefix, localeDefaultFormatTypeName, systemDefaultFormatType) { - const defaultFormat = getDateTimeFormat(translateFn, allFormatMap, allFormatArray, - localeFormatPathPrefix, localeDefaultFormatTypeName, systemDefaultFormatType, datetime.defaultDateTimeFormatValue); - const ret = []; - - ret.push({ - type: datetime.defaultDateTimeFormatValue, - format: defaultFormat, - displayName: `${translateFn('Language Default')} (${formatTime(getCurrentDateTime(), defaultFormat)})` - }); - - for (let i = 0; i < allFormatArray.length; i++) { - const formatType = allFormatArray[i]; - const format = translateFn(`${localeFormatPathPrefix}.${formatType.key}`); - - ret.push({ - type: formatType.type, - format: format, - displayName: formatTime(getCurrentDateTime(), format) - }); - } - - return ret; -} - -function getDateTimeFormat(translateFn, allFormatMap, allFormatArray, localeFormatPathPrefix, localeDefaultFormatTypeName, systemDefaultFormatType, formatTypeValue) { - const type = getDateTimeFormatType(allFormatMap, allFormatArray, - localeDefaultFormatTypeName, systemDefaultFormatType, formatTypeValue); - return translateFn(`${localeFormatPathPrefix}.${type.key}`); +export function i18nFunctions(i18nGlobal) { + return { + getAllLanguageInfos: getAllLanguageInfos, + getLanguageInfo: getLanguageInfo, + getDefaultLanguage: getDefaultLanguage, + getCurrentLanguageInfo: () => getCurrentLanguageInfo(i18nGlobal), + getAllLongMonthNames: () => getAllLongMonthNames(i18nGlobal.t), + getAllShortMonthNames: () => getAllShortMonthNames(i18nGlobal.t), + getAllLongWeekdayNames: () => getAllLongWeekdayNames(i18nGlobal.t), + getAllShortWeekdayNames: () => getAllShortWeekdayNames(i18nGlobal.t), + getAllMinWeekdayNames: () => getAllMinWeekdayNames(i18nGlobal.t), + getAllLongDateFormats: () => getAllLongDateFormats(i18nGlobal.t), + getAllShortDateFormats: () => getAllShortDateFormats(i18nGlobal.t), + getAllLongTimeFormats: () => getAllLongTimeFormats(i18nGlobal.t), + getAllShortTimeFormats: () => getAllShortTimeFormats(i18nGlobal.t), + formatUnixTimeToLongDateTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongDateFormat(i18nGlobal.t, userStore.currentUserLongDateFormat) + ' ' + getI18nLongTimeFormat(i18nGlobal.t, userStore.currentUserLongTimeFormat), utcOffset, currentUtcOffset), + formatUnixTimeToShortDateTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortDateFormat(i18nGlobal.t, userStore.currentUserShortDateFormat) + ' ' + getI18nShortTimeFormat(i18nGlobal.t, userStore.currentUserShortTimeFormat), utcOffset, currentUtcOffset), + formatUnixTimeToLongDate: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongDateFormat(i18nGlobal.t, userStore.currentUserLongDateFormat), utcOffset, currentUtcOffset), + formatUnixTimeToShortDate: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortDateFormat(i18nGlobal.t, userStore.currentUserShortDateFormat), utcOffset, currentUtcOffset), + formatUnixTimeToLongYear: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongYearFormat(i18nGlobal.t, userStore.currentUserLongDateFormat), utcOffset, currentUtcOffset), + formatUnixTimeToShortYear: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortYearFormat(i18nGlobal.t, userStore.currentUserShortDateFormat), utcOffset, currentUtcOffset), + formatUnixTimeToLongYearMonth: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongYearMonthFormat(i18nGlobal.t, userStore.currentUserLongDateFormat), utcOffset, currentUtcOffset), + formatUnixTimeToShortYearMonth: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortYearMonthFormat(i18nGlobal.t, userStore.currentUserShortDateFormat), utcOffset, currentUtcOffset), + formatUnixTimeToLongMonthDay: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongMonthDayFormat(i18nGlobal.t, userStore.currentUserLongDateFormat), utcOffset, currentUtcOffset), + formatUnixTimeToShortMonthDay: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortMonthDayFormat(i18nGlobal.t, userStore.currentUserShortDateFormat), utcOffset, currentUtcOffset), + formatUnixTimeToLongTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongTimeFormat(i18nGlobal.t, userStore.currentUserLongTimeFormat), utcOffset, currentUtcOffset), + formatUnixTimeToShortTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortTimeFormat(i18nGlobal.t, userStore.currentUserShortTimeFormat), utcOffset, currentUtcOffset), + formatTimeToLongYearMonth: (userStore, dateTime) => formatTime(dateTime, getI18nLongYearMonthFormat(i18nGlobal.t, userStore.currentUserLongDateFormat)), + formatTimeToShortYearMonth: (userStore, dateTime) => formatTime(dateTime, getI18nShortYearMonthFormat(i18nGlobal.t, userStore.currentUserShortDateFormat)), + isLongTime24HourFormat: (userStore) => isLongTime24HourFormat(i18nGlobal.t, userStore.currentUserLongTimeFormat), + isShortTime24HourFormat: (userStore) => isShortTime24HourFormat(i18nGlobal.t, userStore.currentUserShortTimeFormat), + getAllTimezones: (includeSystemDefault) => getAllTimezones(includeSystemDefault, i18nGlobal.t), + getAllCurrencies: () => getAllCurrencies(i18nGlobal.t), + getDisplayCurrency: (value, currencyCode, notConvertValue) => getDisplayCurrency(value, currencyCode, notConvertValue, i18nGlobal.t), + setLanguage: (locale, force) => setLanguage(i18nGlobal, locale, force), + getTimezone: settings.getTimezone, + setTimezone: setTimezone, + initLocale: (lastUserLanguage) => initLocale(i18nGlobal, lastUserLanguage) + }; } diff --git a/src/mobile-main.js b/src/mobile-main.js index 3ec942ff..b0981793 100644 --- a/src/mobile-main.js +++ b/src/mobile-main.js @@ -2,8 +2,6 @@ import { createApp } from 'vue'; import { createPinia } from 'pinia'; import { createI18n } from 'vue-i18n'; -import moment from 'moment-timezone'; - import Framework7 from 'framework7/lite'; import Framework7Dialog from 'framework7/components/dialog'; import Framework7Popup from 'framework7/components/popup'; @@ -75,48 +73,13 @@ import 'line-awesome/dist/line-awesome/css/line-awesome.css'; import VueDatePicker from '@vuepic/vue-datepicker'; import '@vuepic/vue-datepicker/dist/main.css'; -import datetimeConstants from '@/consts/datetime.js'; - import version from '@/lib/version.js'; -import logger from '@/lib/logger.js'; import settings from '@/lib/settings.js'; -import services from '@/lib/services.js'; import userstate from '@/lib/userstate.js'; import { - formatUnixTime, - formatTime, - getTimezoneOffset -} from '@/lib/datetime.js'; -import { - getAllLanguageInfos, - getLanguageInfo, - getDefaultLanguage, - transateIf, - getAllLongMonthNames, - getAllShortMonthNames, - getAllLongWeekdayNames, - getAllShortWeekdayNames, - getAllMinWeekdayNames, - getAllLongDateFormats, - getAllShortDateFormats, - getAllLongTimeFormats, - getAllShortTimeFormats, - getI18nLongDateFormat, - getI18nShortDateFormat, - getI18nLongTimeFormat, - getI18nShortTimeFormat, - getI18nLongYearFormat, - getI18nShortYearFormat, - getI18nLongYearMonthFormat, - getI18nShortYearMonthFormat, - getI18nLongMonthDayFormat, - getI18nShortMonthDayFormat, - isLongTime24HourFormat, - isShortTime24HourFormat, - getAllTimezones, - getAllCurrencies, - getDisplayCurrency, getI18nOptions, + transateIf, + i18nFunctions } from '@/lib/i18n.js'; import { showAlert, @@ -147,9 +110,6 @@ import TransactionTagSelectionSheet from '@/components/mobile/TransactionTagSele import TextareaAutoSize from '@/directives/mobile/textareaAutoSize.js'; -import { useSettingsStore } from '@/stores/setting.js'; -import { useUserStore } from '@/stores/user.js'; - import '@/styles/mobile/font-size-default.css'; import '@/styles/mobile/font-size-small.css'; import '@/styles/mobile/font-size-large.css'; @@ -201,95 +161,6 @@ registerComponents(app); app.use(pinia); app.use(i18n); -function getCurrentLanguageInfo() { - const locale = getLanguageInfo(i18n.global.locale); - - if (locale) { - return locale; - } - - return getDefaultLanguage(); -} - -function setLanguage(locale, force) { - if (!locale) { - locale = getDefaultLanguage(); - logger.info(`No specified language, use browser default language ${locale}`); - } - - if (!getLanguageInfo(locale)) { - locale = getDefaultLanguage(); - logger.warn(`Not found language ${locale}, use browser default language ${locale}`); - } - - if (!force && i18n.global.locale === locale) { - logger.info(`Current locale is already ${locale}`); - return locale; - } - - logger.info(`Apply current language to ${locale}`); - - i18n.global.locale = locale; - moment.updateLocale(locale, { - months : app.config.globalProperties.$locale.getAllLongMonthNames(), - monthsShort : app.config.globalProperties.$locale.getAllShortMonthNames(), - weekdays : app.config.globalProperties.$locale.getAllLongWeekdayNames(), - weekdaysShort : app.config.globalProperties.$locale.getAllShortWeekdayNames(), - weekdaysMin : app.config.globalProperties.$locale.getAllMinWeekdayNames(), - meridiem: function (hours) { - if (hours > 11) { - return i18n.global.t('datetime.PM.upperCase'); - } else { - return i18n.global.t('datetime.AM.upperCase'); - } - } - }); - services.setLocale(locale); - document.querySelector('html').setAttribute('lang', locale); - - const defaultCurrency = i18n.global.t('default.currency'); - const defaultFirstDayOfWeekName = i18n.global.t('default.firstDayOfWeek'); - let defaultFirstDayOfWeek = datetimeConstants.defaultFirstDayOfWeek; - - if (datetimeConstants.allWeekDays[defaultFirstDayOfWeekName]) { - defaultFirstDayOfWeek = datetimeConstants.allWeekDays[defaultFirstDayOfWeekName].type; - } - - const settingsStore = useSettingsStore(); - settingsStore.updateLocalizedDefaultSettings({ defaultCurrency, defaultFirstDayOfWeek }); - - return locale; -} - -function setTimezone(timezone) { - if (timezone) { - settings.setTimezone(timezone); - moment.tz.setDefault(timezone); - } else { - settings.setTimezone(''); - moment.tz.setDefault(); - } -} - -function initLocale() { - const userStore = useUserStore(); - const lastUserLanguage = userStore.currentUserLanguage; - - if (lastUserLanguage && getLanguageInfo(lastUserLanguage)) { - logger.info(`Last user language is ${lastUserLanguage}`); - setLanguage(lastUserLanguage, true); - } else { - setLanguage(null, true); - } - - if (settings.getTimezone()) { - logger.info(`Current timezone is ${settings.getTimezone()}`); - setTimezone(settings.getTimezone()); - } else { - logger.info(`No timezone is set, use browser default ${getTimezoneOffset()} (maybe ${moment.tz.guess(true)})`); - } -} - app.component('VueDatePicker', VueDatePicker); app.component('ItemIcon', ItemIcon); @@ -316,44 +187,7 @@ app.config.globalProperties.$version = version.getVersion(); app.config.globalProperties.$buildTime = version.getBuildTime(); app.config.globalProperties.$settings = settings; -app.config.globalProperties.$locale = { - getDefaultLanguage: getDefaultLanguage, - getAllLanguageInfos: getAllLanguageInfos, - getLanguageInfo: getLanguageInfo, - getAllLongMonthNames: () => getAllLongMonthNames(i18n.global.t), - getAllShortMonthNames: () => getAllShortMonthNames(i18n.global.t), - getAllLongWeekdayNames: () => getAllLongWeekdayNames(i18n.global.t), - getAllShortWeekdayNames: () => getAllShortWeekdayNames(i18n.global.t), - getAllMinWeekdayNames: () => getAllMinWeekdayNames(i18n.global.t), - getAllLongDateFormats: () => getAllLongDateFormats(i18n.global.t), - getAllShortDateFormats: () => getAllShortDateFormats(i18n.global.t), - getAllLongTimeFormats: () => getAllLongTimeFormats(i18n.global.t), - getAllShortTimeFormats: () => getAllShortTimeFormats(i18n.global.t), - formatUnixTimeToLongDateTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongDateFormat(i18n.global.t, userStore.currentUserLongDateFormat) + ' ' + getI18nLongTimeFormat(i18n.global.t, userStore.currentUserLongTimeFormat), utcOffset, currentUtcOffset), - formatUnixTimeToShortDateTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortDateFormat(i18n.global.t, userStore.currentUserShortDateFormat) + ' ' + getI18nShortTimeFormat(i18n.global.t, userStore.currentUserShortTimeFormat), utcOffset, currentUtcOffset), - formatUnixTimeToLongDate: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongDateFormat(i18n.global.t, userStore.currentUserLongDateFormat), utcOffset, currentUtcOffset), - formatUnixTimeToShortDate: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortDateFormat(i18n.global.t, userStore.currentUserShortDateFormat), utcOffset, currentUtcOffset), - formatUnixTimeToLongYear: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongYearFormat(i18n.global.t, userStore.currentUserLongDateFormat), utcOffset, currentUtcOffset), - formatUnixTimeToShortYear: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortYearFormat(i18n.global.t, userStore.currentUserShortDateFormat), utcOffset, currentUtcOffset), - formatUnixTimeToLongYearMonth: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongYearMonthFormat(i18n.global.t, userStore.currentUserLongDateFormat), utcOffset, currentUtcOffset), - formatUnixTimeToShortYearMonth: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortYearMonthFormat(i18n.global.t, userStore.currentUserShortDateFormat), utcOffset, currentUtcOffset), - formatUnixTimeToLongMonthDay: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongMonthDayFormat(i18n.global.t, userStore.currentUserLongDateFormat), utcOffset, currentUtcOffset), - formatUnixTimeToShortMonthDay: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortMonthDayFormat(i18n.global.t, userStore.currentUserShortDateFormat), utcOffset, currentUtcOffset), - formatUnixTimeToLongTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nLongTimeFormat(i18n.global.t, userStore.currentUserLongTimeFormat), utcOffset, currentUtcOffset), - formatUnixTimeToShortTime: (userStore, unixTime, utcOffset, currentUtcOffset) => formatUnixTime(unixTime, getI18nShortTimeFormat(i18n.global.t, userStore.currentUserShortTimeFormat), utcOffset, currentUtcOffset), - formatTimeToLongYearMonth: (userStore, dateTime) => formatTime(dateTime, getI18nLongYearMonthFormat(i18n.global.t, userStore.currentUserLongDateFormat)), - formatTimeToShortYearMonth: (userStore, dateTime) => formatTime(dateTime, getI18nShortYearMonthFormat(i18n.global.t, userStore.currentUserShortDateFormat)), - isLongTime24HourFormat: (userStore) => isLongTime24HourFormat(i18n.global.t, userStore.currentUserLongTimeFormat), - isShortTime24HourFormat: (userStore) => isShortTime24HourFormat(i18n.global.t, userStore.currentUserShortTimeFormat), - getCurrentLanguageInfo: getCurrentLanguageInfo, - setLanguage: setLanguage, - getTimezone: settings.getTimezone, - setTimezone: setTimezone, - getAllTimezones: (includeSystemDefault) => getAllTimezones(includeSystemDefault, i18n.global.t), - getAllCurrencies: () => getAllCurrencies(i18n.global.t), - getDisplayCurrency: (value, currencyCode, notConvertValue) => getDisplayCurrency(value, currencyCode, notConvertValue, i18n.global.t), - initLocale: initLocale -}; +app.config.globalProperties.$locale = i18nFunctions(i18n.global); app.config.globalProperties.$tIf = (text, isTranslate) => transateIf(text, isTranslate, i18n.global.t); app.config.globalProperties.$alert = (message, confirmCallback) => showAlert(message, confirmCallback, i18n.global.t); @@ -365,6 +199,4 @@ app.config.globalProperties.$routeBackOnError = routeBackOnError; app.config.globalProperties.$user = userstate; -app.config.globalProperties.$locale.initLocale(); - app.mount('#app'); diff --git a/src/stores/setting.js b/src/stores/setting.js index b58dc45f..772f323c 100644 --- a/src/stores/setting.js +++ b/src/stores/setting.js @@ -16,9 +16,13 @@ export const useSettingsStore = defineStore('settings', { } }), actions: { - updateLocalizedDefaultSettings({ defaultCurrency, defaultFirstDayOfWeek }) { - this.defaultSetting.currency = defaultCurrency; - this.defaultSetting.firstDayOfWeek = defaultFirstDayOfWeek; + updateLocalizedDefaultSettings(localeDefaultSettings) { + if (!localeDefaultSettings) { + return; + } + + this.defaultSetting.currency = localeDefaultSettings.defaultCurrency; + this.defaultSetting.firstDayOfWeek = localeDefaultSettings.defaultFirstDayOfWeek; } } }); diff --git a/src/views/mobile/LoginPage.vue b/src/views/mobile/LoginPage.vue index 79b7b4a3..b7d9cbfe 100644 --- a/src/views/mobile/LoginPage.vue +++ b/src/views/mobile/LoginPage.vue @@ -111,6 +111,7 @@