Themes: add currency type which does some reformatting

This commit is contained in:
Pieter Vander Vennet 2024-04-27 01:47:51 +02:00
parent c8eef2c8f6
commit d40474d47e
2 changed files with 76 additions and 0 deletions

View file

@ -28,6 +28,7 @@ import TagValidator from "./Validators/TagValidator"
import IdValidator from "./Validators/IdValidator"
import SlopeValidator from "./Validators/SlopeValidator"
import VeloparkValidator from "./Validators/VeloparkValidator"
import CurrencyValidator from "./Validators/CurrencyValidator"
export type ValidatorType = (typeof Validators.availableTypes)[number]
@ -60,6 +61,7 @@ export default class Validators {
"id",
"slope",
"velopark",
"currency"
] as const
public static readonly AllValidators: ReadonlyArray<Validator> = [
@ -89,6 +91,7 @@ export default class Validators {
new IdValidator(),
new SlopeValidator(),
new VeloparkValidator(),
new CurrencyValidator()
]
private static _byType = Validators._byTypeConstructor()

View file

@ -0,0 +1,73 @@
import { Validator } from "../Validator"
import { Utils } from "../../../Utils"
export default class CurrencyValidator extends Validator {
private readonly segmenter: Intl.Segmenter
private readonly symbolToCurrencyMapping: Map<string, string>
private readonly supportedCurrencies: Set<string>
constructor() {
super("currency", "Validates monetary amounts")
if (Intl.Segmenter === undefined || Utils.runningFromConsole) {
// Librewolf doesn't support this
return
}
let locale = "en-US"
if(!Utils.runningFromConsole){
locale??= navigator.language
}
this.segmenter = new Intl.Segmenter(locale, {
granularity: "word"
})
const mapping: Map<string, string> = new Map<string, string>()
const supportedCurrencies: Set<string> = new Set(Intl.supportedValuesOf("currency"))
this.supportedCurrencies = supportedCurrencies
for (const currency of supportedCurrencies) {
const symbol = (0).toLocaleString(
locale,
{
style: "currency",
currency: currency,
minimumFractionDigits: 0,
maximumFractionDigits: 0
}
).replace(/\d/g, "").trim()
mapping.set(symbol.toLowerCase(), currency)
}
this.symbolToCurrencyMapping = mapping
}
reformat(s: string): string {
if (!this.segmenter) {
return s
}
const parts = Array.from(this.segmenter.segment(s)).map(i => i.segment).filter(part => part.trim().length > 0)
if(parts.length !== 2){
return s
}
const mapping = this.symbolToCurrencyMapping
let currency: string = undefined
let amount = undefined
for (const part of parts) {
const lc = part.toLowerCase()
if (this.supportedCurrencies.has(part.toUpperCase())) {
currency = part.toUpperCase()
continue
}
if (mapping.has(lc)) {
currency = mapping.get(lc)
continue
}
amount = part
}
if(amount === undefined || currency === undefined){
return s
}
return amount+" "+currency
}
}