mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 08:06:19 +00:00
* chore(deps-dev): bump @antfu/eslint-config in /frontend Bumps [@antfu/eslint-config](https://github.com/antfu/eslint-config) from 9.5.1 to 10.0.0. - [Release notes](https://github.com/antfu/eslint-config/releases) - [Commits](https://github.com/antfu/eslint-config/compare/v9.5.1...v10.0.0) --- updated-dependencies: - dependency-name: "@antfu/eslint-config" dependency-version: 10.0.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * chore(frontend): migrate formatting to ESLint v10 Co-authored-by: Codex <noreply@openai.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Zyy <zyycn@users.noreply.github.com> Co-authored-by: Codex <noreply@openai.com>
94 lines
2.4 KiB
TypeScript
94 lines
2.4 KiB
TypeScript
import { locale } from '@/i18n'
|
|
|
|
export function numberLocale() {
|
|
return locale.value === 'en'
|
|
? 'en-US'
|
|
: locale.value
|
|
}
|
|
|
|
const metricUnits = [
|
|
['P', 1_000_000_000_000_000],
|
|
['T', 1_000_000_000_000],
|
|
['B', 1_000_000_000],
|
|
['M', 1_000_000],
|
|
['K', 1_000],
|
|
] as const
|
|
|
|
export function formatInteger(value: number) {
|
|
return new Intl.NumberFormat(numberLocale()).format(value)
|
|
}
|
|
|
|
export function formatLocalizedCompactNumber(value: number) {
|
|
return new Intl.NumberFormat(numberLocale(), {
|
|
notation: 'compact',
|
|
maximumFractionDigits: 1,
|
|
}).format(Number.isFinite(value)
|
|
? value
|
|
: 0)
|
|
}
|
|
|
|
export function formatCompactNumber(value: number) {
|
|
const normalized = Math.max(0, Math.round(value))
|
|
if (normalized < 1_000)
|
|
return formatInteger(normalized)
|
|
|
|
for (const [unit, threshold] of metricUnits) {
|
|
if (normalized < threshold)
|
|
continue
|
|
|
|
const scaled = normalized / threshold
|
|
const rounded = scaled >= 10
|
|
? scaled.toFixed(1)
|
|
: scaled.toFixed(2)
|
|
return `${rounded.replace(/\.?0+$/, '')}${unit}`
|
|
}
|
|
|
|
return formatInteger(normalized)
|
|
}
|
|
|
|
export function formatPercent(value?: number | null) {
|
|
return value == null || !Number.isFinite(value)
|
|
? '—'
|
|
: new Intl.NumberFormat(numberLocale(), { style: 'percent', maximumFractionDigits: 1 }).format(value)
|
|
}
|
|
|
|
export function formatDuration(value?: number | null) {
|
|
if (value == null || !Number.isFinite(value) || value < 0)
|
|
return '—'
|
|
if (value < 1_000)
|
|
return `${Math.round(value)} ms`
|
|
if (value < 60_000) {
|
|
const seconds = value / 1_000
|
|
return `${seconds.toFixed(seconds >= 10
|
|
? 1
|
|
: 2).replace(/\.0+$|(?<=\.\d)0$/, '')} s`
|
|
}
|
|
return `${(value / 60_000).toFixed(1).replace(/\.0$/, '')} min`
|
|
}
|
|
|
|
export function decimalDisplayNumber(value?: string | number | null) {
|
|
if (value == null)
|
|
return null
|
|
const parsed = typeof value === 'number'
|
|
? value
|
|
: Number(value)
|
|
return Number.isFinite(parsed)
|
|
? parsed
|
|
: null
|
|
}
|
|
|
|
export function formatUsd(value?: string | number | null, precise = false) {
|
|
const parsed = decimalDisplayNumber(value)
|
|
if (parsed == null)
|
|
return '—'
|
|
const fractionDigits = precise || (Math.abs(parsed) > 0 && Math.abs(parsed) < 0.01)
|
|
? 4
|
|
: 2
|
|
return new Intl.NumberFormat('en-US', {
|
|
style: 'currency',
|
|
currency: 'USD',
|
|
minimumFractionDigits: fractionDigits,
|
|
maximumFractionDigits: fractionDigits,
|
|
}).format(parsed)
|
|
}
|