Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I18n support + french translations #14

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,15 @@ In your component templates you can just do:
```
<span>{{your_date | timeAgo}}</span>
```
where "your_date" is a local date string, which could be parsed by the standard Js Date()

## i18n

Only English and French are supported.

To use french translations you can just do:

```
<span>{{your_date | timeAgo:'fr'}}</span>
```
where "your_date" is a local date string, which could be parsed by the standard Js Date()
11 changes: 11 additions & 0 deletions test/time-ago-pipe.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ describe('time-ago-pipe', () => {
}
}
});

it('\'a few seconds ago\' in fr tests', () => {
var pastDate = new Date();
for (let i =0; i < 45; i++){
clock.tick(oneSec);
if (i < 44) {
expect(pipe.transform(pastDate.toString(), 'fr')).to.equal('il y a quelques secondes');
}
}
});

it('\'a minute ago\' tests', () => {
var pastDate = new Date();
clock.tick(oneSec * 45);
Expand Down
33 changes: 33 additions & 0 deletions test/translate.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
var expect = require('chai').expect;
var sinon = require('sinon');
import {Translate} from '../translate';


describe('translate', () => {


describe('translate function', function () {

let translate = new Translate();

it('should translate a message without parameters', () => {

expect(translate.translate('fr', 'a few seconds ago')).to.equal('il y a quelques secondes');

});

it('should translate a message with parameters', () => {

expect(translate.translate('fr', 'seconds ago', {seconds: 20})).to.equal('il y a 20 secondes');

});

it('should return the message key if translation cannot be found', () => {

expect(translate.translate('de', 'seconds ago')).to.equal('seconds ago');

});

});

});
59 changes: 35 additions & 24 deletions time-ago-pipe.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import {Pipe, PipeTransform, NgZone, ChangeDetectorRef, OnDestroy} from "@angular/core";
import {Translate} from './translate';
@Pipe({
name:'timeAgo',
pure:false
})
export class TimeAgoPipe implements PipeTransform, OnDestroy {
private timer: number;
private translate: Translate = new Translate();

constructor(private changeDetectorRef: ChangeDetectorRef, private ngZone: NgZone) {}
transform(value:string) {
transform(value:string, locale?: string) {
this.removeTimer();
let d = new Date(value);
let now = new Date();
Expand All @@ -20,35 +23,43 @@ export class TimeAgoPipe implements PipeTransform, OnDestroy {
}
return null;
});

return this.getI18nMessage(seconds, locale || 'en');
}

getI18nMessage(seconds:number, locale: string) {
let minutes = Math.round(Math.abs(seconds / 60));
let hours = Math.round(Math.abs(minutes / 60));
let days = Math.round(Math.abs(hours / 24));
let months = Math.round(Math.abs(days/30.416));
let years = Math.round(Math.abs(days/365));
if (seconds <= 45) {
return 'a few seconds ago';
} else if (seconds <= 90) {
return 'a minute ago';
} else if (minutes <= 45) {
return minutes + ' minutes ago';
} else if (minutes <= 90) {
return 'an hour ago';
} else if (hours <= 22) {
return hours + ' hours ago';
} else if (hours <= 36) {
return 'a day ago';
} else if (days <= 25) {
return days + ' days ago';
} else if (days <= 45) {
return 'a month ago';
} else if (days <= 345) {
return months + ' months ago';
} else if (days <= 545) {
return 'a year ago';
} else { // (days > 545)
return years + ' years ago';
}


if (seconds <= 45) {
return this.translate.translate(locale, 'a few seconds ago');
} else if (seconds <= 90) {
return this.translate.translate(locale, 'a minute ago');
} else if (minutes <= 45) {
return this.translate.translate(locale, 'minutes ago', { minutes });
} else if (minutes <= 90) {
return this.translate.translate(locale, 'an hour ago');
} else if (hours <= 22) {
return this.translate.translate(locale, 'hours ago', { hours });
} else if (hours <= 36) {
return this.translate.translate(locale, 'a day ago');
} else if (days <= 25) {
return this.translate.translate(locale, 'days ago', { days });
} else if (days <= 45) {
return this.translate.translate(locale, 'a month ago');
} else if (days <= 345) {
return this.translate.translate(locale, 'months ago', { months });
} else if (days <= 545) {
return this.translate.translate(locale, 'a year ago');
} else { // (days > 545)
return this.translate.translate(locale, 'years ago', { years });
}
}

ngOnDestroy(): void {
this.removeTimer();
}
Expand Down
55 changes: 55 additions & 0 deletions translate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
export class Translate {

private translations: Object = {};

constructor() {
this.translations['en'] = {
'a few seconds ago': 'a few seconds ago',
'seconds ago': (p) => `${p.seconds} seconds ago`,
'a minute ago': 'a minute ago',
'minutes ago': (p) => `${p.minutes} minutes ago`,
'an hour ago': 'an hour ago',
'hours ago': (p) => `${p.hours} hours ago`,
'a day ago': 'a day ago',
'days ago': (p) => `${p.days} days ago`,
'a month ago': 'a month ago',
'months ago': (p) => `${p.months} months ago`,
'a year ago': 'a year ago',
'years ago': (p) => `${p.years} years ago`
};

this.translations['fr'] = {
'a few seconds ago': 'il y a quelques secondes',
'seconds ago': (p) => `il y a ${p.seconds} secondes`,
'a minute ago': 'il y a une minute',
'minutes ago': (p) => `il y a ${p.minutes} minutes`,
'an hour ago': 'il y a une heure',
'hours ago': (p) => `il y a ${p.hours} heures`,
'a day ago': 'hier',
'days ago': (p) => `il y a ${p.days} jours`,
'a month ago': 'il y a un mois',
'months ago': (p) => `il y a ${p.months} mois`,
'a year ago': 'il y a un an',
'years ago': (p) => `il y a ${p.years} ans`
};
}

translate(locale: string, messageKey: string, parameters?: Object): string {

const translationsInLocale = this.translations[locale];

if (translationsInLocale) {
const translation = translationsInLocale[messageKey];

if (translation) {
if (typeof translation == 'function') {
return translation(parameters);
}
return translation;
}
}

return messageKey;
}

}
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"experimentalDecorators": true,
"declaration": true,
"removeComments": false,
"noImplicitAny": false
"noImplicitAny": false,
"lib": ["es2017", "dom"]
},
"angularCompilerOptions": {
"genDir": "compiled"
Expand Down