mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-05-31 11:52:10 +00:00
Refactor locale number (#24134)
Before, the `GiteaLocaleNumber.js` was just written as a a drop-in replacement for old `js-pretty-number`. Actually, we can use Golang's `text` package to format. This PR partially completes the TODOs in `GiteaLocaleNumber.js`: > if we have complete backend locale support (eg: Golang "x/text" package), we can drop this component. > tooltip: only 2 usages of this, we can replace it with Golang's "x/text/number" package in the future. This PR also helps #24131 Screenshots: <details>   </details>
This commit is contained in:
parent
be7cd73439
commit
7681d582cd
19 changed files with 118 additions and 106 deletions
|
@ -15,17 +15,20 @@ import (
|
|||
"code.gitea.io/gitea/modules/translation/i18n"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
"golang.org/x/text/number"
|
||||
)
|
||||
|
||||
type contextKey struct{}
|
||||
|
||||
var ContextKey interface{} = &contextKey{}
|
||||
var ContextKey any = &contextKey{}
|
||||
|
||||
// Locale represents an interface to translation
|
||||
type Locale interface {
|
||||
Language() string
|
||||
Tr(string, ...interface{}) string
|
||||
TrN(cnt interface{}, key1, keyN string, args ...interface{}) string
|
||||
Tr(string, ...any) string
|
||||
TrN(cnt any, key1, keyN string, args ...any) string
|
||||
PrettyNumber(v any) string
|
||||
}
|
||||
|
||||
// LangType represents a lang type
|
||||
|
@ -135,6 +138,7 @@ func Match(tags ...language.Tag) language.Tag {
|
|||
type locale struct {
|
||||
i18n.Locale
|
||||
Lang, LangName string // these fields are used directly in templates: .i18n.Lang
|
||||
msgPrinter *message.Printer
|
||||
}
|
||||
|
||||
// NewLocale return a locale
|
||||
|
@ -147,13 +151,24 @@ func NewLocale(lang string) Locale {
|
|||
langName := "unknown"
|
||||
if l, ok := allLangMap[lang]; ok {
|
||||
langName = l.Name
|
||||
} else if len(setting.Langs) > 0 {
|
||||
lang = setting.Langs[0]
|
||||
langName = setting.Names[0]
|
||||
}
|
||||
|
||||
i18nLocale, _ := i18n.GetLocale(lang)
|
||||
return &locale{
|
||||
l := &locale{
|
||||
Locale: i18nLocale,
|
||||
Lang: lang,
|
||||
LangName: langName,
|
||||
}
|
||||
if langTag, err := language.Parse(lang); err != nil {
|
||||
log.Error("Failed to parse language tag from name %q: %v", l.Lang, err)
|
||||
l.msgPrinter = message.NewPrinter(language.English)
|
||||
} else {
|
||||
l.msgPrinter = message.NewPrinter(langTag)
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *locale) Language() string {
|
||||
|
@ -199,7 +214,7 @@ var trNLangRules = map[string]func(int64) int{
|
|||
}
|
||||
|
||||
// TrN returns translated message for plural text translation
|
||||
func (l *locale) TrN(cnt interface{}, key1, keyN string, args ...interface{}) string {
|
||||
func (l *locale) TrN(cnt any, key1, keyN string, args ...any) string {
|
||||
var c int64
|
||||
if t, ok := cnt.(int); ok {
|
||||
c = int64(t)
|
||||
|
@ -223,3 +238,8 @@ func (l *locale) TrN(cnt interface{}, key1, keyN string, args ...interface{}) st
|
|||
}
|
||||
return l.Tr(keyN, args...)
|
||||
}
|
||||
|
||||
func (l *locale) PrettyNumber(v any) string {
|
||||
// TODO: this mechanism is not good enough, the complete solution is to switch the translation system to ICU message format
|
||||
return l.msgPrinter.Sprintf("%v", number.Decimal(v))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue