diff --git a/cmd/user_data.go b/cmd/user_data.go index a68eda1f..610e1ae1 100644 --- a/cmd/user_data.go +++ b/cmd/user_data.go @@ -398,10 +398,15 @@ func printUserInfo(user *models.User) { fmt.Printf("[Nickname] %s\n", user.Nickname) fmt.Printf("[Password] %s\n", user.Password) fmt.Printf("[Salt] %s\n", user.Salt) - fmt.Printf("[DefaultCurrency] %s\n", user.DefaultCurrency) fmt.Printf("[DefaultAccountId] %d\n", user.DefaultAccountId) - fmt.Printf("[FirstDayOfWeek] %s\n", user.FirstDayOfWeek) - fmt.Printf("[TransactionEditScope] %s\n", user.TransactionEditScope) + fmt.Printf("[TransactionEditScope] %s (%d)\n", user.TransactionEditScope, user.TransactionEditScope) + fmt.Printf("[Language] %s\n", user.Language) + fmt.Printf("[DefaultCurrency] %s\n", user.DefaultCurrency) + fmt.Printf("[FirstDayOfWeek] %s (%d)\n", user.FirstDayOfWeek, user.FirstDayOfWeek) + fmt.Printf("[LongDateFormat] %s (%d)\n", user.LongDateFormat, user.LongDateFormat) + fmt.Printf("[ShortDateFormat] %s (%d)\n", user.ShortDateFormat, user.ShortDateFormat) + fmt.Printf("[LongTimeFormat] %s (%d)\n", user.LongTimeFormat, user.LongTimeFormat) + fmt.Printf("[ShortTimeFormat] %s (%d)\n", user.ShortTimeFormat, user.ShortTimeFormat) fmt.Printf("[Deleted] %t\n", user.Deleted) fmt.Printf("[EmailVerified] %t\n", user.EmailVerified) fmt.Printf("[CreatedAt] %s (%d)\n", utils.FormatUnixTimeToLongDateTimeInServerTimezone(user.CreatedUnixTime), user.CreatedUnixTime) diff --git a/pkg/api/users.go b/pkg/api/users.go index 5b47aa85..0a8e9c3b 100644 --- a/pkg/api/users.go +++ b/pkg/api/users.go @@ -57,6 +57,7 @@ func (a *UsersApi) UserRegisterHandler(c *core.Context) (interface{}, *errs.Erro Email: userRegisterReq.Email, Nickname: userRegisterReq.Nickname, Password: userRegisterReq.Password, + Language: userRegisterReq.Language, DefaultCurrency: userRegisterReq.DefaultCurrency, FirstDayOfWeek: userRegisterReq.FirstDayOfWeek, TransactionEditScope: models.TRANSACTION_EDIT_SCOPE_ALL, @@ -161,12 +162,6 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs anythingUpdate = true } - if userUpdateReq.DefaultCurrency != "" && userUpdateReq.DefaultCurrency != user.DefaultCurrency { - user.DefaultCurrency = userUpdateReq.DefaultCurrency - userNew.DefaultCurrency = userUpdateReq.DefaultCurrency - anythingUpdate = true - } - if userUpdateReq.DefaultAccountId > 0 && userUpdateReq.DefaultAccountId != user.DefaultAccountId { accounts, err := a.accounts.GetAccountsByAccountIds(uid, []int64{userUpdateReq.DefaultAccountId}) @@ -179,14 +174,6 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs anythingUpdate = true } - if userUpdateReq.FirstDayOfWeek != nil && *userUpdateReq.FirstDayOfWeek != user.FirstDayOfWeek { - user.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek - userNew.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek - anythingUpdate = true - } else { - userNew.FirstDayOfWeek = models.WEEKDAY_INVALID - } - if userUpdateReq.TransactionEditScope != nil && *userUpdateReq.TransactionEditScope != user.TransactionEditScope { user.TransactionEditScope = *userUpdateReq.TransactionEditScope userNew.TransactionEditScope = *userUpdateReq.TransactionEditScope @@ -195,11 +182,66 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs userNew.TransactionEditScope = models.TRANSACTION_EDIT_SCOPE_INVALID } + modifyUserLanguage := false + + if userUpdateReq.Language != user.Language { + user.Language = userUpdateReq.Language + userNew.Language = userUpdateReq.Language + modifyUserLanguage = true + anythingUpdate = true + } + + if userUpdateReq.DefaultCurrency != "" && userUpdateReq.DefaultCurrency != user.DefaultCurrency { + user.DefaultCurrency = userUpdateReq.DefaultCurrency + userNew.DefaultCurrency = userUpdateReq.DefaultCurrency + anythingUpdate = true + } + + if userUpdateReq.FirstDayOfWeek != nil && *userUpdateReq.FirstDayOfWeek != user.FirstDayOfWeek { + user.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek + userNew.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek + anythingUpdate = true + } else { + userNew.FirstDayOfWeek = models.WEEKDAY_INVALID + } + + if userUpdateReq.LongDateFormat != nil && *userUpdateReq.LongDateFormat != user.LongDateFormat { + user.LongDateFormat = *userUpdateReq.LongDateFormat + userNew.LongDateFormat = *userUpdateReq.LongDateFormat + anythingUpdate = true + } else { + userNew.LongDateFormat = models.LONG_DATE_FORMAT_INVALID + } + + if userUpdateReq.ShortDateFormat != nil && *userUpdateReq.ShortDateFormat != user.ShortDateFormat { + user.ShortDateFormat = *userUpdateReq.ShortDateFormat + userNew.ShortDateFormat = *userUpdateReq.ShortDateFormat + anythingUpdate = true + } else { + userNew.ShortDateFormat = models.SHORT_DATE_FORMAT_INVALID + } + + if userUpdateReq.LongTimeFormat != nil && *userUpdateReq.LongTimeFormat != user.LongTimeFormat { + user.LongTimeFormat = *userUpdateReq.LongTimeFormat + userNew.LongTimeFormat = *userUpdateReq.LongTimeFormat + anythingUpdate = true + } else { + userNew.LongTimeFormat = models.LONG_TIME_FORMAT_INVALID + } + + if userUpdateReq.ShortTimeFormat != nil && *userUpdateReq.ShortTimeFormat != user.ShortTimeFormat { + user.ShortTimeFormat = *userUpdateReq.ShortTimeFormat + userNew.ShortTimeFormat = *userUpdateReq.ShortTimeFormat + anythingUpdate = true + } else { + userNew.ShortTimeFormat = models.SHORT_TIME_FORMAT_INVALID + } + if !anythingUpdate { return nil, errs.ErrNothingWillBeUpdated } - keyProfileUpdated, err := a.users.UpdateUser(userNew) + keyProfileUpdated, err := a.users.UpdateUser(userNew, modifyUserLanguage) if err != nil { log.ErrorfWithRequestId(c, "[users.UserUpdateProfileHandler] failed to update user \"uid:%d\", because %s", user.Uid, err.Error()) diff --git a/pkg/cli/user_data.go b/pkg/cli/user_data.go index 7a11dcbd..f6023c8b 100644 --- a/pkg/cli/user_data.go +++ b/pkg/cli/user_data.go @@ -142,7 +142,7 @@ func (l *UserDataCli) ModifyUserPassword(c *cli.Context, username string, passwo Password: password, } - _, err = l.users.UpdateUser(userNew) + _, err = l.users.UpdateUser(userNew, false) if err != nil { log.BootErrorf("[user_data.ModifyUserPassword] failed to update user \"%s\" password, because %s", user.Username, err.Error()) diff --git a/pkg/models/datetime.go b/pkg/models/datetime.go new file mode 100644 index 00000000..1003fe7c --- /dev/null +++ b/pkg/models/datetime.go @@ -0,0 +1,162 @@ +package models + +import "fmt" + +// WeekDay represents week day +type WeekDay byte + +// Week days +const ( + WEEKDAY_SUNDAY WeekDay = 0 + WEEKDAY_MONDAY WeekDay = 1 + WEEKDAY_TUESDAY WeekDay = 2 + WEEKDAY_WEDNESDAY WeekDay = 3 + WEEKDAY_THURSDAY WeekDay = 4 + WEEKDAY_FRIDAY WeekDay = 5 + WEEKDAY_SATURDAY WeekDay = 6 + WEEKDAY_INVALID WeekDay = 255 +) + +// String returns a textual representation of the week day enum +func (d WeekDay) String() string { + switch d { + case WEEKDAY_SUNDAY: + return "Sunday" + case WEEKDAY_MONDAY: + return "Monday" + case WEEKDAY_TUESDAY: + return "Tuesday" + case WEEKDAY_WEDNESDAY: + return "Wednesday" + case WEEKDAY_THURSDAY: + return "Thursday" + case WEEKDAY_FRIDAY: + return "Friday" + case WEEKDAY_SATURDAY: + return "Saturday" + case WEEKDAY_INVALID: + return "Invalid" + default: + return fmt.Sprintf("Invalid(%d)", int(d)) + } +} + +// LongDateFormat represents long date format +type LongDateFormat byte + +// Long Date Format +const ( + LONG_DATE_FORMAT_DEFAULT LongDateFormat = 0 + LONG_DATE_FORMAT_YYYY_M_D LongDateFormat = 1 + LONG_DATE_FORMAT_M_D_YYYY LongDateFormat = 2 + LONG_DATE_FORMAT_D_M_YYYY LongDateFormat = 3 + LONG_DATE_FORMAT_INVALID LongDateFormat = 255 +) + +// String returns a textual representation of the long date format enum +func (f LongDateFormat) String() string { + switch f { + case LONG_DATE_FORMAT_DEFAULT: + return "Default" + case LONG_DATE_FORMAT_YYYY_M_D: + return "YYYY_MM_D" + case LONG_DATE_FORMAT_M_D_YYYY: + return "M_D_YYYY" + case LONG_DATE_FORMAT_D_M_YYYY: + return "D_M_YYYY" + case LONG_DATE_FORMAT_INVALID: + return "Invalid" + default: + return fmt.Sprintf("Invalid(%d)", int(f)) + } +} + +// ShortDateFormat represents short date format +type ShortDateFormat byte + +// Short Date Format +const ( + SHORT_DATE_FORMAT_DEFAULT ShortDateFormat = 0 + SHORT_DATE_FORMAT_YYYY_M_D ShortDateFormat = 1 + SHORT_DATE_FORMAT_M_D_YYYY ShortDateFormat = 2 + SHORT_DATE_FORMAT_D_M_YYYY ShortDateFormat = 3 + SHORT_DATE_FORMAT_INVALID ShortDateFormat = 255 +) + +// String returns a textual representation of the short date format enum +func (f ShortDateFormat) String() string { + switch f { + case SHORT_DATE_FORMAT_DEFAULT: + return "Default" + case SHORT_DATE_FORMAT_YYYY_M_D: + return "YYYY_MM_D" + case SHORT_DATE_FORMAT_M_D_YYYY: + return "M_D_YYYY" + case SHORT_DATE_FORMAT_D_M_YYYY: + return "D_M_YYYY" + case SHORT_DATE_FORMAT_INVALID: + return "Invalid" + default: + return fmt.Sprintf("Invalid(%d)", int(f)) + } +} + +// LongTimeFormat represents long time format +type LongTimeFormat byte + +// Long Time Format +const ( + LONG_TIME_FORMAT_DEFAULT LongTimeFormat = 0 + LONG_TIME_FORMAT_HH_MM_SS LongTimeFormat = 1 + LONG_TIME_FORMAT_A_HH_MM_SS LongTimeFormat = 2 + LONG_TIME_FORMAT_HH_MM_SS_A LongTimeFormat = 3 + LONG_TIME_FORMAT_INVALID LongTimeFormat = 255 +) + +// String returns a textual representation of the long time format enum +func (f LongTimeFormat) String() string { + switch f { + case LONG_TIME_FORMAT_DEFAULT: + return "Default" + case LONG_TIME_FORMAT_HH_MM_SS: + return "HH_MM_SS" + case LONG_TIME_FORMAT_A_HH_MM_SS: + return "A_HH_MM_SS" + case LONG_TIME_FORMAT_HH_MM_SS_A: + return "HH_MM_SS_A" + case LONG_TIME_FORMAT_INVALID: + return "Invalid" + default: + return fmt.Sprintf("Invalid(%d)", int(f)) + } +} + +// ShortTimeFormat represents short time format +type ShortTimeFormat byte + +// Short Time Format +const ( + SHORT_TIME_FORMAT_DEFAULT ShortTimeFormat = 0 + SHORT_TIME_FORMAT_HH_MM ShortTimeFormat = 1 + SHORT_TIME_FORMAT_A_HH_MM ShortTimeFormat = 2 + SHORT_TIME_FORMAT_HH_MM_A ShortTimeFormat = 3 + SHORT_TIME_FORMAT_INVALID ShortTimeFormat = 255 +) + +// String returns a textual representation of the short time format enum +func (f ShortTimeFormat) String() string { + switch f { + case SHORT_TIME_FORMAT_DEFAULT: + return "Default" + case SHORT_TIME_FORMAT_HH_MM: + return "HH_MM" + case SHORT_TIME_FORMAT_A_HH_MM: + return "A_HH_MM" + case SHORT_TIME_FORMAT_HH_MM_A: + return "HH_MM_A" + case SHORT_TIME_FORMAT_INVALID: + return "Invalid" + default: + return fmt.Sprintf("Invalid(%d)", int(f)) + } +} diff --git a/pkg/models/user.go b/pkg/models/user.go index 5aaf428c..91c653c7 100644 --- a/pkg/models/user.go +++ b/pkg/models/user.go @@ -7,45 +7,6 @@ import ( "github.com/mayswind/ezbookkeeping/pkg/utils" ) -// WeekDay represents week day -type WeekDay byte - -// Week days -const ( - WEEKDAY_SUNDAY WeekDay = 0 - WEEKDAY_MONDAY WeekDay = 1 - WEEKDAY_TUESDAY WeekDay = 2 - WEEKDAY_WEDNESDAY WeekDay = 3 - WEEKDAY_THURSDAY WeekDay = 4 - WEEKDAY_FRIDAY WeekDay = 5 - WEEKDAY_SATURDAY WeekDay = 6 - WEEKDAY_INVALID WeekDay = 255 -) - -// String returns a textual representation of the week day enum -func (d WeekDay) String() string { - switch d { - case WEEKDAY_SUNDAY: - return "Sunday" - case WEEKDAY_MONDAY: - return "Monday" - case WEEKDAY_TUESDAY: - return "Tuesday" - case WEEKDAY_WEDNESDAY: - return "Wednesday" - case WEEKDAY_THURSDAY: - return "Thursday" - case WEEKDAY_FRIDAY: - return "Friday" - case WEEKDAY_SATURDAY: - return "Saturday" - case WEEKDAY_INVALID: - return "Invalid" - default: - return fmt.Sprintf("Invalid(%d)", int(d)) - } -} - // TransactionEditScope represents the scope which transaction can be edited type TransactionEditScope byte @@ -93,10 +54,15 @@ type User struct { Nickname string `xorm:"VARCHAR(64) NOT NULL"` Password string `xorm:"VARCHAR(64) NOT NULL"` Salt string `xorm:"VARCHAR(10) NOT NULL"` - DefaultCurrency string `xorm:"VARCHAR(3) NOT NULL"` DefaultAccountId int64 - FirstDayOfWeek WeekDay `xorm:"TINYINT NOT NULL"` TransactionEditScope TransactionEditScope `xorm:"TINYINT NOT NULL"` + Language string `xorm:"VARCHAR(10)"` + DefaultCurrency string `xorm:"VARCHAR(3) NOT NULL"` + FirstDayOfWeek WeekDay `xorm:"TINYINT NOT NULL"` + LongDateFormat LongDateFormat `xorm:"TINYINT"` + ShortDateFormat ShortDateFormat `xorm:"TINYINT"` + LongTimeFormat LongTimeFormat `xorm:"TINYINT"` + ShortTimeFormat ShortTimeFormat `xorm:"TINYINT"` Deleted bool `xorm:"NOT NULL"` EmailVerified bool `xorm:"NOT NULL"` CreatedUnixTime int64 @@ -110,10 +76,15 @@ type UserBasicInfo struct { Username string `json:"username"` Email string `json:"email"` Nickname string `json:"nickname"` - DefaultCurrency string `json:"defaultCurrency"` DefaultAccountId int64 `json:"defaultAccountId,string"` - FirstDayOfWeek WeekDay `json:"firstDayOfWeek"` TransactionEditScope TransactionEditScope `json:"transactionEditScope"` + Language string `json:"language"` + DefaultCurrency string `json:"defaultCurrency"` + FirstDayOfWeek WeekDay `json:"firstDayOfWeek"` + LongDateFormat LongDateFormat `json:"longDateFormat"` + ShortDateFormat ShortDateFormat `json:"shortDateFormat"` + LongTimeFormat LongTimeFormat `json:"longTimeFormat"` + ShortTimeFormat ShortTimeFormat `json:"shortTimeFormat"` } // UserLoginRequest represents all parameters of user login request @@ -128,6 +99,7 @@ type UserRegisterRequest struct { Email string `json:"email" binding:"required,notBlank,max=100,validEmail"` Nickname string `json:"nickname" binding:"required,notBlank,max=64"` Password string `json:"password" binding:"required,min=6,max=128"` + Language string `json:"language" binding:"required,min=2,max=16"` DefaultCurrency string `json:"defaultCurrency" binding:"required,len=3,validCurrency"` FirstDayOfWeek WeekDay `json:"firstDayOfWeek" binding:"min=0,max=6"` } @@ -138,10 +110,15 @@ type UserProfileUpdateRequest struct { Nickname string `json:"nickname" binding:"omitempty,notBlank,max=64"` Password string `json:"password" binding:"omitempty,min=6,max=128"` OldPassword string `json:"oldPassword" binding:"omitempty,min=6,max=128"` - DefaultCurrency string `json:"defaultCurrency" binding:"omitempty,len=3,validCurrency"` DefaultAccountId int64 `json:"defaultAccountId,string" binding:"omitempty,min=1"` - FirstDayOfWeek *WeekDay `json:"firstDayOfWeek" binding:"omitempty,min=0,max=6"` TransactionEditScope *TransactionEditScope `json:"transactionEditScope" binding:"omitempty,min=0,max=7"` + Language string `json:"language" binding:"omitempty,min=2,max=16"` + DefaultCurrency string `json:"defaultCurrency" binding:"omitempty,len=3,validCurrency"` + FirstDayOfWeek *WeekDay `json:"firstDayOfWeek" binding:"omitempty,min=0,max=6"` + LongDateFormat *LongDateFormat `json:"longDateFormat" binding:"omitempty,min=0,max=3"` + ShortDateFormat *ShortDateFormat `json:"shortDateFormat" binding:"omitempty,min=0,max=3"` + LongTimeFormat *LongTimeFormat `json:"longTimeFormat" binding:"omitempty,min=0,max=3"` + ShortTimeFormat *ShortTimeFormat `json:"shortTimeFormat" binding:"omitempty,min=0,max=3"` } // UserProfileUpdateResponse represents the data returns to frontend after updating profile @@ -155,10 +132,15 @@ type UserProfileResponse struct { Username string `json:"username"` Email string `json:"email"` Nickname string `json:"nickname"` - DefaultCurrency string `json:"defaultCurrency"` DefaultAccountId int64 `json:"defaultAccountId,string"` - FirstDayOfWeek WeekDay `json:"firstDayOfWeek"` TransactionEditScope TransactionEditScope `json:"transactionEditScope"` + Language string `json:"language"` + DefaultCurrency string `json:"defaultCurrency"` + FirstDayOfWeek WeekDay `json:"firstDayOfWeek"` + LongDateFormat LongDateFormat `json:"longDateFormat"` + ShortDateFormat ShortDateFormat `json:"shortDateFormat"` + LongTimeFormat LongTimeFormat `json:"longTimeFormat"` + ShortTimeFormat ShortTimeFormat `json:"shortTimeFormat"` LastLoginAt int64 `json:"lastLoginAt"` } @@ -210,10 +192,15 @@ func (u *User) ToUserBasicInfo() *UserBasicInfo { Username: u.Username, Email: u.Email, Nickname: u.Nickname, - DefaultCurrency: u.DefaultCurrency, DefaultAccountId: u.DefaultAccountId, - FirstDayOfWeek: u.FirstDayOfWeek, TransactionEditScope: u.TransactionEditScope, + Language: u.Language, + DefaultCurrency: u.DefaultCurrency, + FirstDayOfWeek: u.FirstDayOfWeek, + LongDateFormat: u.LongDateFormat, + ShortDateFormat: u.ShortDateFormat, + LongTimeFormat: u.LongTimeFormat, + ShortTimeFormat: u.ShortTimeFormat, } } @@ -223,10 +210,15 @@ func (u *User) ToUserProfileResponse() *UserProfileResponse { Username: u.Username, Email: u.Email, Nickname: u.Nickname, - DefaultCurrency: u.DefaultCurrency, DefaultAccountId: u.DefaultAccountId, - FirstDayOfWeek: u.FirstDayOfWeek, TransactionEditScope: u.TransactionEditScope, + Language: u.Language, + DefaultCurrency: u.DefaultCurrency, + FirstDayOfWeek: u.FirstDayOfWeek, + LongDateFormat: u.LongDateFormat, + ShortDateFormat: u.ShortDateFormat, + LongTimeFormat: u.LongTimeFormat, + ShortTimeFormat: u.ShortTimeFormat, LastLoginAt: u.LastLoginUnixTime, } } diff --git a/pkg/services/users.go b/pkg/services/users.go index e5e70a16..c22a735e 100644 --- a/pkg/services/users.go +++ b/pkg/services/users.go @@ -150,7 +150,7 @@ func (s *UserService) CreateUser(user *models.User) error { } // UpdateUser saves an existed user model to database -func (s *UserService) UpdateUser(user *models.User) (keyProfileUpdated bool, err error) { +func (s *UserService) UpdateUser(user *models.User, modifyUserLanguage bool) (keyProfileUpdated bool, err error) { if user.Uid <= 0 { return false, errs.ErrUserIdInvalid } @@ -186,20 +186,40 @@ func (s *UserService) UpdateUser(user *models.User) (keyProfileUpdated bool, err updateCols = append(updateCols, "nickname") } - if user.DefaultCurrency != "" { - updateCols = append(updateCols, "default_currency") - } - if user.DefaultAccountId > 0 { updateCols = append(updateCols, "default_account_id") } + if models.TRANSACTION_EDIT_SCOPE_NONE <= user.TransactionEditScope && user.TransactionEditScope <= models.TRANSACTION_EDIT_SCOPE_THIS_YEAR_OR_LATER { + updateCols = append(updateCols, "transaction_edit_scope") + } + + if modifyUserLanguage || user.Language != "" { + updateCols = append(updateCols, "language") + } + + if user.DefaultCurrency != "" { + updateCols = append(updateCols, "default_currency") + } + if models.WEEKDAY_SUNDAY <= user.FirstDayOfWeek && user.FirstDayOfWeek <= models.WEEKDAY_SATURDAY { updateCols = append(updateCols, "first_day_of_week") } - if models.TRANSACTION_EDIT_SCOPE_NONE <= user.TransactionEditScope && user.TransactionEditScope <= models.TRANSACTION_EDIT_SCOPE_THIS_YEAR_OR_LATER { - updateCols = append(updateCols, "transaction_edit_scope") + if models.LONG_DATE_FORMAT_DEFAULT <= user.LongDateFormat && user.LongDateFormat <= models.LONG_DATE_FORMAT_D_M_YYYY { + updateCols = append(updateCols, "long_date_format") + } + + if models.SHORT_DATE_FORMAT_DEFAULT <= user.ShortDateFormat && user.ShortDateFormat <= models.SHORT_DATE_FORMAT_D_M_YYYY { + updateCols = append(updateCols, "short_date_format") + } + + if models.LONG_TIME_FORMAT_DEFAULT <= user.LongTimeFormat && user.LongTimeFormat <= models.LONG_TIME_FORMAT_HH_MM_SS_A { + updateCols = append(updateCols, "long_time_format") + } + + if models.SHORT_TIME_FORMAT_DEFAULT <= user.ShortTimeFormat && user.ShortTimeFormat <= models.SHORT_TIME_FORMAT_HH_MM_A { + updateCols = append(updateCols, "short_time_format") } user.UpdatedUnixTime = now diff --git a/src/MobileApp.vue b/src/MobileApp.vue index 7b107793..e5d4640f 100644 --- a/src/MobileApp.vue +++ b/src/MobileApp.vue @@ -75,14 +75,20 @@ export default { } }, created() { - if (this.$user.isUserLogined()) { - if (!this.$settings.isEnableApplicationLock()) { + const self = this; + + if (self.$user.isUserLogined()) { + if (!self.$settings.isEnableApplicationLock()) { // refresh token if user is logined - this.$store.dispatch('refreshTokenAndRevokeOldToken'); + self.$store.dispatch('refreshTokenAndRevokeOldToken').then(response => { + if (response.user && response.user.language) { + self.$locale.setLanguage(response.user.language); + } + }); // auto refresh exchange rates data - if (this.$settings.isAutoUpdateExchangeRatesData()) { - this.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); + if (self.$settings.isAutoUpdateExchangeRatesData()) { + self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); } } } diff --git a/src/components/mobile/DateRangeSelectionSheet.vue b/src/components/mobile/DateRangeSelectionSheet.vue index 0fcc02dd..e8b087a5 100644 --- a/src/components/mobile/DateRangeSelectionSheet.vue +++ b/src/components/mobile/DateRangeSelectionSheet.vue @@ -95,16 +95,15 @@ export default { return this.$utilities.arrangeArrayWithNewStartIndex(this.$locale.getAllMinWeekdayNames(), this.firstDayOfWeek); }, is24Hour() { - const datetimeFormat = this.$t('format.datetime.long'); - return this.$utilities.is24HourFormat(datetimeFormat); + return this.$locale.isLongTime24HourFormat(); }, beginDateTime() { const actualBeginUnixTime = this.$utilities.getActualUnixTimeForStore(this.$utilities.getUnixTime(this.dateRange[0]), this.$utilities.getTimezoneOffsetMinutes(), this.$utilities.getBrowserTimezoneOffsetMinutes()); - return this.$utilities.formatUnixTime(actualBeginUnixTime, this.$t('format.datetime.long')); + return this.$utilities.formatUnixTime(actualBeginUnixTime, this.$locale.getLongDateTimeFormat()); }, endDateTime() { const actualEndUnixTime = this.$utilities.getActualUnixTimeForStore(this.$utilities.getUnixTime(this.dateRange[1]), this.$utilities.getTimezoneOffsetMinutes(), this.$utilities.getBrowserTimezoneOffsetMinutes()); - return this.$utilities.formatUnixTime(actualEndUnixTime, this.$t('format.datetime.long')); + return this.$utilities.formatUnixTime(actualEndUnixTime, this.$locale.getLongDateTimeFormat()); }, presetRanges() { const presetRanges = []; diff --git a/src/components/mobile/DateTimeSelectionSheet.vue b/src/components/mobile/DateTimeSelectionSheet.vue index c42c9711..b3894be6 100644 --- a/src/components/mobile/DateTimeSelectionSheet.vue +++ b/src/components/mobile/DateTimeSelectionSheet.vue @@ -70,8 +70,7 @@ export default { return this.$utilities.arrangeArrayWithNewStartIndex(this.$locale.getAllMinWeekdayNames(), this.firstDayOfWeek); }, is24Hour() { - const datetimeFormat = this.$t('format.datetime.long'); - return this.$utilities.is24HourFormat(datetimeFormat); + return this.$locale.isLongTime24HourFormat(); } }, methods: { diff --git a/src/consts/datetime.js b/src/consts/datetime.js index c10a8b7f..ff98acc4 100644 --- a/src/consts/datetime.js +++ b/src/consts/datetime.js @@ -39,6 +39,96 @@ const allWeekDaysArray = [ allWeekDays.Saturday ]; +const allLongDateFormat = { + YYYYMMDD: { + type: 1, + key: 'yyyy_mm_dd' + }, + MMDDYYYY: { + type: 2, + key: 'mm_dd_yyyy' + }, + DDMMYYYY: { + type: 3, + key: 'dd_mm_yyyy' + } +}; + +const allLongDateFormatArray = [ + allLongDateFormat.YYYYMMDD, + allLongDateFormat.MMDDYYYY, + allLongDateFormat.DDMMYYYY +]; + +const allShortDateFormat = { + YYYYMMDD: { + type: 1, + key: 'yyyy_mm_dd' + }, + MMDDYYYY: { + type: 2, + key: 'mm_dd_yyyy' + }, + DDMMYYYY: { + type: 3, + key: 'dd_mm_yyyy' + } +}; + +const allShortDateFormatArray = [ + allShortDateFormat.YYYYMMDD, + allShortDateFormat.MMDDYYYY, + allShortDateFormat.DDMMYYYY +]; + +const allLongTimeFormat = { + HHMMSS: { + type: 1, + key: 'hh_mm_ss', + is24HourFormat: true + }, + AHHMMSS: { + type: 2, + key: 'a_hh_mm_ss', + is24HourFormat: false + }, + HHMMSSA: { + type: 3, + key: 'hh_mm_ss_a', + is24HourFormat: false + } +}; + +const allLongTimeFormatArray = [ + allLongTimeFormat.HHMMSS, + allLongTimeFormat.AHHMMSS, + allLongTimeFormat.HHMMSSA +]; + +const allShortTimeFormat = { + HHMM: { + type: 1, + key: 'hh_mm', + is24HourFormat: true + }, + AHHMM: { + type: 2, + key: 'a_hh_mm', + is24HourFormat: false + }, + HHMMA: { + type: 3, + key: 'hh_mm_a', + is24HourFormat: false + } +}; + +const allShortTimeFormatArray = [ + allShortTimeFormat.HHMM, + allShortTimeFormat.AHHMM, + allShortTimeFormat.HHMMA +]; + const allDateRanges = { All: { type: 0, @@ -91,10 +181,28 @@ const allDateRanges = { }; const defaultFirstDayOfWeek = allWeekDays.Sunday.type; +const defaultLongDateFormat = allLongDateFormat.YYYYMMDD; +const defaultShortDateFormat = allShortDateFormat.YYYYMMDD; +const defaultLongTimeFormat = allLongTimeFormat.HHMMSS; +const defaultShortTimeFormat = allShortTimeFormat.HHMM; +const defaultDateTimeFormatValue = 0; export default { allWeekDays: allWeekDays, allWeekDaysArray: allWeekDaysArray, + allLongDateFormat: allLongDateFormat, + allLongDateFormatArray: allLongDateFormatArray, + allShortDateFormat: allShortDateFormat, + allShortDateFormatArray: allShortDateFormatArray, + allLongTimeFormat: allLongTimeFormat, + allLongTimeFormatArray: allLongTimeFormatArray, + allShortTimeFormat: allShortTimeFormat, + allShortTimeFormatArray: allShortTimeFormatArray, allDateRanges: allDateRanges, - defaultFirstDayOfWeek: defaultFirstDayOfWeek + defaultFirstDayOfWeek: defaultFirstDayOfWeek, + defaultLongDateFormat: defaultLongDateFormat, + defaultShortDateFormat: defaultShortDateFormat, + defaultLongTimeFormat: defaultLongTimeFormat, + defaultShortTimeFormat: defaultShortTimeFormat, + defaultDateTimeFormatValue: defaultDateTimeFormatValue, }; diff --git a/src/lib/i18n.js b/src/lib/i18n.js index 914c1554..02b2ff8c 100644 --- a/src/lib/i18n.js +++ b/src/lib/i18n.js @@ -1,4 +1,5 @@ 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"; @@ -250,6 +251,88 @@ export function getAllMinWeekdayNames(translateFn) { ]; } +export function getAllLongDateFormats(translateFn) { + const defaultLongDateFormatTypeName = translateFn('default.longDateFormat'); + return getDateTimeFormats(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longDate', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat); +} + +export function getAllShortDateFormats(translateFn) { + const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat'); + return getDateTimeFormats(translateFn, datetime.allShortDateFormat, datetime.allShortDateFormatArray, 'format.shortDate', defaultShortDateFormatTypeName, datetime.defaultShortDateFormat); +} + +export function getAllLongTimeFormats(translateFn) { + const defaultLongTimeFormatTypeName = translateFn('default.longTimeFormat'); + return getDateTimeFormats(translateFn, datetime.allLongTimeFormat, datetime.allLongTimeFormatArray, 'format.longTime', defaultLongTimeFormatTypeName, datetime.defaultLongTimeFormat); +} + +export 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) { + const defaultLongDateFormatTypeName = translateFn('default.longDateFormat'); + return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longDate', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue); +} + +export 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) { + const defaultLongDateFormatTypeName = translateFn('default.longDateFormat'); + return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longYear', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue); +} + +export 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) { + const defaultLongDateFormatTypeName = translateFn('default.longDateFormat'); + return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longYearMonth', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue); +} + +export 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) { + const defaultLongDateFormatTypeName = translateFn('default.longDateFormat'); + return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longMonthDay', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue); +} + +export 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) { + const defaultLongTimeFormatTypeName = translateFn('default.longTimeFormat'); + return getDateTimeFormat(translateFn, datetime.allLongTimeFormat, datetime.allLongTimeFormatArray, 'format.longTime', defaultLongTimeFormatTypeName, datetime.defaultLongTimeFormat, formatTypeValue); +} + +export 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) { + const defaultLongTimeFormatTypeName = translateFn('default.longTimeFormat'); + const type = utilities.getDateTimeFormatType(datetime.allLongTimeFormat, datetime.allLongTimeFormatArray, defaultLongTimeFormatTypeName, datetime.defaultLongTimeFormat, formatTypeValue); + return type.is24HourFormat; +} + +export function isShortTime24HourFormat(translateFn, formatTypeValue) { + const defaultShortTimeFormatTypeName = translateFn('default.shortTimeFormat'); + const type = utilities.getDateTimeFormatType(datetime.allShortTimeFormat, datetime.allShortTimeFormatArray, defaultShortTimeFormatTypeName, datetime.defaultShortTimeFormat, formatTypeValue); + return type.is24HourFormat; +} + export function getAllTimezones(includeSystemDefault, translateFn) { const defaultTimezoneOffset = utilities.getTimezoneOffset(); const defaultTimezoneOffsetMinutes = utilities.getTimezoneOffsetMinutes(); @@ -462,3 +545,34 @@ function getLocaleFromLanguageAlias(alias) { 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')} (${utilities.formatTime(utilities.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: utilities.formatTime(utilities.getCurrentDateTime(), format) + }); + } + + return ret; +} + +function getDateTimeFormat(translateFn, allFormatMap, allFormatArray, localeFormatPathPrefix, localeDefaultFormatTypeName, systemDefaultFormatType, formatTypeValue) { + const type = utilities.getDateTimeFormatType(allFormatMap, allFormatArray, + localeDefaultFormatTypeName, systemDefaultFormatType, formatTypeValue); + return translateFn(`${localeFormatPathPrefix}.${type.key}`); +} diff --git a/src/lib/services.js b/src/lib/services.js index f531e802..9431a1fa 100644 --- a/src/lib/services.js +++ b/src/lib/services.js @@ -87,12 +87,13 @@ export default { } }); }, - register: ({ username, email, nickname, password, defaultCurrency, firstDayOfWeek }) => { + register: ({ username, email, nickname, password, language, defaultCurrency, firstDayOfWeek }) => { return axios.post('register.json', { username, email, nickname, password, + language, defaultCurrency, firstDayOfWeek }); @@ -135,16 +136,21 @@ export default { getProfile: () => { return axios.get('v1/users/profile/get.json'); }, - updateProfile: ({ email, nickname, password, oldPassword, defaultCurrency, defaultAccountId, firstDayOfWeek, transactionEditScope }) => { + updateProfile: ({ email, nickname, password, oldPassword, defaultAccountId, transactionEditScope, language, defaultCurrency, firstDayOfWeek, longDateFormat, shortDateFormat, longTimeFormat, shortTimeFormat }) => { return axios.post('v1/users/profile/update.json', { email, nickname, password, oldPassword, - defaultCurrency, defaultAccountId, + transactionEditScope, + language, + defaultCurrency, firstDayOfWeek, - transactionEditScope + longDateFormat, + shortDateFormat, + longTimeFormat, + shortTimeFormat }); }, get2FAStatus: () => { diff --git a/src/lib/settings.js b/src/lib/settings.js index c4e78e5d..7c3d152e 100644 --- a/src/lib/settings.js +++ b/src/lib/settings.js @@ -7,7 +7,6 @@ const settingsLocalStorageKey = 'ebk_app_settings'; const serverSettingsCookieKey = 'ebk_server_settings'; const defaultSettings = { - lang: 'en', timeZone: '', debug: false, applicationLock: false, @@ -129,8 +128,6 @@ function clearSettings() { export default { isProduction: () => process.env.NODE_ENV === 'production', - getLanguage: () => getOriginalOption('lang'), - setLanguage: value => setOption('lang', value), getTimezone: () => getOption('timeZone'), setTimezone: value => setOption('timeZone', value), isEnableDebug: () => getOption('debug'), diff --git a/src/lib/utilities/datetime.js b/src/lib/utilities/datetime.js index 0f1f4b3e..13300833 100644 --- a/src/lib/utilities/datetime.js +++ b/src/lib/utilities/datetime.js @@ -89,16 +89,6 @@ export function parseDateFromUnixTime(unixTime, utcOffset, currentUtcOffset) { return moment.unix(unixTime); } -export function is24HourFormat(format) { - if (format.indexOf('HH') >= 0 && format.indexOf('hh') < 0) { - return true; - } else if (format.indexOf('HH') < 0 && format.indexOf('hh') >= 0) { - return false; - } - - return true; -} - export function formatUnixTime(unixTime, format, utcOffset, currentUtcOffset) { return parseDateFromUnixTime(unixTime, utcOffset, currentUtcOffset).format(format); } @@ -214,6 +204,16 @@ export function getThisYearLastUnixTime() { return moment.unix(getThisYearFirstUnixTime()).add(1, 'years').subtract(1, 'seconds').unix(); } +export function getDateTimeFormatType(allFormatMap, allFormatArray, localeDefaultFormatTypeName, systemDefaultFormatType, formatTypeValue) { + if (formatTypeValue > dateTimeConstants.defaultDateTimeFormatValue && allFormatArray[formatTypeValue - 1] && allFormatArray[formatTypeValue - 1].key) { + return allFormatArray[formatTypeValue - 1]; + } else if (formatTypeValue === dateTimeConstants.defaultDateTimeFormatValue && allFormatMap[localeDefaultFormatTypeName] && allFormatMap[localeDefaultFormatTypeName].key) { + return allFormatMap[localeDefaultFormatTypeName]; + } else { + return systemDefaultFormatType; + } +} + export function getShiftedDateRange(minTime, maxTime, scale) { const minDateTime = parseDateFromUnixTime(minTime).set({ second: 0, millisecond: 0 }); const maxDateTime = parseDateFromUnixTime(maxTime).set({ second: 59, millisecond: 999 }); diff --git a/src/lib/utilities/index.js b/src/lib/utilities/index.js index 15f61c4e..8038dd5b 100644 --- a/src/lib/utilities/index.js +++ b/src/lib/utilities/index.js @@ -31,7 +31,6 @@ import { getCurrentUnixTime, getCurrentDateTime, parseDateFromUnixTime, - is24HourFormat, formatUnixTime, formatTime, getUnixTime, @@ -55,6 +54,7 @@ import { getThisMonthLastUnixTime, getThisYearFirstUnixTime, getThisYearLastUnixTime, + getDateTimeFormatType, getShiftedDateRange, getDateRangeByDateType, isDateRangeMatchFullYears, @@ -123,7 +123,6 @@ export default { getCurrentUnixTime, getCurrentDateTime, parseDateFromUnixTime, - is24HourFormat, formatUnixTime, formatTime, getUnixTime, @@ -147,6 +146,7 @@ export default { getThisMonthLastUnixTime, getThisYearFirstUnixTime, getThisYearLastUnixTime, + getDateTimeFormatType, getShiftedDateRange, getDateRangeByDateType, isDateRangeMatchFullYears, diff --git a/src/locales/en.js b/src/locales/en.js index f637580b..decab858 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -6,31 +6,62 @@ export default { }, 'default': { 'currency': 'USD', - 'firstDayOfWeek': 'Sunday' + 'firstDayOfWeek': 'Sunday', + 'longDateFormat': 'MMDDYYYY', + 'shortDateFormat': 'MMDDYYYY', + 'longTimeFormat': 'HHMMSSA', + 'shortTimeFormat': 'HHMMA' }, 'format': { // The type of date or time format is moment format, ref: https://momentjs.com/docs/#/displaying/ - 'date': { - 'long': 'M/D/YYYY', - 'short': 'M/D/YYYY' + 'longDate': { + 'yyyy_mm_dd': 'YYYY MMMM DD', + 'mm_dd_yyyy': 'MMMM D, YYYY', + 'dd_mm_yyyy': 'D MMMM, YYYY' }, - 'datetime': { - 'long': 'M/D/YYYY hh:mm:ss A', - 'long-without-second': 'M/D/YYYY hh:mm A', + 'shortDate': { + 'yyyy_mm_dd': 'YYYY-M-D', + 'mm_dd_yyyy': 'M/D/YYYY', + 'dd_mm_yyyy': 'D/M/YYYY' }, - 'year': { - 'long': 'YYYY', - 'short': 'YYYY' + 'longYear': { // used in home page + 'yyyy_mm_dd': 'YYYY', + 'mm_dd_yyyy': 'YYYY', + 'dd_mm_yyyy': 'YYYY' }, - 'yearMonth': { - 'long': 'YYYY-M', - 'short': 'YYYY-M' + 'shortYear': {// used in transaction statistics page + 'yyyy_mm_dd': 'YYYY', + 'mm_dd_yyyy': 'YYYY', + 'dd_mm_yyyy': 'YYYY' }, - 'monthDay': { - 'long': 'M/D', - 'short': 'M/D' + 'longYearMonth': { // used in transaction list page + 'yyyy_mm_dd': 'YYYY MMMM', + 'mm_dd_yyyy': 'MMMM, YYYY', + 'dd_mm_yyyy': 'MMMM, YYYY' }, - 'hourMinute': { - 'long': 'hh:mm A' + 'shortYearMonth': { // used in transaction statistics page + 'yyyy_mm_dd': 'YYYY-M', + 'mm_dd_yyyy': 'MMM, YYYY', + 'dd_mm_yyyy': 'MMM, YYYY' + }, + 'longMonthDay': { // used in home page + 'yyyy_mm_dd': 'MMMM D', + 'mm_dd_yyyy': 'MMMM D', + 'dd_mm_yyyy': 'D MMMM' + }, + 'shortMonthDay': { // should be similar to the shortDate. it would be next to the shortDate content on the transaction statistics page + 'yyyy_mm_dd': 'M/D', + 'mm_dd_yyyy': 'M/D', + 'dd_mm_yyyy': 'D/M' + }, + 'longTime': { + 'hh_mm_ss': 'HH:mm:ss', + 'a_hh_mm_ss': 'A hh:mm:ss', + 'hh_mm_ss_a': 'hh:mm:ss A' + }, + 'shortTime': { + 'hh_mm': 'HH:mm', + 'a_hh_mm': 'A hh:mm', + 'hh_mm_a': 'hh:mm A' }, 'currency': { 'symbol': '{symbol} {amount}' @@ -41,6 +72,12 @@ export default { 'exportFilename': 'ezBookkeeping_{nickname}_export_data' }, 'datetime': { + 'AM': { + 'upperCase': 'AM' + }, + 'PM': { + 'upperCase': 'PM' + }, 'Monday': { 'min': 'Mo', 'short': 'Mon', @@ -657,6 +694,7 @@ export default { 'None': 'None', 'Not Specified': 'Not Specified', 'No results': 'No results', + 'Unknown': 'Unknown', 'Done': 'Done', 'Continue': 'Continue', 'Status': 'Status', @@ -727,6 +765,10 @@ export default { 'Default Currency': 'Default Currency', 'Default Account': 'Default Account', 'First Day of Week': 'First Day of Week', + 'Long Date Format': 'Long Date Format', + 'Short Date Format': 'Short Date Format', + 'Long Time Format': 'Long Time Format', + 'Short Time Format': 'Short Time Format', 'Editable Transaction Scope': 'Editable Transaction Scope', 'Today or later': 'Today or later', 'Recent 24 hours or later': 'Recent 24 hours or later', @@ -894,6 +936,7 @@ export default { 'Language': 'Language', 'Timezone': 'Timezone', 'System Default': 'System Default', + 'Language Default': 'Language Default', 'Auto Update Exchange Rates Data': 'Auto Update Exchange Rates Data', 'Auto Get Current Geographic Location': 'Auto Get Current Geographic Location', 'Enable Thousands Separator': 'Enable Thousands Separator', diff --git a/src/locales/index.js b/src/locales/index.js index 422ecf15..ce09f3e3 100644 --- a/src/locales/index.js +++ b/src/locales/index.js @@ -1,5 +1,3 @@ -import 'moment/dist/locale/zh-cn.js'; - import en from './en.js' import zhHans from './zh_Hans.js' diff --git a/src/locales/zh_Hans.js b/src/locales/zh_Hans.js index 4ae0f943..181c83f4 100644 --- a/src/locales/zh_Hans.js +++ b/src/locales/zh_Hans.js @@ -6,31 +6,62 @@ export default { }, 'default': { 'currency': 'CNY', - 'firstDayOfWeek': 'Monday' + 'firstDayOfWeek': 'Monday', + 'longDateFormat': 'YYYYMMDD', + 'shortDateFormat': 'YYYYMMDD', + 'longTimeFormat': 'HHMMSS', + 'shortTimeFormat': 'HHMM' }, 'format': { - 'date': { - 'long': 'YYYY年M月D日', - 'short': 'YYYY-M-D' + 'longDate': { + 'yyyy_mm_dd': 'YYYY年M月D日', + 'mm_dd_yyyy': 'M/D/YYYY', + 'dd_mm_yyyy': 'D/M/YYYY' }, - 'datetime': { - 'long': 'YYYY年M月D日 HH:mm:ss', - 'long-without-second': 'YYYY年M月D日 HH:mm', + 'shortDate': { + 'yyyy_mm_dd': 'YYYY-M-D', + 'mm_dd_yyyy': 'M/D/YYYY', + 'dd_mm_yyyy': 'D/M/YYYY' }, - 'year': { - 'long': 'YYYY年', - 'short': 'YYYY' + 'longYear': { + 'yyyy_mm_dd': 'YYYY年', + 'mm_dd_yyyy': 'YYYY年', + 'dd_mm_yyyy': 'YYYY年' }, - 'yearMonth': { - 'long': 'YYYY年M月', - 'short': 'YYYY-M' + 'shortYear': { + 'yyyy_mm_dd': 'YYYY', + 'mm_dd_yyyy': 'YYYY', + 'dd_mm_yyyy': 'YYYY' }, - 'monthDay': { - 'long': 'M月D日', - 'short': 'M-D' + 'longYearMonth': { + 'yyyy_mm_dd': 'YYYY年M月', + 'mm_dd_yyyy': 'M/YYYY', + 'dd_mm_yyyy': 'M/YYYY' }, - 'hourMinute': { - 'long': 'HH:mm' + 'shortYearMonth': { + 'yyyy_mm_dd': 'YYYY-M', + 'mm_dd_yyyy': 'M/YYYY', + 'dd_mm_yyyy': 'M/YYYY' + }, + 'longMonthDay': { + 'yyyy_mm_dd': 'M月D日', + 'mm_dd_yyyy': 'M/D', + 'dd_mm_yyyy': 'D/M' + }, + 'shortMonthDay': { + 'yyyy_mm_dd': 'M-D', + 'mm_dd_yyyy': 'M/D', + 'dd_mm_yyyy': 'D/M' + }, + 'longTime': { + 'hh_mm_ss': 'HH:mm:ss', + 'a_hh_mm_ss': 'A hh:mm:ss', + 'hh_mm_ss_a': 'hh:mm:ss A' + }, + 'shortTime': { + 'hh_mm': 'HH:mm', + 'a_hh_mm': 'A hh:mm', + 'hh_mm_a': 'hh:mm A' }, 'currency': { 'symbol': '{symbol} {amount}' @@ -41,6 +72,12 @@ export default { 'exportFilename': 'ezBookkeeping_{nickname}_导出数据' }, 'datetime': { + 'AM': { + 'upperCase': '上午' + }, + 'PM': { + 'upperCase': '下午' + }, 'Monday': { 'min': '一', 'short': '周一', @@ -657,6 +694,7 @@ export default { 'None': '无', 'Not Specified': '未指定', 'No results': '无结果', + 'Unknown': '未知', 'Done': '完成', 'Continue': '继续', 'Status': '状态', @@ -727,6 +765,10 @@ export default { 'Default Currency': '默认货币', 'Default Account': '默认账户', 'First Day of Week': '每周第一天', + 'Long Date Format': '长日期格式', + 'Short Date Format': '短日期格式', + 'Long Time Format': '长时间格式', + 'Short Time Format': '短时间格式', 'Editable Transaction Scope': '可编辑交易范围', 'Today or later': '今天或更晚', 'Recent 24 hours or later': '最近24小时或更晚', @@ -894,6 +936,7 @@ export default { 'Language': '语言', 'Timezone': '时区', 'System Default': '系统默认', + 'Language Default': '语言默认', 'Auto Update Exchange Rates Data': '自动更新汇率数据', 'Auto Get Current Geographic Location': '自动获取当前地理位置', 'Enable Thousands Separator': '启用千位分隔符', diff --git a/src/mobile-main.js b/src/mobile-main.js index 99f75486..4b364ca5 100644 --- a/src/mobile-main.js +++ b/src/mobile-main.js @@ -104,6 +104,22 @@ import { getAllLongWeekdayNames, getAllShortWeekdayNames, getAllMinWeekdayNames, + getAllLongDateFormats, + getAllShortDateFormats, + getAllLongTimeFormats, + getAllShortTimeFormats, + getI18nLongDateFormat, + getI18nShortDateFormat, + getI18nLongTimeFormat, + getI18nShortTimeFormat, + getI18nLongYearFormat, + getI18nShortYearFormat, + getI18nLongYearMonthFormat, + getI18nShortYearMonthFormat, + getI18nLongMonthDayFormat, + getI18nShortMonthDayFormat, + isLongTime24HourFormat, + isShortTime24HourFormat, getAllTimezones, getAllCurrencies, getDisplayCurrency, @@ -186,10 +202,22 @@ app.use(store); app.use(i18n); function setLanguage(locale) { - if (settings.getLanguage() !== locale) { - settings.setLanguage(locale); + if (!locale) { + locale = getDefaultLanguage(); + logger.info(`No specified language, use browser default language ${locale}`); } + if (!getLanguageInfo(locale)) { + logger.warn(`Not found language ${locale}`); + return null; + } + + if (i18n.global.locale === locale) { + return locale; + } + + logger.info(`Apply current language to ${locale}`); + i18n.global.locale = locale; moment.updateLocale(locale, { months : app.config.globalProperties.$locale.getAllLongMonthNames(), @@ -197,6 +225,13 @@ function setLanguage(locale) { 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); @@ -225,12 +260,13 @@ function setTimezone(timezone) { } function initLocale() { - if (settings.getLanguage()) { - logger.info(`Current language is ${settings.getLanguage()}`); - setLanguage(settings.getLanguage()); + const lastUserLanguage = store.getters.currentUserLanguage; + + if (lastUserLanguage && getLanguageInfo(lastUserLanguage)) { + logger.info(`Last user language is ${lastUserLanguage}`); + setLanguage(lastUserLanguage); } else { - logger.info(`No language is set, use browser default ${getDefaultLanguage()}`); - setLanguage(getDefaultLanguage()); + setLanguage(null); } if (settings.getTimezone()) { @@ -296,6 +332,24 @@ app.config.globalProperties.$locale = { 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), + getLongDateTimeFormat: () => getI18nLongDateFormat(i18n.global.t, store.getters.currentUserLongDateFormat) + ' ' + getI18nLongTimeFormat(i18n.global.t, store.getters.currentUserLongTimeFormat), + getShortDateTimeFormat: () => getI18nShortDateFormat(i18n.global.t, store.getters.currentUserShortDateFormat) + ' ' + getI18nShortTimeFormat(i18n.global.t, store.getters.currentUserShortTimeFormat), + getLongDateFormat: () => getI18nLongDateFormat(i18n.global.t, store.getters.currentUserLongDateFormat), + getShortDateFormat: () => getI18nShortDateFormat(i18n.global.t, store.getters.currentUserShortDateFormat), + getLongYearFormat: () => getI18nLongYearFormat(i18n.global.t, store.getters.currentUserLongDateFormat), + getShortYearFormat: () => getI18nShortYearFormat(i18n.global.t, store.getters.currentUserShortDateFormat), + getLongYearMonthFormat: () => getI18nLongYearMonthFormat(i18n.global.t, store.getters.currentUserLongDateFormat), + getShortYearMonthFormat: () => getI18nShortYearMonthFormat(i18n.global.t, store.getters.currentUserShortDateFormat), + getLongMonthDayFormat: () => getI18nLongMonthDayFormat(i18n.global.t, store.getters.currentUserLongDateFormat), + getShortMonthDayFormat: () => getI18nShortMonthDayFormat(i18n.global.t, store.getters.currentUserShortDateFormat), + getLongTimeFormat: () => getI18nLongTimeFormat(i18n.global.t, store.getters.currentUserLongTimeFormat), + getShortTimeFormat: () => getI18nShortTimeFormat(i18n.global.t, store.getters.currentUserShortTimeFormat), + isLongTime24HourFormat: () => isLongTime24HourFormat(i18n.global.t, store.getters.currentUserLongTimeFormat), + isShortTime24HourFormat: () => isShortTime24HourFormat(i18n.global.t, store.getters.currentUserShortTimeFormat), setLanguage: setLanguage, getTimezone: settings.getTimezone, setTimezone: setTimezone, diff --git a/src/store/index.js b/src/store/index.js index 986fab66..ad794994 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -73,9 +73,14 @@ import { clearUserInfoState, resetState, currentUserNickname, - currentUserDefaultCurrency, currentUserDefaultAccountId, + currentUserLanguage, + currentUserDefaultCurrency, currentUserFirstDayOfWeek, + currentUserLongDateFormat, + currentUserShortDateFormat, + currentUserLongTimeFormat, + currentUserShortTimeFormat, } from './user.js'; import { @@ -166,8 +171,13 @@ const stores = { strict: !settings.isProduction(), state: { defaultSetting: { + language: '', currency: currencyConstants.defaultCurrency, - firstDayOfWeek: datetimeConstants.defaultFirstDayOfWeek + firstDayOfWeek: datetimeConstants.defaultFirstDayOfWeek, + longDateFormat: 0, + shortDateFormat: 0, + longTimeFormat: 0, + shortTimeFormat: 0 }, currentUserInfo: userState.getUserInfo(), latestExchangeRates: getExchangeRatesFromLocalStorage(), @@ -210,9 +220,14 @@ const stores = { getters: { // user currentUserNickname, - currentUserDefaultCurrency, currentUserDefaultAccountId, + currentUserLanguage, + currentUserDefaultCurrency, currentUserFirstDayOfWeek, + currentUserLongDateFormat, + currentUserShortDateFormat, + currentUserLongTimeFormat, + currentUserShortTimeFormat, // exchange rates exchangeRatesLastUpdateTime, diff --git a/src/store/user.js b/src/store/user.js index 2cbc827f..7aa7497e 100644 --- a/src/store/user.js +++ b/src/store/user.js @@ -133,6 +133,7 @@ export function register(context, { user }) { password: user.password, email: user.email, nickname: user.nickname, + language: user.language, defaultCurrency: user.defaultCurrency, firstDayOfWeek: user.firstDayOfWeek }).then(response => { @@ -235,10 +236,15 @@ export function updateUserProfile(context, { profile, currentPassword }) { oldPassword: currentPassword, email: profile.email, nickname: profile.nickname, - defaultCurrency: profile.defaultCurrency, defaultAccountId: profile.defaultAccountId, + transactionEditScope: profile.transactionEditScope, + language: profile.language, + defaultCurrency: profile.defaultCurrency, firstDayOfWeek: profile.firstDayOfWeek, - transactionEditScope: profile.transactionEditScope + longDateFormat: profile.longDateFormat, + shortDateFormat: profile.shortDateFormat, + longTimeFormat: profile.longTimeFormat, + shortTimeFormat: profile.shortTimeFormat }).then(response => { const data = response.data; @@ -391,17 +397,42 @@ export function currentUserNickname(state) { return userInfo.nickname || userInfo.username || null; } -export function currentUserDefaultCurrency(state) { - const userInfo = state.currentUserInfo || {}; - return userInfo.defaultCurrency || state.defaultSetting.currency; -} - export function currentUserDefaultAccountId(state) { const userInfo = state.currentUserInfo || {}; return userInfo.defaultAccountId || ''; } +export function currentUserLanguage(state) { + const userInfo = state.currentUserInfo || {}; + return userInfo.language || state.defaultSetting.language; +} + +export function currentUserDefaultCurrency(state) { + const userInfo = state.currentUserInfo || {}; + return userInfo.defaultCurrency || state.defaultSetting.currency; +} + export function currentUserFirstDayOfWeek(state) { const userInfo = state.currentUserInfo || {}; return utilities.isNumber(userInfo.firstDayOfWeek) ? userInfo.firstDayOfWeek : state.defaultSetting.firstDayOfWeek; } + +export function currentUserLongDateFormat(state) { + const userInfo = state.currentUserInfo || {}; + return utilities.isNumber(userInfo.longDateFormat) ? userInfo.longDateFormat : state.defaultSetting.longDateFormat; +} + +export function currentUserShortDateFormat(state) { + const userInfo = state.currentUserInfo || {}; + return utilities.isNumber(userInfo.shortDateFormat) ? userInfo.shortDateFormat : state.defaultSetting.shortDateFormat; +} + +export function currentUserLongTimeFormat(state) { + const userInfo = state.currentUserInfo || {}; + return utilities.isNumber(userInfo.longTimeFormat) ? userInfo.longTimeFormat : state.defaultSetting.longTimeFormat; +} + +export function currentUserShortTimeFormat(state) { + const userInfo = state.currentUserInfo || {}; + return utilities.isNumber(userInfo.shortTimeFormat) ? userInfo.shortTimeFormat : state.defaultSetting.shortTimeFormat; +} diff --git a/src/views/mobile/AboutPage.vue b/src/views/mobile/AboutPage.vue index 5264ab8b..f6f545c5 100644 --- a/src/views/mobile/AboutPage.vue +++ b/src/views/mobile/AboutPage.vue @@ -51,7 +51,7 @@ export default { return this.$buildTime; } - return this.$utilities.formatUnixTime(this.$buildTime, this.$t('format.datetime.long')); + return this.$utilities.formatUnixTime(this.$buildTime, this.$locale.getLongDateTimeFormat()); }, licenseLines() { return this.$licenses.license.replaceAll(/\r/g, '').split('\n'); diff --git a/src/views/mobile/ExchangeRatesPage.vue b/src/views/mobile/ExchangeRatesPage.vue index 740f8cf8..b5efb6a0 100644 --- a/src/views/mobile/ExchangeRatesPage.vue +++ b/src/views/mobile/ExchangeRatesPage.vue @@ -111,7 +111,7 @@ export default { return ''; } - return this.$utilities.formatUnixTime(this.exchangeRatesData.updateTime, this.$t('format.date.long')); + return this.$utilities.formatUnixTime(this.exchangeRatesData.updateTime, this.$locale.getLongDateFormat()); }, exchangeRateMap() { const exchangeRateMap = {}; diff --git a/src/views/mobile/HomePage.vue b/src/views/mobile/HomePage.vue index 6fcfb6c9..9727d504 100644 --- a/src/views/mobile/HomePage.vue +++ b/src/views/mobile/HomePage.vue @@ -235,19 +235,19 @@ export default { return { today: { - displayTime: self.$utilities.formatUnixTime(self.dateRange.today.startTime, self.$t('format.date.long')), + displayTime: self.$utilities.formatUnixTime(self.dateRange.today.startTime, self.$locale.getLongDateFormat()), }, thisWeek: { - startTime: self.$utilities.formatUnixTime(self.dateRange.thisWeek.startTime, self.$t('format.monthDay.long')), - endTime: self.$utilities.formatUnixTime(self.dateRange.thisWeek.endTime, self.$t('format.monthDay.long')) + startTime: self.$utilities.formatUnixTime(self.dateRange.thisWeek.startTime, self.$locale.getLongMonthDayFormat()), + endTime: self.$utilities.formatUnixTime(self.dateRange.thisWeek.endTime, self.$locale.getLongMonthDayFormat()) }, thisMonth: { displayTime: self.$utilities.formatUnixTime(self.dateRange.thisMonth.startTime, 'MMMM'), - startTime: self.$utilities.formatUnixTime(self.dateRange.thisMonth.startTime, self.$t('format.monthDay.long')), - endTime: self.$utilities.formatUnixTime(self.dateRange.thisMonth.endTime, self.$t('format.monthDay.long')) + startTime: self.$utilities.formatUnixTime(self.dateRange.thisMonth.startTime, self.$locale.getLongMonthDayFormat()), + endTime: self.$utilities.formatUnixTime(self.dateRange.thisMonth.endTime, self.$locale.getLongMonthDayFormat()) }, thisYear: { - displayTime: self.$utilities.formatUnixTime(self.dateRange.thisYear.startTime, self.$t('format.year.long')) + displayTime: self.$utilities.formatUnixTime(self.dateRange.thisYear.startTime, self.$locale.getLongYearFormat()) } }; }, diff --git a/src/views/mobile/LoginPage.vue b/src/views/mobile/LoginPage.vue index c547046e..3f04820d 100644 --- a/src/views/mobile/LoginPage.vue +++ b/src/views/mobile/LoginPage.vue @@ -200,6 +200,10 @@ export default { return; } + if (authResponse.user && authResponse.user.language) { + self.$locale.setLanguage(authResponse.user.language); + } + if (self.$settings.isAutoUpdateExchangeRatesData()) { self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); } @@ -244,10 +248,14 @@ export default { token: self.tempToken, passcode: self.twoFAVerifyType === 'passcode' ? self.passcode : null, recoveryCode: self.twoFAVerifyType === 'backupcode' ? self.backupCode : null - }).then(() => { + }).then(authResponse => { self.verifying = false; self.$hideLoading(); + if (authResponse.user && authResponse.user.language) { + self.$locale.setLanguage(authResponse.user.language); + } + if (self.$settings.isAutoUpdateExchangeRatesData()) { self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); } diff --git a/src/views/mobile/SettingsPage.vue b/src/views/mobile/SettingsPage.vue index 5eb50d1f..f7e689bc 100644 --- a/src/views/mobile/SettingsPage.vue +++ b/src/views/mobile/SettingsPage.vue @@ -16,18 +16,6 @@ {{ $t('Application') }} - - - - @@ -117,20 +104,9 @@ export default { version() { return 'v' + this.$version; }, - allLanguages() { - return this.$locale.getAllLanguageInfos(); - }, allTimezones() { return this.$locale.getAllTimezones(true); }, - currentLocale: { - get: function () { - return this.$i18n.locale; - }, - set: function (value) { - this.$locale.setLanguage(value); - } - }, currentTimezone: { get: function () { return this.$locale.getTimezone(); @@ -144,7 +120,7 @@ export default { }, exchangeRatesLastUpdateDate() { const exchangeRatesLastUpdateTime = this.$store.getters.exchangeRatesLastUpdateTime; - return exchangeRatesLastUpdateTime ? this.$utilities.formatUnixTime(exchangeRatesLastUpdateTime, this.$t('format.date.long')) : ''; + return exchangeRatesLastUpdateTime ? this.$utilities.formatUnixTime(exchangeRatesLastUpdateTime, this.$locale.getLongDateFormat()) : ''; }, isAutoUpdateExchangeRatesData: { get: function () { diff --git a/src/views/mobile/SignupPage.vue b/src/views/mobile/SignupPage.vue index 8a0136d2..ea5e94a5 100644 --- a/src/views/mobile/SignupPage.vue +++ b/src/views/mobile/SignupPage.vue @@ -188,6 +188,7 @@ export default { confirmPassword: '', email: '', nickname: '', + language: self.$i18n.locale, defaultCurrency: self.$store.state.defaultSetting.currency, firstDayOfWeek: self.$constants.datetime.allWeekDays[self.$t('default.firstDayOfWeek')] ? self.$constants.datetime.allWeekDays[self.$t('default.firstDayOfWeek')].type : 0 }, @@ -221,6 +222,7 @@ export default { const isCurrencyDefault = this.user.defaultCurrency === this.$store.state.defaultSetting.currency; const isFirstWeekDayDefault = this.user.firstDayOfWeek === (this.$constants.datetime.allWeekDays[this.$t('default.firstDayOfWeek')] ? this.$constants.datetime.allWeekDays[this.$t('default.firstDayOfWeek')].type : 0); + this.user.language = value; this.$locale.setLanguage(value); if (isCurrencyDefault) { @@ -324,7 +326,7 @@ export default { self.$store.dispatch('register', { user: self.user - }).then(() => { + }).then(response => { if (!self.$user.isUserLogined()) { self.submitting = false; self.$hideLoading(); @@ -339,6 +341,10 @@ export default { return; } + if (response.user && response.user.language) { + self.$locale.setLanguage(response.user.language); + } + if (self.$settings.isAutoUpdateExchangeRatesData()) { self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); } diff --git a/src/views/mobile/UnlockPage.vue b/src/views/mobile/UnlockPage.vue index b883daba..7d0eb4a3 100644 --- a/src/views/mobile/UnlockPage.vue +++ b/src/views/mobile/UnlockPage.vue @@ -113,7 +113,11 @@ export default { self.$hideLoading(); self.$user.unlockTokenByWebAuthn(id, userName, userSecret); - self.$store.dispatch('refreshTokenAndRevokeOldToken'); + self.$store.dispatch('refreshTokenAndRevokeOldToken').then(response => { + if (response.user && response.user.language) { + self.$locale.setLanguage(response.user.language); + } + }); if (self.$settings.isAutoUpdateExchangeRatesData()) { self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); @@ -136,34 +140,40 @@ export default { }); }, unlockByPin(pinCode) { - if (!this.isPinCodeValid(pinCode)) { + const self = this; + + if (!self.isPinCodeValid(pinCode)) { return; } - if (this.$ui.isModalShowing()) { + if (self.$ui.isModalShowing()) { return; } - const router = this.f7router; - const user = this.$store.state.currentUserInfo; + const router = self.f7router; + const user = self.$store.state.currentUserInfo; if (!user || !user.username) { - this.$alert('An error has occurred'); + self.$alert('An error has occurred'); return; } try { - this.$user.unlockTokenByPinCode(user.username, pinCode); - this.$store.dispatch('refreshTokenAndRevokeOldToken'); + self.$user.unlockTokenByPinCode(user.username, pinCode); + self.$store.dispatch('refreshTokenAndRevokeOldToken').then(response => { + if (response.user && response.user.language) { + self.$locale.setLanguage(response.user.language); + } + }); - if (this.$settings.isAutoUpdateExchangeRatesData()) { - this.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); + if (self.$settings.isAutoUpdateExchangeRatesData()) { + self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); } router.refreshPage(); } catch (ex) { - this.$logger.error('failed to unlock by pin code', ex); - this.$toast('PIN code is wrong'); + self.$logger.error('failed to unlock by pin code', ex); + self.$toast('PIN code is wrong'); } }, relogin() { diff --git a/src/views/mobile/statistics/TransactionPage.vue b/src/views/mobile/statistics/TransactionPage.vue index 847e8a9e..8dc0bf78 100644 --- a/src/views/mobile/statistics/TransactionPage.vue +++ b/src/views/mobile/statistics/TransactionPage.vue @@ -217,10 +217,10 @@ @@ -618,15 +618,15 @@ export default { } if (this.$utilities.isDateRangeMatchFullYears(query.startTime, query.endTime)) { - const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$t('format.year.short')); - const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$t('format.year.short')); + const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$locale.getShortYearFormat()); + const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$locale.getShortYearFormat()); return displayStartTime !== displayEndTime ? `${displayStartTime} ~ ${displayEndTime}` : displayStartTime; } if (this.$utilities.isDateRangeMatchFullMonths(query.startTime, query.endTime)) { - const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$t('format.yearMonth.short')); - const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$t('format.yearMonth.short')); + const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$locale.getShortYearMonthFormat()); + const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$locale.getShortYearMonthFormat()); return displayStartTime !== displayEndTime ? `${displayStartTime} ~ ${displayEndTime}` : displayStartTime; } @@ -634,13 +634,13 @@ export default { const startTimeYear = this.$utilities.getYear(this.$utilities.parseDateFromUnixTime(query.startTime)); const endTimeYear = this.$utilities.getYear(this.$utilities.parseDateFromUnixTime(query.endTime)); - const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$t('format.date.short')); - const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$t('format.date.short')); + const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$locale.getShortDateFormat()); + const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$locale.getShortDateFormat()); if (displayStartTime === displayEndTime) { return displayStartTime; } else if (startTimeYear === endTimeYear) { - const displayShortEndTime = this.$utilities.formatUnixTime(query.endTime, this.$t('format.monthDay.short')); + const displayShortEndTime = this.$utilities.formatUnixTime(query.endTime, this.$locale.getShortMonthDayFormat()); return `${displayStartTime} ~ ${displayShortEndTime}`; } diff --git a/src/views/mobile/transactions/EditPage.vue b/src/views/mobile/transactions/EditPage.vue index 25c866cf..489c1a69 100644 --- a/src/views/mobile/transactions/EditPage.vue +++ b/src/views/mobile/transactions/EditPage.vue @@ -213,7 +213,7 @@ link="#" no-chevron :class="{ 'readonly': mode === 'view' }" :header="$t('Transaction Time')" - :title="$utilities.formatUnixTime($utilities.getActualUnixTimeForStore(transaction.time, $utilities.getTimezoneOffsetMinutes(), $utilities.getBrowserTimezoneOffsetMinutes()), this.$t('format.datetime.long'))" + :title="$utilities.formatUnixTime($utilities.getActualUnixTimeForStore(transaction.time, $utilities.getTimezoneOffsetMinutes(), $utilities.getBrowserTimezoneOffsetMinutes()), $locale.getLongDateTimeFormat())" @click="showTransactionDateTimeSheet = true" > @@ -840,6 +840,11 @@ export default {