From 4d7d1a1008202da0256f606f4ef9e42f2bba8484 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 17 Nov 2016 02:58:27 +0100 Subject: [PATCH] implement / fix i18n for JSX --- playground/animation.html | 34 ---------- pogen/pogen.ts | 2 +- src/i18n.tsx | 126 +++++++++++++++++++++++++++++++++----- src/popup/popup.tsx | 12 +++- src/types.ts | 2 +- 5 files changed, 123 insertions(+), 53 deletions(-) delete mode 100644 playground/animation.html diff --git a/playground/animation.html b/playground/animation.html deleted file mode 100644 index 893276b3f..000000000 --- a/playground/animation.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - Spinner playground - - - -
- -
-
-
- -
- - - - diff --git a/pogen/pogen.ts b/pogen/pogen.ts index 1e0467d4e..ae6bbfa0e 100644 --- a/pogen/pogen.ts +++ b/pogen/pogen.ts @@ -198,7 +198,7 @@ export function processFile(sourceFile: ts.SourceFile) { return e.text; } default: - return `%${h[0]++}s`; + return `%{h[0]++}$s`; } } diff --git a/src/i18n.tsx b/src/i18n.tsx index 70e1c3f73..9374efaf0 100644 --- a/src/i18n.tsx +++ b/src/i18n.tsx @@ -207,16 +207,53 @@ i18n.number = function (n : number) { return new PluralNumber (n); }; +function stringifyChildren(children: any): string { + let n = 1; + let ss = React.Children.map(children, (c) => { + if (typeof c === "string") { + return c; + } + return `%${n++}$s`; + }); + return ss.join(""); +} + i18n.Translate = class extends React.Component { render(): JSX.Element { - return
{this.props.children}
; + init(); + if (typeof jed !== "object") { + return
{this.props.children}
; + } + let s = stringifyChildren(this.props.children); + let tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: number) => i % 2 == 0); + let childArray = React.Children.toArray(this.props.children!); + for (let i = 0; i < childArray.length - 1; ++i) { + if ((typeof childArray[i]) == "string" && (typeof childArray[i+1]) == "string") { + childArray[i+i] = childArray[i] as string + childArray[i+1] as string; + childArray.splice(i,1); + } + } + let result = []; + while (childArray.length > 0) { + let x = childArray.shift(); + if (x === undefined) { + continue; + } + if (typeof x === "string") { + let t = tr.shift(); + result.push(t); + } else { + result.push(x); + } + } + return
{result}
; } } i18n.TranslateSwitch = class extends React.Component{ render(): JSX.Element { - let singular; - let plural; + let singular: React.ReactElement | undefined; + let plural: React.ReactElement | undefined; let children = this.props.children; if (children) { React.Children.forEach(children, (child: any) => { @@ -232,30 +269,91 @@ i18n.TranslateSwitch = class extends React.Component{ console.error("translation not found"); return React.createElement("span", {}, ["translation not found"]); } - if (this.props.target == 1) { - return singular; + init(); + singular.props.target = this.props.target; + plural.props.target = this.props.target;; + if (typeof "jed" !== "object") { + if (this.props.target == 1) { + return singular; + } else { + return plural; + } } else { - return plural; + // We're looking up the translation based on the + // singular, even if we must use the plural form. + return singular; } } } interface TranslationProps { - /** - * Substitutions to do for the translation. - */ - subst: {[n: number]: any}; + target: number; } -i18n.TranslatePlural = class extends React.Component{ +class TranslatePlural extends React.Component { render(): JSX.Element { - return
{this.props.children}
; + init(); + if (typeof jed !== "object") { + return
{this.props.children}
; + } + let s = stringifyChildren(this.props.children); + let tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: number) => i % 2 == 0); + let childArray = React.Children.toArray(this.props.children!); + for (let i = 0; i < childArray.length - 1; ++i) { + if ((typeof childArray[i]) == "string" && (typeof childArray[i+1]) == "string") { + childArray[i+i] = childArray[i] as string + childArray[i+1] as string; + childArray.splice(i,1); + } + } + let result = []; + while (childArray.length > 0) { + let x = childArray.shift(); + if (x === undefined) { + continue; + } + if (typeof x === "string") { + let t = tr.shift(); + result.push(t); + } else { + result.push(x); + } + } + return
{result}
; } } -i18n.TranslateSingular = class extends React.Component{ +i18n.TranslatePlural = TranslatePlural; + +class TranslateSingular extends React.Component { render(): JSX.Element { - return
{this.props.children}
; + init(); + if (typeof jed !== "object") { + return
{this.props.children}
; + } + let s = stringifyChildren(this.props.children); + let tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: number) => i % 2 == 0); + let childArray = React.Children.toArray(this.props.children!); + for (let i = 0; i < childArray.length - 1; ++i) { + if ((typeof childArray[i]) == "string" && (typeof childArray[i+1]) == "string") { + childArray[i+i] = childArray[i] as string + childArray[i+1] as string; + childArray.splice(i,1); + } + } + let result = []; + while (childArray.length > 0) { + let x = childArray.shift(); + if (x === undefined) { + continue; + } + if (typeof x === "string") { + let t = tr.shift(); + result.push(t); + } else { + result.push(x); + } + } + return
{result}
; } } +i18n.TranslateSingular = TranslateSingular; diff --git a/src/popup/popup.tsx b/src/popup/popup.tsx index 697162cab..d85395625 100644 --- a/src/popup/popup.tsx +++ b/src/popup/popup.tsx @@ -239,9 +239,15 @@ class WalletBalanceView extends React.Component { help ); - return
You have no balance to show. Need some - {" "}{helpLink}{" "} - getting started?
; + return ( +
+ + You have no balance to show. Need some + {" "}{helpLink}{" "} + getting started? + +
+ ); } formatPending(entry: WalletBalanceEntry): JSX.Element { diff --git a/src/types.ts b/src/types.ts index 9de769dfe..b04453767 100644 --- a/src/types.ts +++ b/src/types.ts @@ -509,7 +509,7 @@ export type PayCoinInfo = Array<{ updatedCoin: CoinRecord, sig: CoinPaySig }>; export namespace Amounts { - export const fractionalBase = 1e6; + export const fractionalBase = 1e8; export interface Result { amount: AmountJson;