Skip to content

Commit aac6206

Browse files
committed
translation tasks
1 parent b2b7a8e commit aac6206

File tree

10 files changed

+811
-142
lines changed

10 files changed

+811
-142
lines changed

App/Lib/DateUtil.js

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import Locale from '../Locale';
2+
3+
var i18nLib = Locale.lib();
4+
5+
global._Date = global._Date || Date;
6+
7+
var DateUtil = {
8+
// localEpoch: function(epochSeconds) {
9+
// var d = new Date(0); // The 0 there is the key, which sets the date to the epoch
10+
// d.setUTCSeconds(epochSeconds);
11+
// return d;
12+
// },
13+
14+
now: function() {
15+
return new _Date();
16+
},
17+
18+
minutes: function(number) {
19+
return number * 60 * 1000;
20+
},
21+
22+
hours: function(number) {
23+
return number * this.minutes(60);
24+
},
25+
26+
days: function(number) {
27+
return number * this.hours(24);
28+
},
29+
30+
timeAgoInWords: function(milliseconds) {
31+
if (milliseconds < (new Date('January 01, 1970 00:00:00')).getTime()) {
32+
console.warn('timeAgoInSeconds requires milliseconds >= Epoch');
33+
return null;
34+
}
35+
const now = this.now().getTime(),
36+
minutesAgo = Math.floor((now - milliseconds) / 1000 / 60);
37+
38+
if (minutesAgo < 1) return i18n.t('time_ago_less_than');
39+
if (minutesAgo === 1) return i18n.t('time_ago_min');
40+
if (minutesAgo < 60) return i18n.t('time_ago_mins', {minutes: minutesAgo});
41+
42+
const hoursAgo = Math.floor(minutesAgo / 60);
43+
if (hoursAgo === 1) return i18n.t('time_ago_hour');
44+
if (hoursAgo < 24) return i18n.t('time_ago_hours', {hours: hoursAgo});
45+
46+
const daysAgo = Math.floor(hoursAgo / 24);
47+
if (daysAgo === 1) return i18n.t('time_ago_day');
48+
if (daysAgo < 7) return i18n.t('time_ago_days', {days: daysAgo});
49+
50+
const weeksAgo = Math.floor(daysAgo / 7);
51+
if (weeksAgo === 1) return i18n.t('time_ago_week');
52+
return i18n.t('time_ago_weeks', {weeks: weeksAgo});
53+
},
54+
55+
isToday(date) {
56+
var parsedDate = this.parse(date);
57+
if (!parsedDate) return false;
58+
59+
return parsedDate.toDateString() === this.now().toDateString();
60+
},
61+
62+
isPast(date) {
63+
var parsedDate = this.parse(date);
64+
if (!parsedDate) return false;
65+
66+
return parsedDate < this.now();
67+
},
68+
69+
isFuture(date) {
70+
return !this.isPast(date);
71+
},
72+
73+
// use this one instead of strftime, please. it's better for i18n
74+
format: function(date, name) {
75+
var pattern = i18nLib.t('datetime.' + name);
76+
return this.strftime(date, pattern);
77+
},
78+
79+
// strftime stuff we support:
80+
// https://github.com/fnando/i18n-js#date-formatting
81+
// %+A : Today, Tomorrow, Monday
82+
strftime: function(date, pattern) {
83+
date = this.parse(date);
84+
if (!date) return null;
85+
86+
if (pattern.indexOf('%+A') >= 0) {
87+
// %+A : Today, Tomorrow, Monday
88+
var dayName = '%A'; // normal one
89+
var today = new _Date();
90+
var tomorrow = new _Date();
91+
tomorrow.setDate(tomorrow.getDate() + 1);
92+
93+
if (date.toDateString() === today.toDateString()) {
94+
dayName = i18n.t('today');
95+
}
96+
else if (date.toDateString() === tomorrow.toDateString()) {
97+
dayName = i18n.t('tomorrow');
98+
}
99+
100+
pattern = pattern.replace(/%\+A/g, dayName);
101+
}
102+
103+
return i18nLib.strftime(date, pattern);
104+
},
105+
106+
localISOString: function(date) {
107+
var d = this.parse(date);
108+
d.setHours(0, -d.getTimezoneOffset(), 0, 0);
109+
110+
return d.toISOString().slice(0, 10);
111+
},
112+
113+
dayWindowName: function(date) {
114+
date = this.parse(date);
115+
if (!date) return null;
116+
117+
var hour = date.getHours();
118+
if (hour < 12) {
119+
return i18n.t('morning');
120+
}
121+
else if (hour < 16) {
122+
return i18n.t('afternoon');
123+
}
124+
else {
125+
return i18n.t('evening');
126+
}
127+
},
128+
129+
parse: function(intOrDateOrString) {
130+
if (intOrDateOrString === null) return null;
131+
132+
// have to know if it's an number if it's in millseconds or seconds
133+
if (typeof intOrDateOrString === 'number') {
134+
// using number of digits to decide (12 digits is 1973)
135+
if (intOrDateOrString.toString().length <= 12) {
136+
intOrDateOrString = intOrDateOrString * 1000;
137+
}
138+
}
139+
return i18nLib.parseDate(intOrDateOrString);
140+
},
141+
142+
toEpoch: function(intOrDateOrString) {
143+
var date = this.parse(intOrDateOrString);
144+
if (date === null) return null;
145+
146+
return Math.round(date.getTime() / 1000);
147+
},
148+
};
149+
150+
var i18n = Locale.key('DateUtil', {
151+
morning: 'Morning',
152+
afternoon: 'Afternoon',
153+
evening: 'Evening',
154+
today: 'Today',
155+
tomorrow: 'Tomorrow',
156+
time_ago_less_than: 'less than 1 min ago',
157+
time_ago_min: '1 min ago',
158+
time_ago_mins: '%{minutes} mins ago',
159+
time_ago_hour: '1 hour ago',
160+
time_ago_hours: '%{hours} hours ago',
161+
time_ago_day: '1 day ago',
162+
time_ago_days: '%{days} days ago',
163+
time_ago_week: '1 week ago',
164+
time_ago_weeks: '%{weeks} weeks ago',
165+
});
166+
167+
export default DateUtil;

