Add CNY currency support

This commit is contained in:
Misaka 2026-06-03 10:45:39 +08:00
parent f748d3463b
commit 906c5338e4
5 changed files with 10 additions and 2 deletions

View file

@ -281,6 +281,7 @@ Subscription tracking for Claude Pro, Claude Max, Cursor Pro, and custom provide
codeburn currency GBP # set to British Pounds codeburn currency GBP # set to British Pounds
codeburn currency AUD # set to Australian Dollars codeburn currency AUD # set to Australian Dollars
codeburn currency JPY # set to Japanese Yen codeburn currency JPY # set to Japanese Yen
codeburn currency CNY # set to Chinese Yuan
codeburn currency # show current setting codeburn currency # show current setting
codeburn currency --reset # back to USD codeburn currency --reset # back to USD
``` ```

View file

@ -991,7 +991,7 @@ final class AppStore {
} }
enum SupportedCurrency: String, CaseIterable, Identifiable { enum SupportedCurrency: String, CaseIterable, Identifiable {
case USD, GBP, EUR, AUD, CAD, NZD, JPY, CHF, INR, BRL, SEK, SGD, HKD, KRW, MXN, ZAR, DKK case USD, GBP, EUR, AUD, CAD, NZD, JPY, CNY, CHF, INR, BRL, SEK, SGD, HKD, KRW, MXN, ZAR, DKK
var id: String { rawValue } var id: String { rawValue }
var displayName: String { var displayName: String {
switch self { switch self {
@ -1002,6 +1002,7 @@ enum SupportedCurrency: String, CaseIterable, Identifiable {
case .CAD: "Canadian Dollar" case .CAD: "Canadian Dollar"
case .NZD: "New Zealand Dollar" case .NZD: "New Zealand Dollar"
case .JPY: "Japanese Yen" case .JPY: "Japanese Yen"
case .CNY: "Chinese Yuan"
case .CHF: "Swiss Franc" case .CHF: "Swiss Franc"
case .INR: "Indian Rupee" case .INR: "Indian Rupee"
case .BRL: "Brazilian Real" case .BRL: "Brazilian Real"

View file

@ -36,7 +36,7 @@ private struct GeneralSettingsTab: View {
get: { store.currency }, get: { store.currency },
set: { applyCurrency(code: $0) } set: { applyCurrency(code: $0) }
)) { )) {
ForEach(["USD", "EUR", "GBP", "INR", "JPY", "AUD", "CAD"], id: \.self) { code in ForEach(["USD", "EUR", "GBP", "INR", "JPY", "CNY", "AUD", "CAD"], id: \.self) { code in
Text(code).tag(code) Text(code).tag(code)
} }
} }

View file

@ -27,6 +27,9 @@ function isValidRate(value: unknown): value is number {
let active: CurrencyState = { code: 'USD', rate: 1, symbol: '$' } let active: CurrencyState = { code: 'USD', rate: 1, symbol: '$' }
const USD: CurrencyState = { code: 'USD', rate: 1, symbol: '$' } const USD: CurrencyState = { code: 'USD', rate: 1, symbol: '$' }
const SYMBOL_OVERRIDES: Record<string, string> = {
CNY: '¥',
}
// Intl.NumberFormat throws on invalid ISO 4217 codes, so we use it as a validator // Intl.NumberFormat throws on invalid ISO 4217 codes, so we use it as a validator
export function isValidCurrencyCode(code: string): boolean { export function isValidCurrencyCode(code: string): boolean {
@ -39,6 +42,8 @@ export function isValidCurrencyCode(code: string): boolean {
} }
function resolveSymbol(code: string): string { function resolveSymbol(code: string): string {
if (SYMBOL_OVERRIDES[code]) return SYMBOL_OVERRIDES[code]
const parts = new Intl.NumberFormat('en', { const parts = new Intl.NumberFormat('en', {
style: 'currency', style: 'currency',
currency: code, currency: code,

View file

@ -100,5 +100,6 @@ describe('getFractionDigits', () => {
expect(getFractionDigits('EUR')).toBe(2) expect(getFractionDigits('EUR')).toBe(2)
expect(getFractionDigits('GBP')).toBe(2) expect(getFractionDigits('GBP')).toBe(2)
expect(getFractionDigits('INR')).toBe(2) expect(getFractionDigits('INR')).toBe(2)
expect(getFractionDigits('CNY')).toBe(2)
}) })
}) })