Skip to content
This repository was archived by the owner on Feb 6, 2024. It is now read-only.

Commit f054e56

Browse files
Merge pull request #1093 from deckgo/i18n
feat: i18n
2 parents fd63b13 + 946228c commit f054e56

File tree

104 files changed

+2149
-731
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+2149
-731
lines changed

studio/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
"dist/"
99
],
1010
"scripts": {
11-
"prebuild": "node ./scripts/rm-www.js",
11+
"clean": "node ./scripts/rm-www.js",
12+
"i18n": "node ./scripts/i18n.types.js",
13+
"prebuild": "npm run clean && npm run i18n",
1214
"build": "stencil build",
1315
"build:staging": "npm run build -- --staging",
1416
"postbuild": "./scripts/config.index.js",

studio/scripts/i18n.types.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const {writeFileSync, readFileSync} = require('fs');
2+
3+
const prettier = require('prettier');
4+
5+
const generate = async () => {
6+
const buffer = readFileSync('./src/assets/i18n/en.json');
7+
const i18n = JSON.parse(buffer.toString());
8+
9+
const data = Object.keys(i18n).map((key) => {
10+
const properties = Object.keys(i18n[key]).map((prop) => `${prop}: string;`);
11+
12+
return {
13+
key,
14+
name: `I18n${key.charAt(0).toUpperCase()}${key.slice(1)}`,
15+
properties,
16+
};
17+
});
18+
19+
const lang = `lang: 'en';`;
20+
21+
const main = `\n\ninterface I18n {${lang}${data.map((i) => `${i.key}: ${i.name};`).join('')}}`;
22+
const interfaces = data.map((i) => `\n\ninterface ${i.name} {${i.properties.join('')}}`).join('');
23+
24+
const output = prettier.format(`${interfaces}${main}`, {semi: false, parser: 'babel', singleQuote: true});
25+
26+
writeFileSync('./src/app/definitions/i18.d.ts', output);
27+
};
28+
29+
(async () => {
30+
try {
31+
await generate();
32+
33+
console.log(`i18n type declarations generated!`);
34+
} catch (err) {
35+
console.error(`Error while generating i18n types.`, err);
36+
}
37+
})();

studio/src/app/components/core/app-footer/app-links.tsx

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {Component, h} from '@stencil/core';
22

3+
import i18n from '../../../stores/i18n.store';
4+
35
@Component({
46
tag: 'app-links',
57
styleUrl: 'app-links.scss',
@@ -13,78 +15,79 @@ export class AppLinks {
1315
<ion-label class="ion-padding-top">DeckDeckGo</ion-label>
1416

1517
<a href="https://deckdeckgo.com/en/" rel="noopener norefferer" target="_blank">
16-
<ion-label>Home</ion-label>
18+
<ion-label>{i18n.state.links.home}</ion-label>
1719
</a>
1820

1921
<a href="https://deckdeckgo.com/en/discover" rel="noopener norefferer" target="_blank">
20-
<ion-label>Discover</ion-label>
22+
<ion-label>{i18n.state.links.discover}</ion-label>
2123
</a>
2224

2325
<a href="https://deckdeckgo.com/en/enterprise" rel="noopener norefferer" target="_blank">
24-
<ion-label>Enterprise</ion-label>
26+
<ion-label>{i18n.state.links.enterprise}</ion-label>
2527
</a>
2628

2729
<a href="https://deckdeckgo.com/en/about" rel="noopener norefferer" target="_blank">
28-
<ion-label>About</ion-label>
30+
<ion-label>{i18n.state.links.about}</ion-label>
2931
</a>
3032

3133
<a href="https://deckdeckgo.com/en/team" rel="noopener norefferer" target="_blank">
32-
<ion-label>Team</ion-label>
34+
<ion-label>{i18n.state.links.team}</ion-label>
3335
</a>
3436

3537
<a href="https://deckdeckgo.com/en/newsletter" rel="noopener norefferer" target="_blank">
36-
<ion-label>Newsletter</ion-label>
38+
<ion-label>{i18n.state.links.newsletter}</ion-label>
3739
</a>
3840

3941
<a href="https://deckdeckgo.com/en/contact" rel="noopener norefferer" target="_blank">
40-
<ion-label>Contact</ion-label>
42+
<ion-label>{i18n.state.links.contact}</ion-label>
4143
</a>
4244

4345
<a href="https://deckdeckgo.com/en/press" rel="noopener norefferer" target="_blank">
44-
<ion-label>Press</ion-label>
46+
<ion-label>{i18n.state.links.press}</ion-label>
4547
</a>
4648

4749
<a href="https://deckdeckgo.com/en/faq" rel="noopener norefferer" target="_blank">
48-
<ion-label>FAQ</ion-label>
50+
<ion-label>{i18n.state.links.faq}</ion-label>
4951
</a>
5052
</section>
5153

5254
<section>
53-
<ion-label class="ion-padding-top">Developers</ion-label>
55+
<ion-label class="ion-padding-top">{i18n.state.links.developers}</ion-label>
5456

5557
<a href="https://deckdeckgo.com/en/opensource" rel="noopener norefferer" target="_blank">
56-
<ion-label>Open source</ion-label>
58+
<ion-label>{i18n.state.links.open_source}</ion-label>
5759
</a>
5860

5961
<a href="https://deckdeckgo.com/en/services" rel="noopener norefferer" target="_blank">
60-
<ion-label>Services</ion-label>
62+
<ion-label>{i18n.state.links.services}</ion-label>
6163
</a>
6264

6365
<a href="https://deckdeckgo.com/en/developer" rel="noopener norefferer" target="_blank">
64-
<ion-label>Developer</ion-label>
66+
<ion-label>{i18n.state.links.developer}</ion-label>
6567
</a>
6668
</section>
6769

6870
<section>
69-
<ion-label class="ion-padding-top">Terms</ion-label>
71+
<ion-label class="ion-padding-top">{i18n.state.links.terms}</ion-label>
7072

7173
<a href="https://deckdeckgo.com/terms" rel="noopener norefferer" target="_blank">
72-
<ion-label>Terms of use</ion-label>
74+
<ion-label>{i18n.state.links.terms_of_use}</ion-label>
7375
</a>
7476

7577
<a href="https://deckdeckgo.com/privacy" rel="noopener norefferer" target="_blank">
76-
<ion-label>Privacy Policy</ion-label>
78+
<ion-label>{i18n.state.links.privacy_policy}</ion-label>
7779
</a>
7880
</section>
7981

8082
<div class="social ion-padding-top ion-margin-top">
81-
<a href="https://twitter.com/deckdeckgo" rel="noopener norefferer" target="_blank">
83+
<a href="https://twitter.com/deckdeckgo" rel="noopener norefferer" target="_blank" aria-label="Twitter">
8284
<ion-icon name="logo-twitter"></ion-icon>
8385
</a>
84-
<a href="https://github.com/deckgo" rel="noopener noreferrer">
86+
<a href="https://github.com/deckgo" rel="noopener noreferrer" aria-label="GitHub">
8587
<ion-icon name="logo-github"></ion-icon>
8688
</a>
8789
<a
90+
aria-label="Slack"
8891
href="https://join.slack.com/t/deckdeckgo/shared_invite/enQtNzM0NjMwOTc3NTI0LTBlNmFhODNhYmRkMWUxZmU4ZTQ2MDJiNjlmYWZiODNjMDU5OGRjYThlZmZjMTc5YmQ3MzUzMDlhMzk0ZDgzMDY"
8992
rel="noopener noreferrer">
9093
<ion-icon name="logo-slack"></ion-icon>

studio/src/app/components/core/app-menu/app-menu.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ import {Component, Element, Fragment, h} from '@stencil/core';
22

33
import navStore from '../../../stores/nav.store';
44
import authStore from '../../../stores/auth.store';
5+
import {NavDirection} from '../../../stores/nav.store';
6+
import i18n from '../../../stores/i18n.store';
57

68
import {signIn} from '../../../utils/core/signin.utils';
79

810
import {AuthService} from '../../../services/auth/auth.service';
9-
import {NavDirection} from '../../../stores/nav.store';
1011

1112
@Component({
1213
tag: 'app-menu',
@@ -66,7 +67,7 @@ export class AppMenu {
6667
return (
6768
<ion-item button class="home" href="/dashboard" routerDirection="forward">
6869
<ion-icon lazy={true} name="apps-outline" slot="start"></ion-icon>
69-
<ion-label>Dashboard</ion-label>
70+
<ion-label>{i18n.state.menu.dashboard}</ion-label>
7071
</ion-item>
7172
);
7273
}
@@ -76,14 +77,14 @@ export class AppMenu {
7677
return (
7778
<ion-item button class="signout" onClick={() => this.signOut()}>
7879
<ion-icon lazy={true} name="log-out-outline" slot="start" style={{transform: 'translate(3px, 0px)'}}></ion-icon>
79-
<ion-label>Sign out</ion-label>
80+
<ion-label>{i18n.state.nav.sign_out}</ion-label>
8081
</ion-item>
8182
);
8283
} else {
8384
return (
8485
<ion-item button onClick={() => this.signIn()}>
8586
<ion-icon lazy={true} name="log-in-outline" slot="start" style={{transform: 'translate(-3px, 0px)'}}></ion-icon>
86-
<ion-label>Sign in</ion-label>
87+
<ion-label>{i18n.state.nav.sign_in}</ion-label>
8788
</ion-item>
8889
);
8990
}
@@ -94,12 +95,12 @@ export class AppMenu {
9495
<Fragment>
9596
<ion-item button class="home" href="/poll" routerDirection="forward">
9697
<ion-icon lazy={true} name="chatbubble-ellipses-outline" slot="start"></ion-icon>
97-
<ion-label>Poll</ion-label>
98+
<ion-label>{i18n.state.menu.poll}</ion-label>
9899
</ion-item>
99100

100101
<ion-item button class="home remote" href="https://deckdeckgo.app" target="_blank">
101102
<ion-icon lazy={true} name="phone-portrait-outline" slot="start"></ion-icon>
102-
<ion-label>Remote control</ion-label>
103+
<ion-label>{i18n.state.menu.remote_control}</ion-label>
103104
</ion-item>
104105
</Fragment>
105106
);
@@ -113,15 +114,15 @@ export class AppMenu {
113114

114115
<ion-list class="settings">
115116
<ion-item button class="home" href="/profile" routerDirection="forward">
116-
<ion-label>Profile</ion-label>
117+
<ion-label>{i18n.state.nav.profile}</ion-label>
117118
<ion-icon lazy={true} name="person-outline" slot="start"></ion-icon>
118119
</ion-item>
119120
<ion-item button class="home" href="/customization" routerDirection="forward">
120-
<ion-label>Customization</ion-label>
121+
<ion-label>{i18n.state.nav.customization}</ion-label>
121122
<ion-icon lazy={true} name="color-palette-outline" slot="start"></ion-icon>
122123
</ion-item>
123124
<ion-item button class="home" href="/templates" routerDirection="forward">
124-
<ion-label>Templates</ion-label>
125+
<ion-label>{i18n.state.nav.templates}</ion-label>
125126
<ion-icon lazy={true} name="reader-outline" slot="start"></ion-icon>
126127
</ion-item>
127128
</ion-list>

studio/src/app/components/core/app-navigation-actions/app-navigation-actions.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {popoverController} from '@ionic/core';
55
import themeStore from '../../../stores/theme.store';
66
import authStore from '../../../stores/auth.store';
77
import userStore from '../../../stores/user.store';
8+
import i18n from '../../../stores/i18n.store';
89

910
import {signIn} from '../../../utils/core/signin.utils';
1011

@@ -47,7 +48,7 @@ export class AppNavigationActions {
4748
} else if (this.presentation || this.publish) {
4849
return (
4950
<button class="wide-device ion-padding-start ion-padding-end signin" onClick={() => signIn()} tabindex={0}>
50-
<ion-label>Sign in</ion-label>
51+
<ion-label>{i18n.state.nav.sign_in}</ion-label>
5152
</button>
5253
);
5354
}
@@ -56,7 +57,7 @@ export class AppNavigationActions {
5657
private renderLoggedIn() {
5758
if (authStore.state.loggedIn && userStore.state.loaded) {
5859
return (
59-
<button class="ion-padding-end" onClick={(e: UIEvent) => this.openMenu(e)} aria-label="Open menu" tabindex={0}>
60+
<button class="ion-padding-end" onClick={(e: UIEvent) => this.openMenu(e)} aria-label={i18n.state.nav.menu} tabindex={0}>
6061
<app-avatar src={userStore.state.photoUrl}></app-avatar>
6162
</button>
6263
);
@@ -75,7 +76,7 @@ export class AppNavigationActions {
7576
routerDirection="root"
7677
mode="md"
7778
color={themeStore.state.darkTheme ? 'light' : 'dark'}>
78-
<ion-label>Write a presentation</ion-label>
79+
<ion-label>{i18n.state.nav.write_a_presentation}</ion-label>
7980
</ion-button>
8081
);
8182
} else {
@@ -92,7 +93,7 @@ export class AppNavigationActions {
9293
onClick={() => this.actionPublish.emit()}
9394
mode="md"
9495
color={themeStore.state.darkTheme ? 'light' : 'dark'}>
95-
<ion-label>Ready to share?</ion-label>
96+
<ion-label>{i18n.state.nav.ready_to_share}</ion-label>
9697
</ion-button>
9798
);
9899
} else {

studio/src/app/components/core/app-navigation/app-navigation.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {Component, Prop, h} from '@stencil/core';
22

33
import offlineStore from '../../../stores/offline.store';
4-
4+
import i18n from '../../../stores/i18n.store';
55
import store from '../../../stores/deck.store';
66

77
@Component({
@@ -104,7 +104,7 @@ export class AppNavigation {
104104
return (
105105
<ion-buttons slot="start">
106106
<ion-menu-toggle>
107-
<ion-button>
107+
<ion-button aria-label={i18n.state.nav.menu}>
108108
<ion-icon slot="icon-only" name="menu"></ion-icon>
109109
</ion-button>
110110
</ion-menu-toggle>
@@ -138,7 +138,7 @@ export class AppNavigation {
138138

139139
return (
140140
<ion-router-link href={`/editor/${offlineStore.state.offline.id}`} routerDirection="root" slot="end" class="offline-info ion-padding-end">
141-
<ion-label>You are editing offline.</ion-label>
141+
<ion-label>{i18n.state.offline.editing}</ion-label>
142142
</ion-router-link>
143143
);
144144
}

studio/src/app/components/core/app-signin/app-signin.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ import {User as FirebaseUser, UserCredential, AuthCredential, OAuthCredential} f
77
import navStore, {NavDirection} from '../../../stores/nav.store';
88
import authStore from '../../../stores/auth.store';
99
import tokenStore from '../../../stores/token.store';
10+
import i18n from '../../../stores/i18n.store';
1011

1112
import {AuthUser} from '../../../models/auth/auth.user';
1213

1314
import {Utils} from '../../../utils/core/utils';
15+
import {renderI18n} from '../../../utils/core/i18n.utils';
16+
1417
import {EnvironmentDeckDeckGoConfig} from '../../../types/core/environment-config';
1518

1619
import {EnvironmentConfigService} from '../../../services/core/environment/environment-config.service';
@@ -293,16 +296,16 @@ export class AppSignIn {
293296
<div id="firebaseui-auth-container"></div>
294297

295298
<p class="ion-text-center ion-padding-start ion-padding-end">
296-
<small>DeckDeckGo is free and open source 😃.</small>
299+
<small>{i18n.state.core.free_open_source}</small>
297300
</p>
298301
</main>,
299302
];
300303
}
301304

302305
private renderMsg() {
303306
return [
304-
<h1 class="ion-text-center ion-padding-start ion-padding-end">Oh, hi 👋! Good to have you.</h1>,
305-
<p class="ion-text-center ion-padding">Sign in to unleash all features of the editor and to share your presentation online.</p>,
307+
<h1 class="ion-text-center ion-padding-start ion-padding-end">{i18n.state.sign_in.hi}</h1>,
308+
<p class="ion-text-center ion-padding">{i18n.state.sign_in.why}</p>,
306309
];
307310
}
308311

@@ -312,8 +315,8 @@ export class AppSignIn {
312315
} else {
313316
return (
314317
<ion-buttons class="back">
315-
<ion-button onClick={() => this.navigateBack()} color="dark">
316-
<ion-icon aria-label="Close" src="/assets/icons/ionicons/close.svg"></ion-icon>
318+
<ion-button onClick={() => this.navigateBack()} color="dark" aria-label={i18n.state.core.close}>
319+
<ion-icon src="/assets/icons/ionicons/close.svg"></ion-icon>
317320
</ion-button>
318321
</ion-buttons>
319322
);
@@ -323,7 +326,7 @@ export class AppSignIn {
323326
private renderGitHub() {
324327
return (
325328
<p class="ion-text-center ion-padding-start ion-padding-end ion-padding-bottom">
326-
Additionally, push the source code of your slides to repos with the GitHub <ion-icon name="logo-github"></ion-icon> logging.
329+
{renderI18n(i18n.state.sign_in.additionally, {placeholder: '{0}', value: <ion-icon name="logo-github"></ion-icon>})}
327330
</p>
328331
);
329332
}

studio/src/app/components/core/app-template-showcase/app-template-showcase.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {Component, Prop, h, State, Fragment} from '@stencil/core';
22

3+
import i18n from '../../../stores/i18n.store';
4+
35
import {Template, TemplateDataSlot} from '../../../models/data/template';
46

57
import {TemplateUtils} from '../../../utils/editor/template.utils';
@@ -61,7 +63,7 @@ export class AppTemplateShowcase {
6163
return (
6264
<div class="spinner">
6365
<ion-spinner color="medium"></ion-spinner>
64-
<ion-label>Loading...</ion-label>
66+
<ion-label>{i18n.state.core.loading}</ion-label>
6567
</div>
6668
);
6769
}

0 commit comments

Comments
 (0)