App/Locales/en-GB-xtra.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
export default {
1+
// Programatic GB translations - do not add directly
2+
// Use npm run translation:backfill
23

3-
};
4+
export default {};

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
"mocha-test": "mocha --recursive --compilers js:babel-core/register",
99
"compile:test": "TARGET=test node tasks/compile.js",
1010
"compile:staging": "TARGET=staging node tasks/compile.js",
11-
"install:staging": "PHONE=true TARGET=staging node tasks/compile.js"
11+
"install:staging": "PHONE=true TARGET=staging node tasks/compile.js",
12+
"translation:dump": "ACTION=dump node tasks/translation.js",
13+
"translation:backfill": "ACTION=backfill node tasks/translation.js",
14+
"translation:times": "ACTION=times node tasks/translation.js",
15+
"translation:check": "ACTION=check node tasks/translation.js"
1216
},
1317
"dependencies": {
1418
"events": "1.1.0",
@@ -22,7 +26,9 @@
2226
"react": "15.3.1",
2327
"react-native": "0.33.0",
2428
"react-native-keychain": "0.2.6",
29+
"react-native-mock": "0.2.7",
2530
"react-timer-mixin": "0.13.3",
31+
"require-all": "2.0.0",
2632
"superagent": "1.8.3",
2733
"underscore": "1.8.3",
2834
"underscore.string": "3.2.2"

tasks/_compiler.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
var child_process = require("child_process");
2+
var path = require("path")
3+
4+
var Compiler = function(platform, environment, console) {
5+
this.platform = platform;
6+
this.environment = environment;
7+
this.console = console;
8+
9+
this.calculateDirectories();
10+
};
11+
12+
Compiler.prototype.log = function(toLog) {
13+
//this.console.log.writeln(toLog);
14+
this.console.log(toLog);
15+
};
16+
17+
Compiler.prototype.run = function(toRun) {
18+
this.log('------------------')
19+
this.log(toRun);
20+
this.log('->')
21+
var out = child_process.execSync(toRun);
22+
this.log('' + out);
23+
this.log('------------------')
24+
return out;
25+
};
26+
27+
Compiler.prototype.calculateDirectories = function() {
28+
this.rootDirectory = process.cwd();
29+
this.platformDirectory = this.rootDirectory + '/' + this.platform;
30+
this.appDirectory = this.rootDirectory + '/testbuild/' + this.environment + '_' + this.platform;
31+
this.buildDirectory = this.appDirectory + '/build';
32+
33+
switch(this.environment) {
34+
case 'test':
35+
this.configuration = "Debug";
36+
this.iosSdk = "iphonesimulator";
37+
this.iosDestination = "platform=iOS Simulator,name=iPhone 6s,OS=latest"
38+
break;
39+
case 'staging':
40+
this.configuration = "Staging";
41+
this.iosSdk = "iphoneos";
42+
break;
43+
default:
44+
throw("UNKNOWN ENVIRONMENT: " + this.environment);
45+
}
46+
47+
this.compiledApp = this.buildDirectory;
48+
49+
if (this.platform === 'android') {
50+
// TODO
51+
}
52+
else {
53+
this.compiledApp += '/' + this.configuration + '-' + this.iosSdk + '/Sample.app';
54+
}
55+
56+
this.zippedApp = this.appDirectory;
57+
if (this.platform === 'android') {
58+
this.zippedApp += '/sample_android.apk';
59+
}
60+
else {
61+
this.zippedApp += '/sample_ios.zip';
62+
}
63+
};
64+
65+
Compiler.prototype.cleanDirectory = function() {
66+
this.log('cleaning: ' + this.appDirectory);
67+
this.run('rm -rf ' + this.appDirectory);
68+
};
69+
70+
Compiler.prototype.buildJavascript = function() {
71+
var pwd = this.rootDirectory;
72+
var to_run = 'cd ' + pwd;
73+
to_run += " && react-native bundle --minify"
74+
this.run(to_run);
75+
};
76+
77+
Compiler.prototype.buildIos = function() {
78+
var env, scheme, config, sdk;
79+
switch(this.environment) {
80+
case 'test':
81+
env = "TEST_ENVIRONMENT=1";
82+
scheme = "Sample Test";
83+
break;
84+
case 'staging':
85+
env = "STAGING_ENVIRONMENT=1";
86+
scheme = "Sample Staging";
87+
break;
88+
default:
89+
throw("UNKNOWN ENVIRONMENT: " + this.environment);
90+
}
91+
92+
var to_run = 'xcodebuild';
93+
to_run += " GCC_PREPROCESSOR_DEFINITIONS='$GCC_PREPROCESSOR_DEFINITIONS " + env + "'"
94+
to_run += " -workspace " + this.platformDirectory + "/Sample.xcworkspace";
95+
to_run += " -scheme \"" + scheme + "\"";
96+
to_run += " -sdk " + this.iosSdk;
97+
if (this.iosDestination) to_run += " -destination '" + this.iosDestination + "'";
98+
to_run += " -configuration " + this.configuration;
99+
to_run += " OBJROOT=" + this.buildDirectory;
100+
to_run += " SYMROOT=" + this.buildDirectory;
101+
to_run += " ONLY_ACTIVE_ARCH=NO";
102+
to_run += " | xcpretty -c && exit ${PIPESTATUS[0]}";
103+
this.run(to_run)
104+
};
105+
106+
Compiler.prototype.build = function() {
107+
this.run('mkdir -p ' + this.buildDirectory);
108+
109+
if (this.environment !== 'test') {
110+
this.buildJavascript();
111+
}
112+
this.buildIos();
113+
};
114+
115+
Compiler.prototype.zipIos = function() {
116+
var parent_dir = path.dirname(this.compiledApp);
117+
var pwd = this.rootDirectory;
118+
var to_run = "cd " + parent_dir;
119+
to_run += " && zip -r " + this.zippedApp + " " + this.compiledApp;
120+
to_run += " && cd " + pwd;
121+
this.run(to_run);
122+
};
123+
124+
Compiler.prototype.zip = function() {
125+
this.zipIos();
126+
};
127+
128+
Compiler.prototype.phoneInstall = function() {
129+
// ios-deploy testbuild/staging_ios/build/Staging-iphoneos/Sample.app
130+
var to_run = "ios-deploy";
131+
//to_run += " --justlaunch";
132+
//to_run += " --debug";
133+
to_run += " --bundle \"" + this.compiledApp + "\"";
134+
135+
this.run(to_run);
136+
};
137+
138+
// TODO: copySauce
139+
140+
module.exports = Compiler;

0 commit comments

Comments
 (0)