aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions/service.js2
-rw-r--r--src/api/server/ServerApi.js56
-rw-r--r--src/assets/images/tray/darwin-dark/tray-active.pngbin0 -> 396 bytes
-rw-r--r--src/assets/images/tray/darwin-dark/tray-active@2x.pngbin0 -> 1291 bytes
-rw-r--r--src/assets/images/tray/darwin-dark/tray-unread-active.pngbin0 -> 424 bytes
-rw-r--r--src/assets/images/tray/darwin-dark/tray-unread-active@2x.pngbin0 -> 1359 bytes
-rw-r--r--src/assets/images/tray/darwin-dark/tray-unread.pngbin0 -> 424 bytes
-rw-r--r--src/assets/images/tray/darwin-dark/tray-unread@2x.pngbin0 -> 1359 bytes
-rw-r--r--src/assets/images/tray/darwin-dark/tray.pngbin0 -> 396 bytes
-rw-r--r--src/assets/images/tray/darwin-dark/tray@2x.pngbin0 -> 1291 bytes
-rw-r--r--src/components/auth/Import.js1
-rw-r--r--src/components/auth/Login.js8
-rw-r--r--src/components/auth/Signup.js7
-rw-r--r--src/components/services/content/ServiceWebview.js24
-rw-r--r--src/components/settings/settings/EditSettingsForm.js1
-rw-r--r--src/components/ui/StatusBarTargetUrl.js40
-rw-r--r--src/components/ui/Subscription.js8
-rw-r--r--src/components/ui/SubscriptionPopup.js2
-rw-r--r--src/config.js10
-rw-r--r--src/containers/settings/EditSettingsScreen.js23
-rw-r--r--src/containers/ui/SubscriptionPopupScreen.js2
-rw-r--r--src/electron/Settings.js14
-rw-r--r--src/electron/ipc-api/appIndicator.js45
-rw-r--r--src/electron/ipc-api/settings.js9
-rw-r--r--src/electron/ipc-api/tray.js48
-rw-r--r--src/i18n/languages.js11
-rw-r--r--src/i18n/locales/de.json167
-rw-r--r--src/i18n/locales/el-GR.json168
-rw-r--r--src/i18n/locales/en-US.json1
-rw-r--r--src/i18n/locales/fr.json167
-rw-r--r--src/i18n/locales/ja.json167
-rw-r--r--src/i18n/locales/nl-BE.json167
-rw-r--r--src/i18n/locales/nl.json168
-rw-r--r--src/i18n/locales/pl.json167
-rw-r--r--src/i18n/locales/pt-BR.json167
-rw-r--r--src/i18n/locales/ru.json168
-rw-r--r--src/i18n/locales/ua.json167
-rw-r--r--src/index.js44
-rw-r--r--src/lib/Menu.js1
-rw-r--r--src/lib/Tray.js73
-rw-r--r--src/stores/AppStore.js53
-rw-r--r--src/stores/RecipesStore.js4
-rw-r--r--src/stores/ServicesStore.js24
-rw-r--r--src/stores/UserStore.js9
-rw-r--r--src/styles/infobox.scss5
-rw-r--r--src/styles/main.scss1
-rw-r--r--src/styles/status-bar-target-url.scss14
47 files changed, 2070 insertions, 143 deletions
diff --git a/src/actions/service.js b/src/actions/service.js
index 7f429ca32..cdd4bbf16 100644
--- a/src/actions/service.js
+++ b/src/actions/service.js
@@ -4,6 +4,8 @@ export default {
4 setActive: { 4 setActive: {
5 serviceId: PropTypes.string.isRequired, 5 serviceId: PropTypes.string.isRequired,
6 }, 6 },
7 setActiveNext: {},
8 setActivePrev: {},
7 showAddServiceInterface: { 9 showAddServiceInterface: {
8 recipeId: PropTypes.string.isRequired, 10 recipeId: PropTypes.string.isRequired,
9 }, 11 },
diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js
index 86f4c99e7..8b0b7563c 100644
--- a/src/api/server/ServerApi.js
+++ b/src/api/server/ServerApi.js
@@ -1,6 +1,6 @@
1import os from 'os'; 1import os from 'os';
2import path from 'path'; 2import path from 'path';
3import targz from 'tar.gz'; 3import tar from 'tar';
4import fs from 'fs-extra'; 4import fs from 'fs-extra';
5import { remote } from 'electron'; 5import { remote } from 'electron';
6 6
@@ -293,7 +293,11 @@ export default class ServerApi {
293 const buffer = await res.buffer(); 293 const buffer = await res.buffer();
294 fs.writeFileSync(archivePath, buffer); 294 fs.writeFileSync(archivePath, buffer);
295 295
296 await targz().extract(archivePath, recipeTempDirectory); 296 tar.x({
297 file: archivePath,
298 cwd: recipeTempDirectory,
299 sync: true,
300 });
297 301
298 const { id } = fs.readJsonSync(path.join(recipeTempDirectory, 'package.json')); 302 const { id } = fs.readJsonSync(path.join(recipeTempDirectory, 'package.json'));
299 const recipeDirectory = path.join(recipesDirectory, id); 303 const recipeDirectory = path.join(recipesDirectory, id);
@@ -443,6 +447,10 @@ export default class ServerApi {
443 447
444 // Helper 448 // Helper
445 async _mapServiceModels(services) { 449 async _mapServiceModels(services) {
450 const recipes = services.map(s => s.recipeId);
451
452 await this._bulkRecipeCheck(recipes);
453
446 return Promise.all(services 454 return Promise.all(services
447 .map(async service => await this._prepareServiceModel(service)) // eslint-disable-line 455 .map(async service => await this._prepareServiceModel(service)) // eslint-disable-line
448 ); 456 );
@@ -454,19 +462,8 @@ export default class ServerApi {
454 recipe = this.recipes.find(r => r.id === service.recipeId); 462 recipe = this.recipes.find(r => r.id === service.recipeId);
455 463
456 if (!recipe) { 464 if (!recipe) {
457 console.warn(`Recipe '${service.recipeId}' not installed, trying to fetch from server`); 465 console.warn(`Recipe ${service.recipeId} not loaded`);
458 466 return null;
459 await this.getRecipePackage(service.recipeId);
460
461 console.debug('Rerun ServerAPI::getInstalledRecipes');
462 await this.getInstalledRecipes();
463
464 recipe = this.recipes.find(r => r.id === service.recipeId);
465
466 if (!recipe) {
467 console.warn(`Could not load recipe ${service.recipeId}`);
468 return null;
469 }
470 } 467 }
471 468
472 return new ServiceModel(service, recipe); 469 return new ServiceModel(service, recipe);
@@ -476,6 +473,35 @@ export default class ServerApi {
476 } 473 }
477 } 474 }
478 475
476 async _bulkRecipeCheck(unfilteredRecipes) {
477 // Filter recipe duplicates as we don't need to download 3 Slack recipes
478 const recipes = unfilteredRecipes.filter((elem, pos, arr) => arr.indexOf(elem) === pos);
479
480 return Promise.all(recipes
481 .map(async (recipeId) => {
482 let recipe = this.recipes.find(r => r.id === recipeId);
483
484 if (!recipe) {
485 console.warn(`Recipe '${recipeId}' not installed, trying to fetch from server`);
486
487 await this.getRecipePackage(recipeId);
488
489 console.debug('Rerun ServerAPI::getInstalledRecipes');
490 await this.getInstalledRecipes();
491
492 recipe = this.recipes.find(r => r.id === recipeId);
493
494 if (!recipe) {
495 console.warn(`Could not load recipe ${recipeId}`);
496 return null;
497 }
498 }
499
500 return recipe;
501 }),
502 ).catch(err => console.error(err));
503 }
504
479 _mapRecipePreviewModel(recipes) { 505 _mapRecipePreviewModel(recipes) {
480 return recipes.map((recipe) => { 506 return recipes.map((recipe) => {
481 try { 507 try {
diff --git a/src/assets/images/tray/darwin-dark/tray-active.png b/src/assets/images/tray/darwin-dark/tray-active.png
new file mode 100644
index 000000000..489533dbf
--- /dev/null
+++ b/src/assets/images/tray/darwin-dark/tray-active.png
Binary files differ
diff --git a/src/assets/images/tray/darwin-dark/tray-active@2x.png b/src/assets/images/tray/darwin-dark/tray-active@2x.png
new file mode 100644
index 000000000..76f212b52
--- /dev/null
+++ b/src/assets/images/tray/darwin-dark/tray-active@2x.png
Binary files differ
diff --git a/src/assets/images/tray/darwin-dark/tray-unread-active.png b/src/assets/images/tray/darwin-dark/tray-unread-active.png
new file mode 100644
index 000000000..e2fd1a822
--- /dev/null
+++ b/src/assets/images/tray/darwin-dark/tray-unread-active.png
Binary files differ
diff --git a/src/assets/images/tray/darwin-dark/tray-unread-active@2x.png b/src/assets/images/tray/darwin-dark/tray-unread-active@2x.png
new file mode 100644
index 000000000..9a64b3ef8
--- /dev/null
+++ b/src/assets/images/tray/darwin-dark/tray-unread-active@2x.png
Binary files differ
diff --git a/src/assets/images/tray/darwin-dark/tray-unread.png b/src/assets/images/tray/darwin-dark/tray-unread.png
new file mode 100644
index 000000000..e2fd1a822
--- /dev/null
+++ b/src/assets/images/tray/darwin-dark/tray-unread.png
Binary files differ
diff --git a/src/assets/images/tray/darwin-dark/tray-unread@2x.png b/src/assets/images/tray/darwin-dark/tray-unread@2x.png
new file mode 100644
index 000000000..9a64b3ef8
--- /dev/null
+++ b/src/assets/images/tray/darwin-dark/tray-unread@2x.png
Binary files differ
diff --git a/src/assets/images/tray/darwin-dark/tray.png b/src/assets/images/tray/darwin-dark/tray.png
new file mode 100644
index 000000000..489533dbf
--- /dev/null
+++ b/src/assets/images/tray/darwin-dark/tray.png
Binary files differ
diff --git a/src/assets/images/tray/darwin-dark/tray@2x.png b/src/assets/images/tray/darwin-dark/tray@2x.png
new file mode 100644
index 000000000..76f212b52
--- /dev/null
+++ b/src/assets/images/tray/darwin-dark/tray@2x.png
Binary files differ
diff --git a/src/components/auth/Import.js b/src/components/auth/Import.js
index cf83aa9c8..06493a0fd 100644
--- a/src/components/auth/Import.js
+++ b/src/components/auth/Import.js
@@ -99,7 +99,6 @@ export default class Import extends Component {
99 <tr 99 <tr
100 key={service.id} 100 key={service.id}
101 className="service-table__row" 101 className="service-table__row"
102 onClick={() => service.$('add').set(!service.$('add').value)}
103 > 102 >
104 <td className="service-table__toggle"> 103 <td className="service-table__toggle">
105 <Toggle 104 <Toggle
diff --git a/src/components/auth/Login.js b/src/components/auth/Login.js
index 015079f02..67e92849d 100644
--- a/src/components/auth/Login.js
+++ b/src/components/auth/Login.js
@@ -3,11 +3,14 @@ import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 4import { defineMessages, intlShape } from 'react-intl';
5 5
6import { isDevMode, useLiveAPI } from '../../environment';
6import Form from '../../lib/Form'; 7import Form from '../../lib/Form';
7import { required, email } from '../../helpers/validation-helpers'; 8import { required, email } from '../../helpers/validation-helpers';
8import Input from '../ui/Input'; 9import Input from '../ui/Input';
9import Button from '../ui/Button'; 10import Button from '../ui/Button';
10import Link from '../ui/Link'; 11import Link from '../ui/Link';
12import Infobox from '../ui/Infobox';
13
11 14
12import { globalError as globalErrorPropType } from '../../prop-types'; 15import { globalError as globalErrorPropType } from '../../prop-types';
13 16
@@ -117,6 +120,11 @@ export default class Login extends Component {
117 alt="" 120 alt=""
118 /> 121 />
119 <h1>{intl.formatMessage(messages.headline)}</h1> 122 <h1>{intl.formatMessage(messages.headline)}</h1>
123 {isDevMode && !useLiveAPI && (
124 <Infobox type="warning">
125 In Dev Mode your data is not persistent. Please use the live app for accesing the production API.
126 </Infobox>
127 )}
120 {isTokenExpired && ( 128 {isTokenExpired && (
121 <p className="error-message center">{intl.formatMessage(messages.tokenExpired)}</p> 129 <p className="error-message center">{intl.formatMessage(messages.tokenExpired)}</p>
122 )} 130 )}
diff --git a/src/components/auth/Signup.js b/src/components/auth/Signup.js
index 71ca16111..a990a112e 100644
--- a/src/components/auth/Signup.js
+++ b/src/components/auth/Signup.js
@@ -3,12 +3,14 @@ import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 4import { defineMessages, intlShape } from 'react-intl';
5 5
6import { isDevMode, useLiveAPI } from '../../environment';
6import Form from '../../lib/Form'; 7import Form from '../../lib/Form';
7import { required, email, minLength } from '../../helpers/validation-helpers'; 8import { required, email, minLength } from '../../helpers/validation-helpers';
8import Input from '../ui/Input'; 9import Input from '../ui/Input';
9import Radio from '../ui/Radio'; 10import Radio from '../ui/Radio';
10import Button from '../ui/Button'; 11import Button from '../ui/Button';
11import Link from '../ui/Link'; 12import Link from '../ui/Link';
13import Infobox from '../ui/Infobox';
12 14
13import { globalError as globalErrorPropType } from '../../prop-types'; 15import { globalError as globalErrorPropType } from '../../prop-types';
14 16
@@ -145,6 +147,11 @@ export default class Signup extends Component {
145 alt="" 147 alt=""
146 /> 148 />
147 <h1>{intl.formatMessage(messages.headline)}</h1> 149 <h1>{intl.formatMessage(messages.headline)}</h1>
150 {isDevMode && !useLiveAPI && (
151 <Infobox type="warning">
152 In Dev Mode your data is not persistent. Please use the live app for accesing the production API.
153 </Infobox>
154 )}
148 <Radio field={form.$('accountType')} showLabel={false} /> 155 <Radio field={form.$('accountType')} showLabel={false} />
149 <div className="grid__row"> 156 <div className="grid__row">
150 <Input field={form.$('firstname')} focus /> 157 <Input field={form.$('firstname')} focus />
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js
index 043ff42ea..3ee3155be 100644
--- a/src/components/services/content/ServiceWebview.js
+++ b/src/components/services/content/ServiceWebview.js
@@ -6,6 +6,7 @@ import Webview from 'react-electron-web-view';
6import classnames from 'classnames'; 6import classnames from 'classnames';
7 7
8import ServiceModel from '../../../models/Service'; 8import ServiceModel from '../../../models/Service';
9import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl';
9 10
10@observer 11@observer
11export default class ServiceWebview extends Component { 12export default class ServiceWebview extends Component {
@@ -20,6 +21,8 @@ export default class ServiceWebview extends Component {
20 21
21 state = { 22 state = {
22 forceRepaint: false, 23 forceRepaint: false,
24 targetUrl: '',
25 statusBarVisible: false,
23 }; 26 };
24 27
25 componentDidMount() { 28 componentDidMount() {
@@ -33,6 +36,17 @@ export default class ServiceWebview extends Component {
33 }); 36 });
34 } 37 }
35 38
39 updateTargetUrl = (event) => {
40 let visible = true;
41 if (event.url === '' || event.url === '#') {
42 visible = false;
43 }
44 this.setState({
45 targetUrl: event.url,
46 statusBarVisible: visible,
47 });
48 }
49
36 webview = null; 50 webview = null;
37 51
38 render() { 52 render() {
@@ -47,6 +61,13 @@ export default class ServiceWebview extends Component {
47 'services__webview--force-repaint': this.state.forceRepaint, 61 'services__webview--force-repaint': this.state.forceRepaint,
48 }); 62 });
49 63
64 let statusBar = null;
65 if (this.state.statusBarVisible) {
66 statusBar = (
67 <StatusBarTargetUrl text={this.state.targetUrl} />
68 );
69 }
70
50 return ( 71 return (
51 <div className={webviewClasses}> 72 <div className={webviewClasses}>
52 <Webview 73 <Webview
@@ -62,11 +83,14 @@ export default class ServiceWebview extends Component {
62 webview: this.webview.view, 83 webview: this.webview.view,
63 })} 84 })}
64 85
86 onUpdateTargetUrl={this.updateTargetUrl}
87
65 useragent={service.userAgent} 88 useragent={service.userAgent}
66 89
67 disablewebsecurity 90 disablewebsecurity
68 allowpopups 91 allowpopups
69 /> 92 />
93 {statusBar}
70 </div> 94 </div>
71 ); 95 );
72 } 96 }
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js
index 02736dbb9..5675fecf4 100644
--- a/src/components/settings/settings/EditSettingsForm.js
+++ b/src/components/settings/settings/EditSettingsForm.js
@@ -115,6 +115,7 @@ export default class EditSettingsForm extends Component {
115 <h2>{intl.formatMessage(messages.headlineGeneral)}</h2> 115 <h2>{intl.formatMessage(messages.headlineGeneral)}</h2>
116 <Toggle field={form.$('autoLaunchOnStart')} /> 116 <Toggle field={form.$('autoLaunchOnStart')} />
117 <Toggle field={form.$('runInBackground')} /> 117 <Toggle field={form.$('runInBackground')} />
118 <Toggle field={form.$('enableSystemTray')} />
118 {process.platform === 'win32' && ( 119 {process.platform === 'win32' && (
119 <Toggle field={form.$('minimizeToSystemTray')} /> 120 <Toggle field={form.$('minimizeToSystemTray')} />
120 )} 121 )}
diff --git a/src/components/ui/StatusBarTargetUrl.js b/src/components/ui/StatusBarTargetUrl.js
new file mode 100644
index 000000000..b7b198f42
--- /dev/null
+++ b/src/components/ui/StatusBarTargetUrl.js
@@ -0,0 +1,40 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react';
4import classnames from 'classnames';
5
6import Appear from '../ui/effects/Appear';
7
8@observer
9export default class StatusBarTargetUrl extends Component {
10 static propTypes = {
11 className: PropTypes.string,
12 text: PropTypes.string,
13 };
14
15 static defaultProps = {
16 className: '',
17 position: 'bottom',
18 text: '',
19 };
20
21 render() {
22 const {
23 className,
24 text,
25 } = this.props;
26
27 return (
28 <Appear
29 className={classnames({
30 'status-bar-target-url': true,
31 [`${className}`]: true,
32 })}
33 >
34 <div className="status-bar-target-url__content">
35 {text}
36 </div>
37 </Appear>
38 );
39 }
40}
diff --git a/src/components/ui/Subscription.js b/src/components/ui/Subscription.js
index ada5cc3e0..fe0925a26 100644
--- a/src/components/ui/Subscription.js
+++ b/src/components/ui/Subscription.js
@@ -79,7 +79,7 @@ const messages = defineMessages({
79 }, 79 },
80 miningDetail1: { 80 miningDetail1: {
81 id: 'subscription.mining.line1', 81 id: 'subscription.mining.line1',
82 defaultMessage: '!!!By enabling "Support with processing power", Franz will use about 20-50% of your CPU to mine cryptocurrency Monero which equals approximately $ 5/year.', 82 defaultMessage: '!!!By enabling "Support with processing power", Franz will use about 20-50% of your CPU to mine cryptocurrency Monero which equals approximately € 5/year.',
83 }, 83 },
84 miningDetail2: { 84 miningDetail2: {
85 id: 'subscription.mining.line2', 85 id: 'subscription.mining.line2',
@@ -136,12 +136,12 @@ export default class SubscriptionForm extends Component {
136 validate: [required], 136 validate: [required],
137 options: [{ 137 options: [{
138 value: 'month', 138 value: 'month',
139 label: `$ ${Object.hasOwnProperty.call(this.props.plan, 'month') 139 label: ` ${Object.hasOwnProperty.call(this.props.plan, 'month')
140 ? `${this.props.plan.month.price} / ${intl.formatMessage(messages.typeMonthly)}` 140 ? `${this.props.plan.month.price} / ${intl.formatMessage(messages.typeMonthly)}`
141 : 'monthly'}`, 141 : 'monthly'}`,
142 }, { 142 }, {
143 value: 'year', 143 value: 'year',
144 label: `$ ${Object.hasOwnProperty.call(this.props.plan, 'year') 144 label: ` ${Object.hasOwnProperty.call(this.props.plan, 'year')
145 ? `${this.props.plan.year.price} / ${intl.formatMessage(messages.typeYearly)}` 145 ? `${this.props.plan.year.price} / ${intl.formatMessage(messages.typeYearly)}`
146 : 'yearly'}`, 146 : 'yearly'}`,
147 }, { 147 }, {
@@ -155,7 +155,7 @@ export default class SubscriptionForm extends Component {
155 if (this.props.showSkipOption) { 155 if (this.props.showSkipOption) {
156 form.fields.paymentTier.options.unshift({ 156 form.fields.paymentTier.options.unshift({
157 value: 'skip', 157 value: 'skip',
158 label: `$ 0 / ${intl.formatMessage(messages.typeFree)}`, 158 label: ` 0 / ${intl.formatMessage(messages.typeFree)}`,
159 }); 159 });
160 } 160 }
161 161
diff --git a/src/components/ui/SubscriptionPopup.js b/src/components/ui/SubscriptionPopup.js
index 72b6ccd98..5aae2c47a 100644
--- a/src/components/ui/SubscriptionPopup.js
+++ b/src/components/ui/SubscriptionPopup.js
@@ -57,7 +57,7 @@ export default class SubscriptionPopup extends Component {
57 className="subscription-popup__webview" 57 className="subscription-popup__webview"
58 58
59 autosize 59 autosize
60 src={url} 60 src={encodeURI(url)}
61 disablewebsecurity 61 disablewebsecurity
62 onDidNavigate={completeCheck} 62 onDidNavigate={completeCheck}
63 // onNewWindow={(event, url, frameName, options) => 63 // onNewWindow={(event, url, frameName, options) =>
diff --git a/src/config.js b/src/config.js
index acbf57f3c..0a4856ece 100644
--- a/src/config.js
+++ b/src/config.js
@@ -3,3 +3,13 @@ export const LOCAL_API = 'http://localhost:3000';
3export const DEV_API = 'https://dev.franzinfra.com'; 3export const DEV_API = 'https://dev.franzinfra.com';
4export const LIVE_API = 'https://api.franzinfra.com'; 4export const LIVE_API = 'https://api.franzinfra.com';
5export const GA_ID = 'UA-74126766-6'; 5export const GA_ID = 'UA-74126766-6';
6
7export const DEFAULT_APP_SETTINGS = {
8 autoLaunchOnStart: true,
9 autoLaunchInBackground: false,
10 runInBackground: false,
11 enableSystemTray: true,
12 minimizeToSystemTray: false,
13 locale: 'en-us', // TODO: Replace with proper solution once translations are in
14 beta: false,
15};
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js
index 0e17cafce..6dc2175e1 100644
--- a/src/containers/settings/EditSettingsScreen.js
+++ b/src/containers/settings/EditSettingsScreen.js
@@ -9,6 +9,7 @@ import UserStore from '../../stores/UserStore';
9import Form from '../../lib/Form'; 9import Form from '../../lib/Form';
10import languages from '../../i18n/languages'; 10import languages from '../../i18n/languages';
11import { gaPage } from '../../lib/analytics'; 11import { gaPage } from '../../lib/analytics';
12import { DEFAULT_APP_SETTINGS } from '../../config';
12 13
13 14
14import EditSettingsForm from '../../components/settings/settings/EditSettingsForm'; 15import EditSettingsForm from '../../components/settings/settings/EditSettingsForm';
@@ -26,6 +27,10 @@ const messages = defineMessages({
26 id: 'settings.app.form.runInBackground', 27 id: 'settings.app.form.runInBackground',
27 defaultMessage: '!!!Keep Franz in background when closing the window', 28 defaultMessage: '!!!Keep Franz in background when closing the window',
28 }, 29 },
30 enableSystemTray: {
31 id: 'settings.app.form.enableSystemTray',
32 defaultMessage: '!!!Show Franz in system tray',
33 },
29 minimizeToSystemTray: { 34 minimizeToSystemTray: {
30 id: 'settings.app.form.minimizeToSystemTray', 35 id: 'settings.app.form.minimizeToSystemTray',
31 defaultMessage: '!!!Minimize Franz to system tray', 36 defaultMessage: '!!!Minimize Franz to system tray',
@@ -61,6 +66,7 @@ export default class EditSettingsScreen extends Component {
61 settings.update({ 66 settings.update({
62 settings: { 67 settings: {
63 runInBackground: settingsData.runInBackground, 68 runInBackground: settingsData.runInBackground,
69 enableSystemTray: settingsData.enableSystemTray,
64 minimizeToSystemTray: settingsData.minimizeToSystemTray, 70 minimizeToSystemTray: settingsData.minimizeToSystemTray,
65 locale: settingsData.locale, 71 locale: settingsData.locale,
66 beta: settingsData.beta, 72 beta: settingsData.beta,
@@ -91,33 +97,38 @@ export default class EditSettingsScreen extends Component {
91 autoLaunchOnStart: { 97 autoLaunchOnStart: {
92 label: intl.formatMessage(messages.autoLaunchOnStart), 98 label: intl.formatMessage(messages.autoLaunchOnStart),
93 value: app.autoLaunchOnStart, 99 value: app.autoLaunchOnStart,
94 default: true, 100 default: DEFAULT_APP_SETTINGS.autoLaunchOnStart,
95 }, 101 },
96 autoLaunchInBackground: { 102 autoLaunchInBackground: {
97 label: intl.formatMessage(messages.autoLaunchInBackground), 103 label: intl.formatMessage(messages.autoLaunchInBackground),
98 value: app.launchInBackground, 104 value: app.launchInBackground,
99 default: false, 105 default: DEFAULT_APP_SETTINGS.autoLaunchInBackground,
100 }, 106 },
101 runInBackground: { 107 runInBackground: {
102 label: intl.formatMessage(messages.runInBackground), 108 label: intl.formatMessage(messages.runInBackground),
103 value: settings.all.runInBackground, 109 value: settings.all.runInBackground,
104 default: true, 110 default: DEFAULT_APP_SETTINGS.runInBackground,
111 },
112 enableSystemTray: {
113 label: intl.formatMessage(messages.enableSystemTray),
114 value: settings.all.enableSystemTray,
115 default: DEFAULT_APP_SETTINGS.enableSystemTray,
105 }, 116 },
106 minimizeToSystemTray: { 117 minimizeToSystemTray: {
107 label: intl.formatMessage(messages.minimizeToSystemTray), 118 label: intl.formatMessage(messages.minimizeToSystemTray),
108 value: settings.all.minimizeToSystemTray, 119 value: settings.all.minimizeToSystemTray,
109 default: false, 120 default: DEFAULT_APP_SETTINGS.minimizeToSystemTray,
110 }, 121 },
111 locale: { 122 locale: {
112 label: intl.formatMessage(messages.language), 123 label: intl.formatMessage(messages.language),
113 value: app.locale, 124 value: app.locale,
114 options, 125 options,
115 default: 'en-US', 126 default: DEFAULT_APP_SETTINGS.locale,
116 }, 127 },
117 beta: { 128 beta: {
118 label: intl.formatMessage(messages.beta), 129 label: intl.formatMessage(messages.beta),
119 value: user.data.beta, 130 value: user.data.beta,
120 default: false, 131 default: DEFAULT_APP_SETTINGS.beta,
121 }, 132 },
122 }, 133 },
123 }; 134 };
diff --git a/src/containers/ui/SubscriptionPopupScreen.js b/src/containers/ui/SubscriptionPopupScreen.js
index d17477b1d..0b6432e50 100644
--- a/src/containers/ui/SubscriptionPopupScreen.js
+++ b/src/containers/ui/SubscriptionPopupScreen.js
@@ -24,7 +24,7 @@ export default class SubscriptionPopupScreen extends Component {
24 render() { 24 render() {
25 return ( 25 return (
26 <SubscriptionPopup 26 <SubscriptionPopup
27 url={decodeURIComponent(this.props.router.params.url)} 27 url={this.props.router.params.url}
28 closeWindow={() => window.close()} 28 closeWindow={() => window.close()}
29 completeCheck={e => this.completeCheck(e)} 29 completeCheck={e => this.completeCheck(e)}
30 isCompleted={this.state.complete} 30 isCompleted={this.state.complete}
diff --git a/src/electron/Settings.js b/src/electron/Settings.js
index 049a08296..824b4c20c 100644
--- a/src/electron/Settings.js
+++ b/src/electron/Settings.js
@@ -1,5 +1,17 @@
1import { observable } from 'mobx';
2
3import { DEFAULT_APP_SETTINGS } from '../config';
4
1export default class Settings { 5export default class Settings {
2 store = {}; 6 @observable store = {
7 autoLaunchOnStart: DEFAULT_APP_SETTINGS.autoLaunchOnStart,
8 autoLaunchInBackground: DEFAULT_APP_SETTINGS.autoLaunchInBackground,
9 runInBackground: DEFAULT_APP_SETTINGS.runInBackground,
10 enableSystemTray: DEFAULT_APP_SETTINGS.enableSystemTray,
11 minimizeToSystemTray: DEFAULT_APP_SETTINGS.minimizeToSystemTray,
12 locale: DEFAULT_APP_SETTINGS.locale,
13 beta: DEFAULT_APP_SETTINGS.beta,
14 };
3 15
4 set(settings) { 16 set(settings) {
5 this.store = Object.assign(this.store, settings); 17 this.store = Object.assign(this.store, settings);
diff --git a/src/electron/ipc-api/appIndicator.js b/src/electron/ipc-api/appIndicator.js
index 576234d25..d31819068 100644
--- a/src/electron/ipc-api/appIndicator.js
+++ b/src/electron/ipc-api/appIndicator.js
@@ -1,12 +1,11 @@
1import { app, ipcMain, Tray, Menu } from 'electron'; 1import { app, ipcMain } from 'electron';
2import path from 'path'; 2import path from 'path';
3import { autorun } from 'mobx';
3 4
4const INDICATOR_TRAY_PLAIN = 'tray';
5const INDICATOR_TRAY_UNREAD = 'tray-unread';
6const INDICATOR_TASKBAR = 'taskbar'; 5const INDICATOR_TASKBAR = 'taskbar';
7
8const FILE_EXTENSION = process.platform === 'win32' ? 'ico' : 'png'; 6const FILE_EXTENSION = process.platform === 'win32' ? 'ico' : 'png';
9let trayIcon; 7
8let isTrayIconEnabled;
10 9
11function getAsset(type, asset) { 10function getAsset(type, asset) {
12 return path.join( 11 return path.join(
@@ -15,26 +14,14 @@ function getAsset(type, asset) {
15} 14}
16 15
17export default (params) => { 16export default (params) => {
18 trayIcon = new Tray(getAsset('tray', INDICATOR_TRAY_PLAIN)); 17 autorun(() => {
19 const trayMenuTemplate = [ 18 isTrayIconEnabled = params.settings.get('enableSystemTray');
20 {
21 label: 'Show Franz',
22 click() {
23 params.mainWindow.show();
24 },
25 }, {
26 label: 'Quit Franz',
27 click() {
28 app.quit();
29 },
30 },
31 ];
32
33 const trayMenu = Menu.buildFromTemplate(trayMenuTemplate);
34 trayIcon.setContextMenu(trayMenu);
35 19
36 trayIcon.on('click', () => { 20 if (!isTrayIconEnabled) {
37 params.mainWindow.show(); 21 params.trayIcon.hide();
22 } else if (isTrayIconEnabled) {
23 params.trayIcon.show();
24 }
38 }); 25 });
39 26
40 ipcMain.on('updateAppIndicator', (event, args) => { 27 ipcMain.on('updateAppIndicator', (event, args) => {
@@ -68,13 +55,7 @@ export default (params) => {
68 } 55 }
69 } 56 }
70 57
71 // Update system tray 58 // Update Tray
72 trayIcon.setImage(getAsset('tray', args.indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN)); 59 params.trayIcon.setIndicator(args.indicator);
73
74 if (process.platform === 'darwin') {
75 trayIcon.setPressedImage(
76 getAsset('tray', `${args.indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN}-active`),
77 );
78 }
79 }); 60 });
80}; 61};
diff --git a/src/electron/ipc-api/settings.js b/src/electron/ipc-api/settings.js
index 1d7eafa6c..995b28fbd 100644
--- a/src/electron/ipc-api/settings.js
+++ b/src/electron/ipc-api/settings.js
@@ -1,10 +1,7 @@
1import { ipcMain } from 'electron'; 1import { ipcMain } from 'electron';
2 2
3export default (params) => { 3export default (params) => {
4 if (process.platform === 'darwin' || process.platform === 'win32') { 4 ipcMain.on('settings', (event, args) => {
5 // eslint-disable-next-line 5 params.settings.set(args);
6 ipcMain.on('settings', (event, args) => { 6 });
7 params.settings.set(args);
8 });
9 }
10}; 7};
diff --git a/src/electron/ipc-api/tray.js b/src/electron/ipc-api/tray.js
deleted file mode 100644
index 43364c0ed..000000000
--- a/src/electron/ipc-api/tray.js
+++ /dev/null
@@ -1,48 +0,0 @@
1import { Tray, Menu, ipcMain } from 'electron';
2import path from 'path';
3
4const INDICATOR_PLAIN = 'franz-taskbar';
5const INDICATOR_UNREAD = 'franz-taskbar-unread';
6
7const FILE_EXTENSION = process.platform === 'win32' ? 'ico' : 'png';
8
9let trayIcon;
10
11function getAsset(asset) {
12 return path.join(
13 __dirname, '..', '..', 'assets', 'images', 'tray', process.platform, `${asset}.${FILE_EXTENSION}`,
14 );
15}
16
17export default (params) => {
18 // if (process.platform === 'win32' || process.platform === 'linux') {
19 trayIcon = new Tray(getAsset(INDICATOR_PLAIN));
20 const trayMenuTemplate = [
21 {
22 label: 'Show Franz',
23 click() {
24 params.mainWindow.show();
25 },
26 }, {
27 label: 'Quit Franz',
28 click() {
29 params.app.quit();
30 },
31 },
32 ];
33
34 const trayMenu = Menu.buildFromTemplate(trayMenuTemplate);
35 trayIcon.setContextMenu(trayMenu);
36
37 trayIcon.on('click', () => {
38 params.mainWindow.show();
39 });
40
41 ipcMain.on('updateTrayIconIndicator', (event, args) => {
42 trayIcon.setImage(getAsset(args.count !== 0 ? INDICATOR_UNREAD : INDICATOR_PLAIN));
43
44 if (process.platform === 'darwin') {
45 trayIcon.setPressedImage(getAsset(`${args.count !== 0 ? INDICATOR_UNREAD : INDICATOR_PLAIN}-active`));
46 }
47 });
48};
diff --git a/src/i18n/languages.js b/src/i18n/languages.js
index 782853b43..9860295b3 100644
--- a/src/i18n/languages.js
+++ b/src/i18n/languages.js
@@ -1,4 +1,13 @@
1module.exports = { 1module.exports = {
2 'en-US': 'English', 2 'en-US': 'English',
3 // 'de-DE': 'Deutsch', 3 'pt-BR': 'Portuguese (Brazil)',
4 'el-GR': 'Ελληνικά (Greece)',
5 nl: 'Nederlands',
6 'nl-BE': 'Vlaams',
7 de: 'Deutsch',
8 fr: 'French',
9 ja: 'Japanese',
10 pl: 'Polish',
11 ru: 'Русский',
12 ua: 'Українська',
4}; 13};
diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json
new file mode 100644
index 000000000..78de9903e
--- /dev/null
+++ b/src/i18n/locales/de.json
@@ -0,0 +1,167 @@
1{
2 "global.api.unhealthy": "Verbindung mit dem Franz Online Service fehlgeschlagen.",
3 "global.notConnectedToTheInternet": "Du bist nicht mit dem Internet verbunden.",
4 "welcome.signupButton": "Kostenloses Konto erstellen",
5 "welcome.loginButton": "Anmelden",
6 "welcome.slogan": "Kommunikation, die für Dich funktioniert",
7 "login.headline": "Anmelden",
8 "login.email.label": "E-Mail-Adresse",
9 "login.password.label": "Passwort",
10 "login.submit.label": "Anmelden",
11 "login.invalidCredentials": "E-Mail-Adresse oder Passwort ungültig",
12 "login.tokenExpired": "Deine Sitzung ist abgelaufen, bitte melde dich erneut an.",
13 "login.serverLogout": "Deine Sitzung ist abgelaufen, bitte melde dich erneut an.",
14 "login.link.signup": "Kostenloses Konto erstellen",
15 "login.link.password": "Passwort zurücksetzen",
16 "password.headline": "Passwort zurücksetzen",
17 "password.email.label": "E-Mail-Adresse",
18 "password.submit.label": "Absenden",
19 "password.noUser": "Es wurde kein Benutzer mit dieser E-Mail-Adresse gefunden",
20 "password.successInfo": "Bitte überprüfe Deine E-Mail-Adresse",
21 "password.link.signup": "Kostenloses Konto erstellen",
22 "password.link.login": "Anmelden",
23 "signup.headline": "Registrierung",
24 "signup.firstname.label": "Vorname",
25 "signup.lastname.label": "Nachname",
26 "signup.email.label": "E-Mail-Adresse",
27 "signup.company.label": "Unternehmen",
28 "signup.password.label": "Passwort",
29 "signup.submit.label": "Konto erstellen",
30 "signup.link.login": "Du hast bereits ein Konto? Melde Dich an.",
31 "signup.emailDuplicate": "Ein Benutzer mit dieser E-Mail-Adresse existiert bereits.",
32 "signup.legal.info": "Mit der Erstellung eines Franz Kontos, akzeptierst Du die",
33 "signup.legal.terms": "Nutzungsbedingungen",
34 "signup.legal.privacy": "Datenschutzerklärung",
35 "pricing.headline": "Unterstütze Franz",
36 "pricing.support.label": "Wie möchtest Du Franz unterstützen?",
37 "pricing.submit.label": "Ich möchte die Entwicklung von Franz unterstützen.",
38 "pricing.link.skipPayment": "Ich möchte die Entwicklung von Franz nicht unterstützen.",
39 "import.headline": "Importiere Deine Franz 4 Dienste",
40 "import.notSupportedHeadline": "Dienste, die noch nicht von Franz 5 unterstützt werden",
41 "import.submit.label": "Dienste importieren",
42 "import.skip.label": "Ich möchte einen Dienst manuell hinzufügen",
43 "invite.submit.label": "Einladungen senden",
44 "invite.headline.friends": "Lade 3 Deiner Freund oder Kollegen ein",
45 "invite.name.label": "Name",
46 "invite.email.label": "E-Mail-Adresse",
47 "invite.skip.label": "Ich möchte das später tun",
48 "subscription.submit.label": "Ich möchte die Entwicklung von Franz unterstützen",
49 "subscription.paymentSessionError": "Das Zahlungs-Formular konnte nicht geladen werden.",
50 "subscription.includedFeatures": "Bezahlte Franz Premium Support Konten beinhalten",
51 "subscription.features.onpremise": "Integration von gehosteten Diensten, wie HipChat",
52 "subscription.features.customServices": "Private Dienste für Dich und Dein Team",
53 "subscription.features.encryptedSync": "Verschlüsselte Sitzungs-Synchronisation",
54 "subscription.features.vpn": "Proxy & VPN Unterstützung",
55 "subscription.features.ads": "Nie mehr Werbung!",
56 "subscription.features.comingSoon": "folgt bald",
57 "infobar.servicesUpdated": "Deine Dienste wurden aktualisiert.",
58 "infobar.updateAvailable": "Eine neue Version von Franz ist verfügbar.",
59 "infobar.buttonReloadServices": "Dienste neuladen",
60 "infobar.buttonInstallUpdate": "Neustarten & Aktualisierung installieren",
61 "infobar.requiredRequestsFailed": "Dienste und Benutzerinformationen konnten nicht geladen werden",
62 "sidebar.settings": "Einstellungen",
63 "services.welcome": "Willkommen bei Franz",
64 "services.getStarted": "Loslegen",
65 "settings.account.headline": "Konto",
66 "settings.account.headlineSubscription": "Dein Abonnement",
67 "settings.account.headlineUpgrade": "Erweitere Dein Konto & unterstütze Franz",
68 "settings.account.headlineInvoices": "Rechnungen",
69 "settings.account.manageSubscription.label": "Verwalte Dein Abonnement",
70 "settings.account.accountType.basic": "Basis Konto",
71 "settings.account.accountType.premium": "Premium-Supporter Konto",
72 "settings.account.account.editButton": "Konto bearbeiten",
73 "settings.account.invoiceDownload": "Herunterladen",
74 "settings.account.userInfoRequestFailed": "Benutzerinformationen konnten nicht geladen werden",
75 "settings.account.tryReloadUserInfoRequest": "Erneut versuchen",
76 "settings.account.headlineProfile": "Profil aktualisieren",
77 "settings.account.headlineAccount": "Kontoinformationen",
78 "settings.account.headlinePassword": "Passwort ändern",
79 "settings.account.successInfo": "Deine Änderungen wurden gespeichert.",
80 "settings.account.buttonSave": "Profil aktualisieren",
81 "settings.account.mining.thankyou": "Vielen Dank, dass Du Franz mit Deiner Rechenleistung unterstützt.",
82 "settings.account.mining.active": "Du führst gerade {hashes} Berechnungen pro Sekunde aus.",
83 "settings.account.mining.moreInformation": "Weitere Informationen",
84 "settings.account.mining.cancel": "Mining abbrechen",
85 "settings.navigation.availableServices": "Verfügbare Dienste",
86 "settings.navigation.yourServices": "Deine Dienste",
87 "settings.navigation.account": "Konto",
88 "settings.navigation.settings": "Einstellungen",
89 "settings.navigation.logout": "Abmelden",
90 "settings.recipes.headline": "Verfügbare Dienste",
91 "settings.recipes.mostPopular": "Am beliebtesten",
92 "settings.recipes.all": "Alle Dienste",
93 "settings.recipes.dev": "Entwicklung",
94 "settings.recipes.nothingFound": "Entschuldigung, aber kein Dienst entspricht Deiner Suchanfrage.",
95 "settings.recipes.servicesSuccessfulAddedInfo": "Dienst erfolgreich hinzugefügt",
96 "settings.service.form.saveButton": "Dienst speichern",
97 "settings.service.form.deleteButton": "Dienst entfernen",
98 "settings.service.form.availableServices": "Verfügbare Dienste",
99 "settings.service.form.yourServices": "Deine Dienste",
100 "settings.service.form.addServiceHeadline": "{name} hinzufügen",
101 "settings.service.form.editServiceHeadline": "{name} bearbeiten",
102 "settings.service.form.tabHosted": "Gehostet",
103 "settings.service.form.tabOnPremise": "Selbst gehostet ⭐️",
104 "settings.service.form.customUrlValidationError": "Dein eigener {name} server konnte nicht verifiziert werden.",
105 "settings.service.form.customUrlPremiumInfo": "Um einen selbst gehosteten Dienst hinzuzufügen, brauchst Du ein Franz Premium-Supporter Konto.",
106 "settings.service.form.customUrlUpgradeAccount": "Erweitere Dein Konto",
107 "settings.service.form.indirectMessageInfo": "Du wirst über alle neuen Nachrichten in einem Kanal informiert, nicht nur @username, @channel, @here, ...",
108 "settings.service.error.headline": "Fehler",
109 "settings.service.error.goBack": "Zurück zu den Diensten",
110 "settings.service.error.message": "Das Dienst-Rezept konnte nicht geladen werden.",
111 "settings.services.tooltip.isDisabled": "Dienst deaktiviert",
112 "settings.services.tooltip.notificationsDisabled": "Benachrichtigungen deaktiviert",
113 "settings.services.headline": "Deine Dienste",
114 "settings.services.noServicesAdded": "Du hast noch keine Dienste hinzugefügt.",
115 "settings.services.discoverServices": "Dienste entdecken",
116 "settings.services.updatedInfo": "Deine Änderungen wurden gespeichert.",
117 "settings.services.deletedInfo": "Dienst wurde entfernt",
118 "settings.app.headline": "Einstellungen",
119 "settings.app.headlineGeneral": "Allgemein",
120 "settings.app.headlineLanguage": "Sprache",
121 "settings.app.headlineUpdates": "Aktualisierungen",
122 "settings.app.buttonSearchForUpdate": "Auf Aktualisierungen prüfen",
123 "settings.app.buttonInstallUpdate": "Neustarten & Aktualisierung installieren",
124 "settings.app.updateStatusSearching": "Suche nach Aktualisierungen",
125 "settings.app.updateStatusAvailable": "Aktualisierung verfügbar, herunterladen...",
126 "settings.app.updateStatusUpToDate": "Du nutzt die aktuellste Version von Franz",
127 "settings.app.form.autoLaunchOnStart": "Franz beim Systemstart ausführen",
128 "settings.app.form.autoLaunchInBackground": "Im Hintergrund öffnen",
129 "settings.app.form.minimizeToSystemTray": "Franz in die Taskleiste minimieren",
130 "settings.app.form.runInBackground": "Franz im Hintergrund behalten, wenn das Fenster geschlossen wird",
131 "settings.app.form.language": "Sprache",
132 "settings.app.form.beta": "Beta-Versionen einbeziehen",
133 "settings.app.currentVersion": "Aktuelle Version:",
134 "settings.service.form.name": "Name",
135 "settings.service.form.enableService": "Dienst aktivieren",
136 "settings.service.form.enableNotification": "Benachrichtigungen aktivieren",
137 "settings.service.form.team": "Team",
138 "settings.service.form.customUrl": "Eigener Server",
139 "settings.service.form.indirectMessages": "Nachrichten-Badge für alle neuen Nachrichten anzeigen",
140 "settings.user.form.firstname": "Vorname",
141 "settings.user.form.lastname": "Nachname",
142 "settings.user.form.email": "E-Mail-Adresse",
143 "settings.user.form.currentPassword": "Aktuelles Passwort",
144 "settings.user.form.newPassword": "Neues Passwort",
145 "settings.user.form.accountType.label": "Konto-Typ",
146 "settings.user.form.accountType.individual": "Einzelperson",
147 "settings.user.form.accountType.non-profit": "Gemeinnützig",
148 "settings.user.form.accountType.company": "Unternehmen",
149 "subscription.type.free": "kostenlos",
150 "subscription.type.month": "Monat",
151 "subscription.type.year": "Jahr",
152 "subscription.type.mining": "Unterstütze Franz mit Rechenleistung",
153 "subscription.mining.headline": "Wie funktioniert das?",
154 "subscription.mining.experimental": "experimentell",
155 "subscription.mining.line1": "Durch das Aktivieren von \"Unterstützung mit Rechenleistung\", wird Franz circa 20-50% deines Prozessors nutzen, um die Crypto-Währung Monero zu minen, was ungefähr 5$/Jahr entspricht.",
156 "subscription.mining.line2": "Wir passen die Prozessor-Nutzung an Dein Arbeitsverhalten an, um Deinen Akku nicht unnötig zu belasten oder Dein System zu verlangsamen.",
157 "subscription.mining.line3": "So lange der Miner aktiv ist, hast Du unbegrenzten Zugang auf alle Franz Premium-Supporter Funktionen.",
158 "subscription.mining.moreInformation": "Erhalte mehr Informationen über diesen Plan.",
159 "subscriptionPopup.buttonCancel": "Abbrechen",
160 "subscriptionPopup.buttonDone": "Fertig",
161 "tabs.item.reload": "Neuladen",
162 "tabs.item.edit": "Bearbeiten",
163 "tabs.item.disableNotifications": "Benachrichtigungen deaktivieren",
164 "tabs.item.enableNotification": "Benachrichtigungen aktivieren",
165 "tabs.item.disableService": "Dienst deaktivieren",
166 "tabs.item.deleteService": "Dienst entfernen"
167}
diff --git a/src/i18n/locales/el-GR.json b/src/i18n/locales/el-GR.json
new file mode 100644
index 000000000..dfada77a2
--- /dev/null
+++ b/src/i18n/locales/el-GR.json
@@ -0,0 +1,168 @@
1{
2 "global.api.unhealthy": "Δεν είναι δυνατή η σύνδεση με τις online υπηρεσίες του Franz",
3 "global.notConnectedToTheInternet": "Δεν είστε συνδεδεμένοι στο διαδίκτυο.",
4 "welcome.signupButton": "Δημιουργία δωρεάν λογαριασμού",
5 "welcome.loginButton": "Σύνδεση στο λογαριασμό σας",
6 "welcome.slogan": "Μηνύματα που λειτουργούν για εσάς",
7 "login.headline": "Σύνδεση",
8 "login.email.label": "Διεύθυνση ηλεκτρονικού ταχυδρομείου",
9 "login.password.label": "Κωδικός πρόσβασης",
10 "login.submit.label": "Σύνδεση",
11 "login.invalidCredentials": "Το email ή ο κωδικός πρόσβασης δεν είναι έγκυρος",
12 "login.tokenExpired": "Η συνεδρία σας έληξε, συνδεθείτε ξανά.",
13 "login.serverLogout": "Η συνεδρία σας έληξε, συνδεθείτε ξανά.",
14 "login.link.signup": "Δημιουργία δωρεάν λογαριασμού",
15 "login.link.password": "Επαναφορά κωδικού πρόσβασης",
16 "password.headline": "Επαναφορά κωδικού πρόσβασης",
17 "password.email.label": "Διεύθυνση ηλεκτρονικού ταχυδρομείου",
18 "password.submit.label": "Υποβολή",
19 "password.noUser": "Δεν βρέθηκε χρήστης με τη συγκεκριμένη διεύθυνση ηλεκτρονικού ταχυδρομείου",
20 "password.successInfo": "Ελέγξτε το email σας",
21 "password.link.signup": "Δημιουργία δωρεάν λογαριασμού",
22 "password.link.login": "Σύνδεση στο λογαριασμό σας",
23 "signup.headline": "Εγγραφή",
24 "signup.firstname.label": "Όνομα",
25 "signup.lastname.label": "Επίθετο",
26 "signup.email.label": "Διεύθυνση ηλεκτρονικού ταχυδρομείου",
27 "signup.company.label": "Εταιρεία",
28 "signup.password.label": "Κωδικός πρόσβασης",
29 "signup.submit.label": "Δημιουργία λογαριασμού",
30 "signup.link.login": "Έχετε ήδη λογαριασμό, συνδεθείτε ?",
31 "signup.emailDuplicate": "Ένας χρήστης με τη συγκεκριμένη διεύθυνση ηλεκτρονικού ταχυδρομείου υπάρχει ήδη",
32 "signup.legal.info": "Δημιουργώντας έναν λογαριασμό Franz αποδέχεστε τους",
33 "signup.legal.terms": "Όροι υπηρεσίας",
34 "signup.legal.privacy": "Δήλωση απορρήτου",
35 "pricing.headline": "Υποστήριξη Franz",
36 "pricing.support.label": "Επιλέξτε το πακέτο υποστήριξης",
37 "pricing.submit.label": "Θέλω να βοηθήσω στήν ανάπτυξη του Franz",
38 "pricing.link.skipPayment": "Δεν θέλω να βοηθήσω στήν ανάπτυξη του Franz.",
39 "import.headline": "Εισαγάγετε τις Franz 4 υπηρεσίες σας",
40 "import.notSupportedHeadline": "Υπηρεσίες που δεν υποστηρίζονται ακόμα στο Franz 5",
41 "import.submit.label": "Υπηρεσίες εισαγωγής",
42 "import.skip.label": "Θέλω να προσθέσω υπηρεσίες χειροκίνητα",
43 "invite.submit.label": "Αποστολή προσκλήσεων",
44 "invite.headline.friends": "Προσκαλέστε 3 από τους φίλους ή τους συναδέλφους σας",
45 "invite.name.label": "Όνομα",
46 "invite.email.label": "Διεύθυνση ηλεκτρονικού ταχυδρομείου",
47 "invite.skip.label": "Θέλω να το κάνω αργότερα",
48 "subscription.submit.label": "Θέλω να βοηθήσω στήν ανάπτυξη του Franz",
49 "subscription.paymentSessionError": "Δεν ήταν δυνατή η προετοιμασία της φόρμας πληρωμής",
50 "subscription.includedFeatures": "Ο Premium λογαριασμός υποστήριξης Franz περιλαμβάνει",
51 "subscription.features.onpremise": "Add on-premise / hosted services όπως το HipChat",
52 "subscription.features.customServices": "Ιδιωτικές υπηρεσίες για εσάς και την ομάδα σας",
53 "subscription.features.encryptedSync": "Κρυπτογραφημένος συγχρονισμός περιόδου σύνδεσης",
54 "subscription.features.vpn": "Υποστήριξη μεσολαβητή (Proxy) και VPN",
55 "subscription.features.ads": "Τέλος στις διαφημίσεις, :-D",
56 "subscription.features.comingSoon": "σύντομα",
57 "infobar.servicesUpdated": "Οι υπηρεσίες σας έχουν ενημερωθεί.",
58 "infobar.updateAvailable": "Υπάρχει διαθέσιμη μια νέα ενημέρωση για τον Franz.",
59 "infobar.buttonReloadServices": "Υπηρεσίες ανανέωσης",
60 "infobar.buttonInstallUpdate": "Επανεκκίνηση & εγκατάσταση ενημερώσεων",
61 "infobar.requiredRequestsFailed": "Δεν ήταν δυνατή η φόρτωση υπηρεσιών και πληροφοριών χρηστών",
62 "sidebar.settings": "Ρυθμίσεις",
63 "services.welcome": "Καλώς ορίσατε στον Franz",
64 "services.getStarted": "Ξεκινήστε",
65 "settings.account.headline": "Λογαριασμός",
66 "settings.account.headlineSubscription": "Η συνδρομή σας",
67 "settings.account.headlineUpgrade": "Αναβάθμιση του λογαριασμού σας και υποστήριξη Franz",
68 "settings.account.headlineInvoices": "Τιμολόγια",
69 "settings.account.manageSubscription.label": "Διαχείριση της συνδρομής σας",
70 "settings.account.accountType.basic": "Βασικός λογαριασμός",
71 "settings.account.accountType.premium": "Υποστηριζόμενος λογαριασμός Premium",
72 "settings.account.account.editButton": "Επεξεργασία λογαριασμού",
73 "settings.account.invoiceDownload": "Λήψη",
74 "settings.account.userInfoRequestFailed": "Δεν ήταν δυνατή η φόρτωση πληροφοριών χρήστη",
75 "settings.account.tryReloadUserInfoRequest": "Δοκιμάστε ξανά",
76 "settings.account.headlineProfile": "Ενημέρωση προφίλ",
77 "settings.account.headlineAccount": "Πληροφορίες λογαριασμού",
78 "settings.account.headlinePassword": "Αλλαγή κωδικού πρόσβασης",
79 "settings.account.successInfo": "Οι αλλαγές σας έχουν αποθηκευτεί",
80 "settings.account.buttonSave": "Ενημέρωση προφίλ",
81 "settings.account.mining.thankyou": "Σας ευχαριστούμε για την υποστήριξη του Franz με την ισχύ επεξεργασίας σας",
82 "settings.account.mining.active": "Τώρα πραγματοποιείτε υπολογισμούς {hashes} ανά δευτερόλεπτο.",
83 "settings.account.mining.moreInformation": "Λάβετε περισσότερες πληροφορίες",
84 "settings.account.mining.cancel": "Άκυρο εξόρυξη",
85 "settings.navigation.availableServices": "Διαθέσιμες υπηρεσίες",
86 "settings.navigation.yourServices": "Οι υπηρεσίες σας",
87 "settings.navigation.account": "Λογαριασμός",
88 "settings.navigation.settings": "Ρυθμίσεις",
89 "settings.navigation.logout": "Αποσύνδεση",
90 "settings.recipes.headline": "Διαθέσιμες υπηρεσίες",
91 "settings.recipes.mostPopular": "Τα πιο δημοφιλή",
92 "settings.recipes.all": "Όλες οι υπηρεσίες",
93 "settings.recipes.dev": "Ανάπτυξη",
94 "settings.recipes.nothingFound": "Λυπούμαστε αλλά καμία υπηρεσία δεν ταιριάζει με τον όρο αναζήτησης.",
95 "settings.recipes.servicesSuccessfulAddedInfo": "Υπηρεσία προστέθηκε με επιτυχία",
96 "settings.service.form.saveButton": "Αποθήκευση υπηρεσίας",
97 "settings.service.form.deleteButton": "Διαγραφή υπηρεσίας",
98 "settings.service.form.availableServices": "Διαθέσιμες υπηρεσίες",
99 "settings.service.form.yourServices": "Οι υπηρεσίες σας",
100 "settings.service.form.addServiceHeadline": "Προσθήκη {όνομα}",
101 "settings.service.form.editServiceHeadline": "Επεξεργασία {όνομα}",
102 "settings.service.form.tabHosted": "Φιλοξενείται",
103 "settings.service.form.tabOnPremise": "Αυτο-φιλοξενείται ⭐️",
104 "settings.service.form.customUrlValidationError": "Δεν ήταν δυνατή η επικύρωση του προσαρμοσμένου διακομιστή {name}.",
105 "settings.service.form.customUrlPremiumInfo": "Για να προσθέσετε υπηρεσίες που φιλοξενούνται μόνος σας, χρειάζεστε έναν λογαριασμό υποστήριξης Premium Franz.",
106 "settings.service.form.customUrlUpgradeAccount": "Αναβάθμιση του λογαριασμού σας",
107 "settings.service.form.indirectMessageInfo": "Θα ειδοποιηθείτε για όλα τα νέα μηνύματα σε ένα κανάλι, όχι μόνο @username, @channel, @here, ...",
108 "settings.service.error.headline": "Σφάλμα",
109 "settings.service.error.goBack": "Επιστροφή στις υπηρεσίες",
110 "settings.service.error.message": "Δεν ήταν δυνατή η φόρτωση της συνταγής υπηρεσίας.",
111 "settings.services.tooltip.isDisabled": "Η υπηρεσία είναι απενεργοποιημένη",
112 "settings.services.tooltip.notificationsDisabled": "Οι ειδοποιήσεις είναι απενεργοποιημένες",
113 "settings.services.headline": "Οι υπηρεσίες σας",
114 "settings.services.noServicesAdded": "Δεν έχετε προσθέσει ακόμα υπηρεσίες.",
115 "settings.services.discoverServices": "Ανακαλύψτε τις υπηρεσίες",
116 "settings.services.updatedInfo": "Οι αλλαγές σας έχουν αποθηκευτεί",
117 "settings.services.deletedInfo": "Η υπηρεσία έχει διαγραφεί",
118 "settings.app.headline": "Ρυθμίσεις",
119 "settings.app.headlineΓενικά": "Γενικά",
120 "settings.app.headlineLanguage": "Γλώσσα",
121 "settings.app.headlineUpdates": "Ενημερώσεις",
122 "settings.app.buttonSearchForUpdate": "Έλεγχος για ενημερώσεις",
123 "settings.app.buttonInstallUpdate": "Επανεκκίνηση & εγκατάσταση ενημερώσεων",
124 "settings.app.updateStatusSearching": "Ψάχνει για ενημέρωση",
125 "settings.app.updateStatusAvailable": "Διαθέσιμη ενημέρωση, λήψη ...",
126 "settings.app.updateStatusUpToDate": "Χρησιμοποιείτε την τελευταία έκδοση του Franz",
127 "settings.app.form.autoLaunchOnStart": "Εκκίνηση του Franz στην αρχή",
128 "settings.app.form.autoLaunchInBackground": "Άνοιγμα στο παρασκήνιο",
129 "settings.app.form.enableSystemTray": "Εμφάνιση του Franz στο δίσκο συστήματος",
130 "settings.app.form.minimizeToSystemTray": "Ελαχιστοποίηση του Franz στο δίσκο συστήματος",
131 "settings.app.form.runInBackground": "Κρατήστε Franz στο παρασκήνιο κατά το κλείσιμο του παραθύρου",
132 "settings.app.form.language": "Γλώσσα",
133 "settings.app.form.beta": "Συμπεριλάβετε εκδόσεις beta",
134 "settings.app.currentVersion": "Τρέχουσα έκδοση:",
135 "settings.service.form.name": "Όνομα",
136 "settings.service.form.enableService": "Ενεργοποίηση υπηρεσίας",
137 "settings.service.form.enableNotification": "Ενεργοποίηση ειδοποιήσεων",
138 "settings.service.form.team": "Ομάδα",
139 "settings.service.form.customUrl": "Προσαρμοσμένος διακομιστής",
140 "settings.service.form.indirectMessages": "Εμφάνιση ειδοποίησης μηνύματος για όλα τα νέα μηνύματα",
141 "settings.user.form.firstname": "Όνομα",
142 "settings.user.form.lastname": "Επίθετο",
143 "settings.user.form.email": "Email",
144 "settings.user.form.currentPassword": "Τρέχων κωδικός πρόσβασης",
145 "settings.user.form.newPassword": "Νέος κωδικός πρόσβασης",
146 "settings.user.form.accountType.label": "Τύπος λογαριασμού",
147 "settings.user.form.accountType.individual": "Ατομική",
148 "settings.user.form.accountType.non-profit": "Μη κερδοσκοπικό",
149 "settings.user.form.accountType.company": "Εταιρεία",
150 "subscription.type.free": "δωρεάν",
151 "subscription.type.month": "μήνας",
152 "subscription.type.year": "έτος",
153 "subscription.type.mining": "Υποστήριξη Franz με ισχύ CPU",
154 "subscription.mining.headline": "Πώς λειτουργεί αυτό;",
155 "subscription.mining.experimental": "πειραματική",
156 "subscription.mining.line1": "Franz χρησιμοποιεί περίπου το 20-50% της CPU σας για να εξορύξει την κρυπτογράφηση Monero που ισούται περίπου με $ 5 / έτος.",
157 "subscription.mining.line2": "Θα προσαρμόσουμε τη χρήση της CPU με βάση τη συμπεριφορά εργασίας σας ώστε να μην αποστραγγίσουμε την μπαταρία σας και να επιβραδύνουμε εσάς και το μηχάνημά σας.",
158 "subscription.mining.line3": "Εφόσον ο Miner είναι ενεργός, θα έχετε απεριόριστη πρόσβαση σε όλα τα χαρακτηριστικά του Franz Premium Supporter.",
159 "subscription.mining.moreInformation": "Λάβετε περισσότερες πληροφορίες σχετικά με αυτό το πακέτο.",
160 "subscriptionPopup.buttonCancel": "Ακύρωση",
161 "subscriptionPopup.buttonDone": "Έγινε",
162 "tabs.item.reload": "Επαναφόρτωση",
163 "tabs.item.edit": "Επεξεργασία",
164 "tabs.item.disableNotifications": "Απενεργοποίηση ειδοποιήσεων",
165 "tabs.item.enableNotification": "Ενεργοποίηση ειδοποιήσεων",
166 "tabs.item.disableService": "Απενεργοποίηση υπηρεσίας",
167 "tabs.item.deleteService": "Διαγραφή υπηρεσίας"
168}
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json
index 194b8047c..b9ed51b83 100644
--- a/src/i18n/locales/en-US.json
+++ b/src/i18n/locales/en-US.json
@@ -126,6 +126,7 @@
126 "settings.app.updateStatusUpToDate": "You are using the latest version of Franz", 126 "settings.app.updateStatusUpToDate": "You are using the latest version of Franz",
127 "settings.app.form.autoLaunchOnStart": "Launch Franz on start", 127 "settings.app.form.autoLaunchOnStart": "Launch Franz on start",
128 "settings.app.form.autoLaunchInBackground": "Open in background", 128 "settings.app.form.autoLaunchInBackground": "Open in background",
129 "settings.app.form.enableSystemTray": "Show Franz in system tray",
129 "settings.app.form.minimizeToSystemTray": "Minimize Franz to system tray", 130 "settings.app.form.minimizeToSystemTray": "Minimize Franz to system tray",
130 "settings.app.form.runInBackground": "Keep Franz in background when closing the window", 131 "settings.app.form.runInBackground": "Keep Franz in background when closing the window",
131 "settings.app.form.language": "Language", 132 "settings.app.form.language": "Language",
diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json
new file mode 100644
index 000000000..84cf54492
--- /dev/null
+++ b/src/i18n/locales/fr.json
@@ -0,0 +1,167 @@
1{
2 "global.api.unhealthy": "Impossible de se connecter aux services en ligne de Franz",
3 "global.notConnectedToTheInternet": "Vous n'êtes pas connecté à Internet.",
4 "welcome.signupButton": "Créer un compte gratuitement",
5 "welcome.loginButton": "Connectez-vous à votre compte",
6 "welcome.slogan": "Une messagerie qui fonctionne pour vous",
7 "login.headline": "S'inscrire",
8 "login.email.label": "Adresse e-mail",
9 "login.password.label": "Mot de passe",
10 "login.submit.label": "Se connecter",
11 "login.invalidCredentials": "E-mail ou mot de passe invalide",
12 "login.tokenExpired": "Votre session a expiré, veuillez vous reconnecter.",
13 "login.serverLogout": "Votre session a expiré, veuillez vous reconnecter.",
14 "login.link.signup": "Créer un compte gratuitement",
15 "login.link.password": "Réinitialiser le mot de passe",
16 "password.headline": "Réinitialiser le mot de passe",
17 "password.email.label": "Adresse e-mail",
18 "password.submit.label": "Soumettre",
19 "password.noUser": "Aucun utilisateur avec cette adresse e-mail n'a été trouvé",
20 "password.successInfo": "Merci de consulter vos e-mails",
21 "password.link.signup": "Créer un compte gratuitement",
22 "password.link.login": "Connectez-vous à votre compte",
23 "signup.headline": "S'inscrire",
24 "signup.firstname.label": "Prénom",
25 "signup.lastname.label": "Nom",
26 "signup.email.label": "Adresse e-mail",
27 "signup.company.label": "Compagnie",
28 "signup.password.label": "Mot de passe",
29 "signup.submit.label": "Créer un compte",
30 "signup.link.login": "Vous possédez déjà un compte ? Connectez-vous",
31 "signup.emailDuplicate": "Un utilisateur avec cette adresse e-mail existe déjà",
32 "signup.legal.info": "En créant un compte Franz, vous acceptez les",
33 "signup.legal.terms": "Conditions d'utilisation",
34 "signup.legal.privacy": "Déclaration de confidentialité",
35 "pricing.headline": "Supportez Franz",
36 "pricing.support.label": "Sélectionnez votre plan de soutien",
37 "pricing.submit.label": "Je veux soutenir le développement de Franz",
38 "pricing.link.skipPayment": "Je ne veux pas soutenir le développement de Franz.",
39 "import.headline": "Importez vos services depuis Franz 4",
40 "import.notSupportedHeadline": "Services non supportés actuellement dans Franz 5",
41 "import.submit.label": "Importer des services",
42 "import.skip.label": "Je veux ajouter des services manuellement",
43 "invite.submit.label": "Envoyer des invitations",
44 "invite.headline.friends": "Invitez 3 de vos amis ou collègues",
45 "invite.name.label": "Nom",
46 "invite.email.label": "Adresse e-mail",
47 "invite.skip.label": "Je veux faire cela plus tard",
48 "subscription.submit.label": "Je veux soutenir le développement de Franz",
49 "subscription.paymentSessionError": "Impossible d'initialiser le formulaire de paiement",
50 "subscription.includedFeatures": "Le compte payant Supporter Premium Franz inclut",
51 "subscription.features.onpremise": "Add on-premise/hosted services like HipChat",
52 "subscription.features.customServices": "Des services privés pour vous et votre équipe",
53 "subscription.features.encryptedSync": "Synchronisation de session chiffrée",
54 "subscription.features.vpn": "Support des Proxy et VPN",
55 "subscription.features.ads": "Aucune publicité !",
56 "subscription.features.comingSoon": "arrive bientôt",
57 "infobar.servicesUpdated": "Vos services ont été mis à jour.",
58 "infobar.updateAvailable": "Une nouvelle mise à jour est disponible pour Franz.",
59 "infobar.buttonReloadServices": "Recharger les services",
60 "infobar.buttonInstallUpdate": "Redémarrer et installer la mise à jour",
61 "infobar.requiredRequestsFailed": "Impossible de charger les services et les informations de l'utilisateur",
62 "sidebar.settings": "Paramètres",
63 "services.welcome": "Bienvenue sur Franz",
64 "services.getStarted": "Commencer",
65 "settings.account.headline": "Compte",
66 "settings.account.headlineSubscription": "Votre abonnement",
67 "settings.account.headlineUpgrade": "Améliorez votre compte et supportez Franz",
68 "settings.account.headlineInvoices": "Factures",
69 "settings.account.manageSubscription.label": "Gérer votre abonnement",
70 "settings.account.accountType.basic": "Compte basique",
71 "settings.account.accountType.premium": "Compte Supporter Premium",
72 "settings.account.account.editButton": "Modifier le compte",
73 "settings.account.invoiceDownload": "Télécharger",
74 "settings.account.userInfoRequestFailed": "Impossible de charger les informations de l'utilisateur",
75 "settings.account.tryReloadUserInfoRequest": "Réessayer",
76 "settings.account.headlineProfile": "Mettre à jour le profil",
77 "settings.account.headlineAccount": "Informations de compte",
78 "settings.account.headlinePassword": "Changer le mot de passe",
79 "settings.account.successInfo": "Vos modifications ont été enregistrées",
80 "settings.account.buttonSave": "Mettre à jour le profil",
81 "settings.account.mining.thankyou": "Merci de soutenir Franz avec votre puissance de calcul.",
82 "settings.account.mining.active": "Vous êtes en train d'effectuer {hashes} calculs par seconde.",
83 "settings.account.mining.moreInformation": "Obtenir plus d'informations",
84 "settings.account.mining.cancel": "Annuler le minage",
85 "settings.navigation.availableServices": "Services disponibles",
86 "settings.navigation.yourServices": "Vos services",
87 "settings.navigation.account": "Compte",
88 "settings.navigation.settings": "Paramètres",
89 "settings.navigation.logout": "Se déconnecter",
90 "settings.recipes.headline": "Services disponibles",
91 "settings.recipes.mostPopular": "Les plus populaires",
92 "settings.recipes.all": "Tous les services",
93 "settings.recipes.dev": "Développement",
94 "settings.recipes.nothingFound": "Désolé, aucun service ne correspond à votre recherche.",
95 "settings.recipes.servicesSuccessfulAddedInfo": "Service ajouté avec succès",
96 "settings.service.form.saveButton": "Enregistrer le service",
97 "settings.service.form.deleteButton": "Supprimer le service",
98 "settings.service.form.availableServices": "Services disponibles",
99 "settings.service.form.yourServices": "Vos services",
100 "settings.service.form.addServiceHeadline": "Ajouter {name}",
101 "settings.service.form.editServiceHeadline": "Modifier {name}",
102 "settings.service.form.tabHosted": "Hébergé",
103 "settings.service.form.tabOnPremise": "Auto-hébergé ⭐️",
104 "settings.service.form.customUrlValidationError": "Impossible de valider le {name} personnalisé du serveur.",
105 "settings.service.form.customUrlPremiumInfo": "Pour ajouter des services auto-hébergés, vous avez besoin d'un compte Supporter Premium Franz.",
106 "settings.service.form.customUrlUpgradeAccount": "Améliorez votre compte",
107 "settings.service.form.indirectMessageInfo": "Vous serez averti de tous les nouveaux messages dans un salon, pas seulement @username, @channel, @here, ...",
108 "settings.service.error.headline": "Erreur",
109 "settings.service.error.goBack": "Retour aux services",
110 "settings.service.error.message": "Could not load service recipe.",
111 "settings.services.tooltip.isDisabled": "Le service est désactivé",
112 "settings.services.tooltip.notificationsDisabled": "Les notifications sont désactivées",
113 "settings.services.headline": "Vos services",
114 "settings.services.noServicesAdded": "Vous n'avez pas encore ajouté de services.",
115 "settings.services.discoverServices": "Découvrir des services",
116 "settings.services.updatedInfo": "Vos modifications ont été enregistrées",
117 "settings.services.deletedInfo": "Le service a été supprimé",
118 "settings.app.headline": "Paramètres",
119 "settings.app.headlineGeneral": "Général",
120 "settings.app.headlineLanguage": "Langue",
121 "settings.app.headlineUpdates": "Mises à jour",
122 "settings.app.buttonSearchForUpdate": "Vérifier les mises à jour",
123 "settings.app.buttonInstallUpdate": "Redémarrer et installer la mise à jour",
124 "settings.app.updateStatusSearching": "Recherche des mises à jour",
125 "settings.app.updateStatusAvailable": "Mise à jour disponible, téléchargement...",
126 "settings.app.updateStatusUpToDate": "Vous utilisez la dernière version de Franz",
127 "settings.app.form.autoLaunchOnStart": "Lancer Franz au démarrage",
128 "settings.app.form.autoLaunchInBackground": "Ouvrir en arrière-plan",
129 "settings.app.form.minimizeToSystemTray": "Minimiser Franz dans la zone de notification",
130 "settings.app.form.runInBackground": "Gardez Franz en arrière-plan lors de la fermeture de la fenêtre",
131 "settings.app.form.language": "Langue",
132 "settings.app.form.beta": "Inclure les versions bêta",
133 "settings.app.currentVersion": "Version actuelle :",
134 "settings.service.form.name": "Nom",
135 "settings.service.form.enableService": "Activer le service",
136 "settings.service.form.enableNotification": "Activer les notifications",
137 "settings.service.form.team": "Équipe",
138 "settings.service.form.customUrl": "Serveur personnalisé",
139 "settings.service.form.indirectMessages": "Afficher le badge des messages pour tous les nouveaux messages",
140 "settings.user.form.firstname": "Prénom",
141 "settings.user.form.lastname": "Nom",
142 "settings.user.form.email": "E-mail",
143 "settings.user.form.currentPassword": "Mot de passe actuel",
144 "settings.user.form.newPassword": "Nouveau mot de passe",
145 "settings.user.form.accountType.label": "Type de compte",
146 "settings.user.form.accountType.individual": "Individuel",
147 "settings.user.form.accountType.non-profit": "Non lucratif",
148 "settings.user.form.accountType.company": "Compagnie",
149 "subscription.type.free": "gratuit",
150 "subscription.type.month": "mois",
151 "subscription.type.year": "année",
152 "subscription.type.mining": "Soutenez Franz avec de la puissance de calcul",
153 "subscription.mining.headline": "Comment cela fonctionne-t-il?",
154 "subscription.mining.experimental": "expérimental",
155 "subscription.mining.line1": "En activant \"Soutenez Franz avec de la puissance de calcul\", Franz utilisera environ de 20 à 50% de votre CPU pour miner la crypto-monnaie Monero, ce qui équivaut à environ 5$/an.",
156 "subscription.mining.line2": "Nous adapterons l'utilisation du processeur en fonction de vos habitudes de travail pour ne pas vider votre batterie et ne pas ralentir votre machine.",
157 "subscription.mining.line3": "Tant que le minage est actif, vous aurez un accès illimité à toutes les fonctionnalités Supporter Premium Franz.",
158 "subscription.mining.moreInformation": "Obtenir plus d'informations.",
159 "subscriptionPopup.buttonCancel": "Annuler",
160 "subscriptionPopup.buttonDone": "Terminé",
161 "tabs.item.reload": "Recharger",
162 "tabs.item.edit": "Modifier",
163 "tabs.item.disableNotifications": "Désactiver les notifications",
164 "tabs.item.enableNotification": "Activer les notifications",
165 "tabs.item.disableService": "Désactiver le service",
166 "tabs.item.deleteService": "Supprimer le service"
167}
diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json
new file mode 100644
index 000000000..a283154c9
--- /dev/null
+++ b/src/i18n/locales/ja.json
@@ -0,0 +1,167 @@
1{
2 "global.api.unhealthy": "Franzオンラインサービスに接続できません。",
3 "global.notConnectedToTheInternet": "Internetに接続されていません。",
4 "welcome.signupButton": "無料アカウントを作成",
5 "welcome.loginButton": "アカウントにログイン",
6 "welcome.slogan": "Messaging that works for you",
7 "login.headline": "サインイン",
8 "login.email.label": "メールアドレス",
9 "login.password.label": "パスワード",
10 "login.submit.label": "サインイン",
11 "login.invalidCredentials": "メールアドレスかパスワードに誤りがあります。",
12 "login.tokenExpired": "セッションが切れました。ログインし直して下さい。",
13 "login.serverLogout": "セッションが切れました。ログインし直して下さい。",
14 "login.link.signup": "無料アカウントを作成",
15 "login.link.password": "パスワードをリセット",
16 "password.headline": "パスワードをリセット",
17 "password.email.label": "メールアドレス",
18 "password.submit.label": "送信",
19 "password.noUser": "このメールアドレスは登録されていません",
20 "password.successInfo": "メールを確認して下さい",
21 "password.link.signup": "無料アカウントを作成",
22 "password.link.login": "サインイン",
23 "signup.headline": "アカウントの作成",
24 "signup.firstname.label": "名",
25 "signup.lastname.label": "姓",
26 "signup.email.label": "メールアドレス",
27 "signup.company.label": "会社名",
28 "signup.password.label": "パスワード",
29 "signup.submit.label": "作成する",
30 "signup.link.login": "アカウントを既に持っていますか? こちらからサインイン",
31 "signup.emailDuplicate": "このメールアドレスは既に登録されています",
32 "signup.legal.info": "Franzアカウントを作成することで、以下の規約に同意したものとみなします",
33 "signup.legal.terms": "利用規約",
34 "signup.legal.privacy": "プライバシーについて",
35 "pricing.headline": "Franzを支援する",
36 "pricing.support.label": "プランを選択して下さい",
37 "pricing.submit.label": "Franzの開発を支援したい",
38 "pricing.link.skipPayment": "Franzの開発を支援しない",
39 "import.headline": "Franz 4サービスのインポート",
40 "import.notSupportedHeadline": "サービスの機能はFranz 5ではまだ対応されていません",
41 "import.submit.label": "サービスのインポート",
42 "import.skip.label": "サービスの追加は後で行う",
43 "invite.submit.label": "招待を送る",
44 "invite.headline.friends": "あなたの友人や同僚の方を3名までFranzに招待できます",
45 "invite.name.label": "氏名",
46 "invite.email.label": "メールアドレス",
47 "invite.skip.label": "後にする",
48 "subscription.submit.label": "Franzの開発を支援したい",
49 "subscription.paymentSessionError": "支払いフォームを初期化出来ません",
50 "subscription.includedFeatures": "Franz Premium Supporter有料アカウントには以下が含まれます",
51 "subscription.features.onpremise": "HipChatのようなオンプレミス/ホスト型サービスの追加",
52 "subscription.features.customServices": "あなたとあなたのチームのためのプライベートサービス",
53 "subscription.features.encryptedSync": "暗号化されたセッションの同期",
54 "subscription.features.vpn": "プロキシサーバーとVPNのサポート",
55 "subscription.features.ads": "広告は一切ありません!",
56 "subscription.features.comingSoon": "まもなく登場",
57 "infobar.servicesUpdated": "サービスが更新されました",
58 "infobar.updateAvailable": "Franzの新しい更新があります",
59 "infobar.buttonReloadServices": "Serviceのリロード",
60 "infobar.buttonInstallUpdate": "再起動して更新をインストールする",
61 "infobar.requiredRequestsFailed": "サービスとユーザー情報が読み込めません",
62 "sidebar.settings": "設定",
63 "services.welcome": "Franzにようこそ",
64 "services.getStarted": "はじめる",
65 "settings.account.headline": "アカウント",
66 "settings.account.headlineSubscription": "サブスクリプション内容",
67 "settings.account.headlineUpgrade": "アカウントをアップグレードし、Franzを支援する",
68 "settings.account.headlineInvoices": "Invoices",
69 "settings.account.manageSubscription.label": "サブスクリプションの管理",
70 "settings.account.accountType.basic": "Basicアカウント",
71 "settings.account.accountType.premium": "Premium Supporterアカウント",
72 "settings.account.account.editButton": "アカウントを編集する",
73 "settings.account.invoiceDownload": "ダウンロード",
74 "settings.account.userInfoRequestFailed": "ユーザー情報が読み込めません",
75 "settings.account.tryReloadUserInfoRequest": "リトライ",
76 "settings.account.headlineProfile": "プロフィールを更新する",
77 "settings.account.headlineAccount": "アカウント情報",
78 "settings.account.headlinePassword": "パスワードを変更する",
79 "settings.account.successInfo": "変更内容が保存されました",
80 "settings.account.buttonSave": "プロフィールを更新",
81 "settings.account.mining.thankyou": "お使いのPCの処理能力をFranzの支援に活用して頂き、ありがとうございます。",
82 "settings.account.mining.active": "1秒あたり{hashes}個のハッシュを計算中です。",
83 "settings.account.mining.moreInformation": "詳細を確認する",
84 "settings.account.mining.cancel": "マイニングをキャンセルする",
85 "settings.navigation.availableServices": "利用可能なサービス",
86 "settings.navigation.yourServices": "利用中のサービス",
87 "settings.navigation.account": "アカウント",
88 "settings.navigation.settings": "設定",
89 "settings.navigation.logout": "ログアウト",
90 "settings.recipes.headline": "利用可能なサービス",
91 "settings.recipes.mostPopular": "最も人気",
92 "settings.recipes.all": "全てのサービス",
93 "settings.recipes.dev": "開発版",
94 "settings.recipes.nothingFound": "すみませんが、検索ワードに該当するサービスが見つかりませんでした。",
95 "settings.recipes.servicesSuccessfulAddedInfo": "サービスが追加されました",
96 "settings.service.form.saveButton": "サービスを保存する",
97 "settings.service.form.deleteButton": "サービスを削除する",
98 "settings.service.form.availableServices": "利用可能なサービス",
99 "settings.service.form.yourServices": "利用中のサービス",
100 "settings.service.form.addServiceHeadline": "{name}を追加",
101 "settings.service.form.editServiceHeadline": "{name}を編集",
102 "settings.service.form.tabHosted": "ホスト",
103 "settings.service.form.tabOnPremise": "セルフホスト ⭐️",
104 "settings.service.form.customUrlValidationError": "カスタムサービス{name}を検証できませんでした。",
105 "settings.service.form.customUrlPremiumInfo": "独自サービスを追加するためには、Franz Premium Supporterアカウントが必要です。",
106 "settings.service.form.customUrlUpgradeAccount": "アカウントをアップグレードする",
107 "settings.service.form.indirectMessageInfo": "@username、@channel、@hereだけでなく、チャンネル内のすべての新規メッセージについて通知されます。",
108 "settings.service.error.headline": "エラー",
109 "settings.service.error.goBack": "サービスに戻る",
110 "settings.service.error.message": "サービスのレシピが読み込めません。",
111 "settings.services.tooltip.isDisabled": "サービスが無効です",
112 "settings.services.tooltip.notificationsDisabled": "通知が無効です",
113 "settings.services.headline": "利用中のサービス",
114 "settings.services.noServicesAdded": "まだ、どのサービスも追加されていません。",
115 "settings.services.discoverServices": "サービスを見つける",
116 "settings.services.updatedInfo": "変更内容が保存されました",
117 "settings.services.deletedInfo": "サービスが削除されました",
118 "settings.app.headline": "設定",
119 "settings.app.headlineGeneral": "一般",
120 "settings.app.headlineLanguage": "言語",
121 "settings.app.headlineUpdates": "更新",
122 "settings.app.buttonSearchForUpdate": "更新の確認",
123 "settings.app.buttonInstallUpdate": "再起動して更新をインストール",
124 "settings.app.updateStatusSearching": "更新を確認中",
125 "settings.app.updateStatusAvailable": "更新が見つかりました。ダウンロードしています...",
126 "settings.app.updateStatusUpToDate": "お使いのFranzは最新です",
127 "settings.app.form.autoLaunchOnStart": "システム起動時にFranzを開く",
128 "settings.app.form.autoLaunchInBackground": "バックグラウンドで開く",
129 "settings.app.form.minimizeToSystemTray": "Franzをシステムトレイに最小化する",
130 "settings.app.form.runInBackground": "ウインドウを閉じた際にFranzをバックグラウンドで実行させておく",
131 "settings.app.form.language": "言語",
132 "settings.app.form.beta": "Betaバージョンを含める",
133 "settings.app.currentVersion": "現在のバージョン:",
134 "settings.service.form.name": "サービス名",
135 "settings.service.form.enableService": "サービスを有効にする",
136 "settings.service.form.enableNotification": "通知を有効にする",
137 "settings.service.form.team": "チーム",
138 "settings.service.form.customUrl": "カスタムサーバー",
139 "settings.service.form.indirectMessages": "すべての新規メッセージについてバッジを表示する",
140 "settings.user.form.firstname": "名",
141 "settings.user.form.lastname": "姓",
142 "settings.user.form.email": "メールアドレス",
143 "settings.user.form.currentPassword": "現在のパスワード",
144 "settings.user.form.newPassword": "新しいパスワード",
145 "settings.user.form.accountType.label": "アカウントの種類",
146 "settings.user.form.accountType.individual": "個人",
147 "settings.user.form.accountType.non-profit": "非営利",
148 "settings.user.form.accountType.company": "法人",
149 "subscription.type.free": "無料",
150 "subscription.type.month": "月間",
151 "subscription.type.year": "年間",
152 "subscription.type.mining": "PCの処理能力を使ってFranzを支援する",
153 "subscription.mining.headline": "これはどのように動作しているか",
154 "subscription.mining.experimental": "実験的",
155 "subscription.mining.line1": "\"PCの処理能力を使ってFranzを支援する\"を有効にすることで、Franzはおよそ20-50%のCPUパワーを暗号通貨Moneroのマイニングに使用し、これはおよそ年間で5ドル分にあたります。",
156 "subscription.mining.line2": "処理能力に基づいてCPUの使用率を適応しますのでバッテリーを無駄に消費したり、システムを遅くすることはありません。",
157 "subscription.mining.line3": "マイニングが機能している限り、Franz Premium Supporterの全ての機能を無制限で利用できます。",
158 "subscription.mining.moreInformation": "このプランの詳細を確認する。",
159 "subscriptionPopup.buttonCancel": "キャンセルしました",
160 "subscriptionPopup.buttonDone": "完了しました",
161 "tabs.item.reload": "リロード",
162 "tabs.item.edit": "編集",
163 "tabs.item.disableNotifications": "通知を無効にする",
164 "tabs.item.enableNotification": "通知を有効にする",
165 "tabs.item.disableService": "サービスを無効にする",
166 "tabs.item.deleteService": "サービスを削除する"
167}
diff --git a/src/i18n/locales/nl-BE.json b/src/i18n/locales/nl-BE.json
new file mode 100644
index 000000000..40cc14c50
--- /dev/null
+++ b/src/i18n/locales/nl-BE.json
@@ -0,0 +1,167 @@
1{
2 "global.api.unhealthy": "Kan geen verbinding maken met de Franz online services",
3 "global.notConnectedToTheInternet": "Je bent niet verbonden met het internet.",
4 "welcome.signupButton": "Maak een gratis account aan",
5 "welcome.loginButton": "Inloggen op je account",
6 "welcome.slogan": "Messaging that works for you",
7 "login.headline": "Inloggen",
8 "login.email.label": "E-mailadres",
9 "login.password.label": "Wachtwoord",
10 "login.submit.label": "Log in",
11 "login.invalidCredentials": "E-mailadres of wachtwoord ongeldig",
12 "login.tokenExpired": "Je sessie is verlopen, log opnieuw in a.u.b..",
13 "login.serverLogout": "Je sessie is verlopen, log opnieuw in a.u.b..",
14 "login.link.signup": "Gratis account aanmaken",
15 "login.link.password": "Wachtwoord resetten",
16 "password.headline": "Wachtwoord resetten",
17 "password.email.label": "E-mailadres",
18 "password.submit.label": "Doorgaan",
19 "password.noUser": "Geen gebruiker met dit e-mailadres gevonden",
20 "password.successInfo": "Kijk je mail na",
21 "password.link.signup": "Gratis account aanmaken",
22 "password.link.login": "Inloggen op je account",
23 "signup.headline": "Registreren",
24 "signup.firstname.label": "Naam",
25 "signup.lastname.label": "Achternaam",
26 "signup.email.label": "E-mailadres",
27 "signup.company.label": "Bedrijf",
28 "signup.password.label": "Wachtwoord",
29 "signup.submit.label": "Account aanmaken",
30 "signup.link.login": "Al een account, inloggen?",
31 "signup.emailDuplicate": "Er bestaat reeds een gebruiker met dat e-mailadres",
32 "signup.legal.info": "Door een account aan te maken aanvaard je de",
33 "signup.legal.terms": "Servicevoorwaarden",
34 "signup.legal.privacy": "Privacyverklaring",
35 "pricing.headline": "Franz Steunen",
36 "pricing.support.label": "Selecteer je steunplan",
37 "pricing.submit.label": "Ik wil de ontwikkeling van Franz steunen",
38 "pricing.link.skipPayment": "Ik wil de ontwikkeling van Franz niet steunen.",
39 "import.headline": "Je Franz 4 services importeren",
40 "import.notSupportedHeadline": "Services nog niet ondersteund in Franz 5",
41 "import.submit.label": "Services importeren",
42 "import.skip.label": "Ik wil services handmatig toevoegen",
43 "invite.submit.label": "Uitnodiging sturen",
44 "invite.headline.friends": "3 van je vrienden of collega's uitnodigen",
45 "invite.name.label": "Naam",
46 "invite.email.label": "E-mailadres",
47 "invite.skip.label": "Ik wil dit later doen",
48 "subscription.submit.label": "Ik wil de ontwikkeling van Franz steunen",
49 "subscription.paymentSessionError": "Betalingsformulier kon niet geladen worden",
50 "subscription.includedFeatures": "Een betalend account voor Franz omvat",
51 "subscription.features.onpremise": "Intern gehoste services zoals HipChat",
52 "subscription.features.customServices": "Persoonlijke services voor jou en je team",
53 "subscription.features.encryptedSync": "Synchronisatie van geëncrypteerde sessies",
54 "subscription.features.vpn": "Proxy & VPN ondersteuning",
55 "subscription.features.ads": "Geen reclame, nooit!",
56 "subscription.features.comingSoon": "komt binnenkort",
57 "infobar.servicesUpdated": "Je services zijn geüpdated.",
58 "infobar.updateAvailable": "Er is een nieuwe update van Franz beschikbaar.",
59 "infobar.buttonReloadServices": "Services herladen",
60 "infobar.buttonInstallUpdate": "Herstarten & update installeren",
61 "infobar.requiredRequestsFailed": "Kon services en gebruikersinformatie niet laden",
62 "sidebar.settings": "Instellingen",
63 "services.welcome": "Welkom bij Franz",
64 "services.getStarted": "Begin",
65 "settings.account.headline": "Account",
66 "settings.account.headlineSubscription": "Je abonnement",
67 "settings.account.headlineUpgrade": "Upgrade je account & ondersteun Franz",
68 "settings.account.headlineInvoices": "Facturen",
69 "settings.account.manageSubscription.label": "Je abonnement beheren",
70 "settings.account.accountType.basic": "Basisaccount",
71 "settings.account.accountType.premium": "Premium Supporter Account",
72 "settings.account.account.editButton": "Account aanpassen",
73 "settings.account.invoiceDownload": "Downloaden",
74 "settings.account.userInfoRequestFailed": "Kon de gebruikersinformatie niet laden",
75 "settings.account.tryReloadUserInfoRequest": "Probeer opnieuw",
76 "settings.account.headlineProfile": "Profiel aanpassen",
77 "settings.account.headlineAccount": "Accountinformatie",
78 "settings.account.headlinePassword": "Wachtwoord veranderen",
79 "settings.account.successInfo": "Je wijzigingen werden bewaard",
80 "settings.account.buttonSave": "Profiel aanpassen",
81 "settings.account.mining.thankyou": "Bedankt om Franz te steunen met je rekenkracht.",
82 "settings.account.mining.active": "Op dit moment maak je {hashes} berekeningen per seconde.",
83 "settings.account.mining.moreInformation": "Meer informatie",
84 "settings.account.mining.cancel": "Mijnen annuleren",
85 "settings.navigation.availableServices": "Beschikbare services",
86 "settings.navigation.yourServices": "Jouw services",
87 "settings.navigation.account": "Account",
88 "settings.navigation.settings": "Instellingen",
89 "settings.navigation.logout": "Uitloggen",
90 "settings.recipes.headline": "Beschikbare services",
91 "settings.recipes.mostPopular": "Meest populair",
92 "settings.recipes.all": "Alle services",
93 "settings.recipes.dev": "Ontwikkeling",
94 "settings.recipes.nothingFound": "Sorry, maar geen enkele service kwam overeen met je zoekterm.",
95 "settings.recipes.servicesSuccessfulAddedInfo": "Service succesvol toegevoegd",
96 "settings.service.form.saveButton": "Service bewaren",
97 "settings.service.form.deleteButton": "Service verwijderen",
98 "settings.service.form.availableServices": "Beschikbare services",
99 "settings.service.form.yourServices": "Jouw services",
100 "settings.service.form.addServiceHeadline": "{name} toevoegen",
101 "settings.service.form.editServiceHeadline": "{name} aanpassen",
102 "settings.service.form.tabHosted": "Gehost",
103 "settings.service.form.tabOnPremise": "Intern gehost ⭐️",
104 "settings.service.form.customUrlValidationError": "Kon de custom {name} server niet valideren.",
105 "settings.service.form.customUrlPremiumInfo": "Om intern gehoste services toe te voegen heb je een Franz Premium Supporter Account nodig.",
106 "settings.service.form.customUrlUpgradeAccount": "Je account upgraden",
107 "settings.service.form.indirectMessageInfo": "Je wordt verwittigd over alle nieuwe berichten in een kanaal, niet alleen @username, @channel, @here, ...",
108 "settings.service.error.headline": "Fout",
109 "settings.service.error.goBack": "Terug naar de services",
110 "settings.service.error.message": "Kon het service-recept niet laden.",
111 "settings.services.tooltip.isDisabled": "Service staat uit",
112 "settings.services.tooltip.notificationsDisabled": "Notificaties staan uit",
113 "settings.services.headline": "Jouw services",
114 "settings.services.noServicesAdded": "Je hebt nog geen services toegevoegd.",
115 "settings.services.discoverServices": "Services ontdekken",
116 "settings.services.updatedInfo": "Je veranderingen werden bewaard",
117 "settings.services.deletedInfo": "Service werd verwijderd",
118 "settings.app.headline": "Instellingen",
119 "settings.app.headlineGeneral": "Algemeen",
120 "settings.app.headlineLanguage": "Talen",
121 "settings.app.headlineUpdates": "Updates",
122 "settings.app.buttonSearchForUpdate": "Controleren op updates",
123 "settings.app.buttonInstallUpdate": "Herstart & installeer update",
124 "settings.app.updateStatusSearching": "Zoeken naar updates",
125 "settings.app.updateStatusAvailable": "Update beschikbaar, wordt gedownload...",
126 "settings.app.updateStatusUpToDate": "Je gebruikt de laatste versie van Franz",
127 "settings.app.form.autoLaunchOnStart": "Franz lanceren bij het starten",
128 "settings.app.form.autoLaunchInBackground": "In de achtergrond openen",
129 "settings.app.form.minimizeToSystemTray": "Franz naar je systeemvak minimaliseren",
130 "settings.app.form.runInBackground": "Franz in de achtergrond draaien wanneer je het venster sluit",
131 "settings.app.form.language": "Taal",
132 "settings.app.form.beta": "Ook beta versies",
133 "settings.app.currentVersion": "Huidige versie:",
134 "settings.service.form.name": "Naam",
135 "settings.service.form.enableService": "Service aanzetten",
136 "settings.service.form.enableNotification": "Notificaties aanzetten",
137 "settings.service.form.team": "Team",
138 "settings.service.form.customUrl": "Aangepaste server",
139 "settings.service.form.indirectMessages": "Toon berichten-badge voor alle nieuwe berichten",
140 "settings.user.form.firstname": "Naam",
141 "settings.user.form.lastname": "Achternaam",
142 "settings.user.form.email": "Email",
143 "settings.user.form.currentPassword": "Huidig wachtwoord",
144 "settings.user.form.newPassword": "Nieuw wachtwoord",
145 "settings.user.form.accountType.label": "Account type",
146 "settings.user.form.accountType.individual": "Particulier",
147 "settings.user.form.accountType.non-profit": "Non-Profit",
148 "settings.user.form.accountType.company": "Bedrijf",
149 "subscription.type.free": "gratis",
150 "subscription.type.month": "maand",
151 "subscription.type.year": "jaar",
152 "subscription.type.mining": "Franz ondersteunen met rekenkracht",
153 "subscription.mining.headline": "Hoe werkt dit?",
154 "subscription.mining.experimental": "experimenteel",
155 "subscription.mining.line1": "Door \"Ondersteunen met rekenkracht\" aan te zetten zal Franz ongeveer 20-50% van je CPU gebruiken om Monero cryptocurrency te minen, wat ongeveer op €4,3/jaar neerkomt.",
156 "subscription.mining.line2": "Het CPU gebruik zal aangepast worden aan je werkgedrag zodat we je batterij niet leeg laten lopen of jou en je machine vertragen.",
157 "subscription.mining.line3": "Zolang de miner actief is heb je ongelimiteerde toegang tot alle Franz Premium Supporter Features.",
158 "subscription.mining.moreInformation": "Meer informatie over dit plan.",
159 "subscriptionPopup.buttonCancel": "Annuleren",
160 "subscriptionPopup.buttonDone": "Klaar",
161 "tabs.item.reload": "Herladen",
162 "tabs.item.edit": "Aanpassen",
163 "tabs.item.disableNotifications": "Notificaties uitschakelen",
164 "tabs.item.enableNotification": "Notificaties inschakelen",
165 "tabs.item.disableService": "Service uitschakelen",
166 "tabs.item.deleteService": "Service verwijderen"
167}
diff --git a/src/i18n/locales/nl.json b/src/i18n/locales/nl.json
new file mode 100644
index 000000000..159d1f328
--- /dev/null
+++ b/src/i18n/locales/nl.json
@@ -0,0 +1,168 @@
1{
2 "global.api.unhealthy": "Kan niet verbinden met Franz online services",
3 "global.notConnectedToTheInternet": "Je bent niet verbonden met het internet.",
4 "welcome.signupButton": "Maak een gratis account",
5 "welcome.loginButton": "Log in op je account",
6 "welcome.slogan": "Messaging dat voor jou werkt",
7 "login.headline": "Inloggen",
8 "login.email.label": "E-mailadres",
9 "login.password.label": "Wachtwoord",
10 "login.submit.label": "Inloggen",
11 "login.invalidCredentials": "E-mailadres of wachtwoord ongeldig",
12 "login.tokenExpired": "De sessie is verlopen, log opnieuw in alsjeblieft.",
13 "login.serverLogout": "De sessie is verlopen, log opnieuw in alsjeblieft..",
14 "login.link.signup": "Maak een gratis account",
15 "login.link.password": "Wachtwoord vergeten",
16 "password.headline": "Wachtwoord vergeten",
17 "password.email.label": "E-mailadres",
18 "password.submit.label": "Verzenden",
19 "password.noUser": "Geen gebruiker bekend met dat e-mailadres",
20 "password.successInfo": "Controleer alsjeblieft je e-mail",
21 "password.link.signup": "Maak een nieuw account aan",
22 "password.link.login": "Log in op je account",
23 "signup.headline": "Aanmelden",
24 "signup.firstname.label": "Voornaam",
25 "signup.lastname.label": "Achternaam",
26 "signup.email.label": "E-mailadres",
27 "signup.company.label": "Bedrijf",
28 "signup.password.label": "Wachtwoord",
29 "signup.submit.label": "Maak account aan",
30 "signup.link.login": "Al een account? Log in!",
31 "signup.emailDuplicate": "Er bestaat al een gebruiker met dat e-mailadres",
32 "signup.legal.info": "Door een Franz account aan te maken ga je akkoord met de",
33 "signup.legal.terms": "Gebruiksvoorwaarden",
34 "signup.legal.privacy": "Privacy Voorwaarden",
35 "pricing.headline": "Ondersteun Franz",
36 "pricing.support.label": "Selecteer je ondersteuningsplan",
37 "pricing.submit.label": "Ik wil de ontwikkeling van Franz ondersteunen",
38 "pricing.link.skipPayment": "Ik wil de ontwikkeling van Franz niet ondersteunen.",
39 "import.headline": "Importeer je Franz 4 services",
40 "import.notSupportedHeadline": "Services nog niet ondersteund in Franz 5",
41 "import.submit.label": "Importeer services",
42 "import.skip.label": "Ik wil services handmatig toevoegen",
43 "invite.submit.label": "Verzend uitnodigingen",
44 "invite.headline.friends": "Nodig 3 van je vrienden of collega's uit",
45 "invite.name.label": "Naam",
46 "invite.email.label": "E-mailadres",
47 "invite.skip.label": "Ik wil dit later doen",
48 "subscription.submit.label": "Ik wil de ontwikkeling van Franz ondersteunen",
49 "subscription.paymentSessionError": "Kan betaalformulier niet initialiseren",
50 "subscription.includedFeatures": "Betaald Franz Premium Supporter Account bevat",
51 "subscription.features.onpremise": "Add on-geschikt/gehoste services zoals HipChat",
52 "subscription.features.customServices": "Privé services voor jou en je team",
53 "subscription.features.encryptedSync": "Beveiligde sessie synchronisatie",
54 "subscription.features.vpn": "Proxy & VPN ondersteuning",
55 "subscription.features.ads": "Geen advertenties, nooit!",
56 "subscription.features.comingSoon": "komt binnenkort",
57 "infobar.servicesUpdated": "Je services zijn geüpdatet.",
58 "infobar.updateAvailable": "Een nieuwe update voor Franz is beschikbaar.",
59 "infobar.buttonReloadServices": "Herlaad services",
60 "infobar.buttonInstallUpdate": "Herstart & installeer update",
61 "infobar.requiredRequestsFailed": "Kon services en gebruikerinformatie niet laden",
62 "sidebar.settings": "Instellingen",
63 "services.welcome": "Welkom bij Franz",
64 "services.getStarted": "Beginnen",
65 "settings.account.headline": "Account",
66 "settings.account.headlineSubscription": "Je abonnement",
67 "settings.account.headlineUpgrade": "Upgrade je account & ondersteun Franz",
68 "settings.account.headlineInvoices": "Facturen",
69 "settings.account.manageSubscription.label": "Beheer je abonnement",
70 "settings.account.accountType.basic": "Basis Account",
71 "settings.account.accountType.premium": "Premium Supporter Account",
72 "settings.account.account.editButton": "Bewerk account",
73 "settings.account.invoiceDownload": "Download",
74 "settings.account.userInfoRequestFailed": "Kon gebruikerinformatie niet laden",
75 "settings.account.tryReloadUserInfoRequest": "Probeer opnieuw",
76 "settings.account.headlineProfile": "Update profiel",
77 "settings.account.headlineAccount": "Account informatie",
78 "settings.account.headlinePassword": "Wijzig wachtwoord",
79 "settings.account.successInfo": "Je wijzigingen zijn opgeslagen",
80 "settings.account.buttonSave": "Update profiel",
81 "settings.account.mining.thankyou": "Bedankt voor je ondersteuning van Franz met je rekenkracht.",
82 "settings.account.mining.active": "Op dit moment voer je {hashes} berekingen per seconde uit.",
83 "settings.account.mining.moreInformation": "Meer informatie",
84 "settings.account.mining.cancel": "Stop mining",
85 "settings.navigation.availableServices": "Beschikbare services",
86 "settings.navigation.yourServices": "Jouw services",
87 "settings.navigation.account": "Account",
88 "settings.navigation.settings": "Instellingen",
89 "settings.navigation.logout": "Uitloggen",
90 "settings.recipes.headline": "Beschikbare services",
91 "settings.recipes.mostPopular": "Meest populair",
92 "settings.recipes.all": "Alle services",
93 "settings.recipes.dev": "Ontwikkeling",
94 "settings.recipes.nothingFound": "Geen service kwam overeen met je zoekopdracht.",
95 "settings.recipes.servicesSuccessfulAddedInfo": "Service succesvol toegevoegd",
96 "settings.service.form.saveButton": "Opslaan service",
97 "settings.service.form.deleteButton": "Verwijder service",
98 "settings.service.form.availableServices": "Beschikbare services",
99 "settings.service.form.yourServices": "Jouw services",
100 "settings.service.form.addServiceHeadline": "Toevoegen {name}",
101 "settings.service.form.editServiceHeadline": "Bewerk {name}",
102 "settings.service.form.tabHosted": "Gehost",
103 "settings.service.form.tabOnPremise": "Zelf-gehoste ??",
104 "settings.service.form.customUrlValidationError": "Kon custom server {name} niet valideren.",
105 "settings.service.form.customUrlPremiumInfo": "Om zelf-gehoste services toe te kunnen voegen, heb je een Franz Premium Supporter Account nodig.",
106 "settings.service.form.customUrlUpgradeAccount": "Upgrade je account",
107 "settings.service.form.indirectMessageInfo": "Je ontvangt meldingen van alle nieuwe berichten in een kanaal, niet alleen @username, @channel, @here, ...",
108 "settings.service.error.headline": "Fout",
109 "settings.service.error.goBack": "Terug naar services",
110 "settings.service.error.message": "Kon servicerecept niet laden.",
111 "settings.services.tooltip.isDisabled": "Service is uitgeschakeld",
112 "settings.services.tooltip.notificationsDisabled": "Meldingen zijn uitgeschakeld",
113 "settings.services.headline": "Jouw services",
114 "settings.services.noServicesAdded": "Je hebt nog geen services toegevoegd.",
115 "settings.services.discoverServices": "Ontdek services",
116 "settings.services.updatedInfo": "Je wijzigingen zijn opgeslagen",
117 "settings.services.deletedInfo": "Service is verwijderd",
118 "settings.app.headline": "Instellingen",
119 "settings.app.headlineGeneral": "Algemeen",
120 "settings.app.headlineLanguage": "Taal",
121 "settings.app.headlineUpdates": "Updates",
122 "settings.app.buttonSearchForUpdate": "Controleer op updates",
123 "settings.app.buttonInstallUpdate": "Herstart & installeer update",
124 "settings.app.updateStatusSearching": "Zoekt naar updates",
125 "settings.app.updateStatusAvailable": "Update beschikbaar, downloaden...",
126 "settings.app.updateStatusUpToDate": "Je gebruikt de laatste versie van Franz",
127 "settings.app.form.autoLaunchOnStart": "Lanceer Franz bij opstarten",
128 "settings.app.form.autoLaunchInBackground": "Open op de achtergrond",
129 "settings.app.form.enableSystemTray": "Toon Franz in de systeembalk",
130 "settings.app.form.minimizeToSystemTray": "Minimaliseer Franz naar de systeembal",
131 "settings.app.form.runInBackground": "Houd Franz op de achtergrond wanneer het venster gesloten wordt",
132 "settings.app.form.language": "Taal",
133 "settings.app.form.beta": "Inclusief beta versies",
134 "settings.app.currentVersion": "Huidige versie:",
135 "settings.service.form.name": "Naam",
136 "settings.service.form.enableService": "Activeer service",
137 "settings.service.form.enableNotification": "Activeer meldingen",
138 "settings.service.form.team": "Team",
139 "settings.service.form.customUrl": "Custom server",
140 "settings.service.form.indirectMessages": "Toon berichtenbadge voor alle nieuwe berichten",
141 "settings.user.form.firstname": "Voornaam",
142 "settings.user.form.lastname": "Achternaam",
143 "settings.user.form.email": "E-mailadres",
144 "settings.user.form.currentPassword": "Huidig wachtwoord",
145 "settings.user.form.newPassword": "Nieuw wachtwoord",
146 "settings.user.form.accountType.label": "Account type",
147 "settings.user.form.accountType.individual": "Individueel",
148 "settings.user.form.accountType.non-profit": "Non-Profit",
149 "settings.user.form.accountType.company": "Bedrijf",
150 "subscription.type.free": "gratis",
151 "subscription.type.month": "maand",
152 "subscription.type.year": "jaar",
153 "subscription.type.mining": "Ondersteun Franz met rekenkracht",
154 "subscription.mining.headline": "Hoe werkt dit?",
155 "subscription.mining.experimental": "experimenteel",
156 "subscription.mining.line1": "Door \"Ondersteun met rekenkracht\" te activeren, zal Franz ongeveer 20-50% van je CPU gebruiken om de cryptomunt Monero te minen, wat overeenkomt met ongeveer $ 5/jaar.",
157 "subscription.mining.line2": "We zullen het CPU-gebruik aanpassen aan je gebruik en daarmee voorkomen dat de batterij niet leegloopt of dat jij en je werk afgeremd wordt.",
158 "subscription.mining.line3": "Zolang de miner actief is, heb je onbeperkt toegang tot alle Franz Premium Supporter Features.",
159 "subscription.mining.moreInformation": "Verkrijg meer informatie over dit plan.",
160 "subscriptionPopup.buttonCancel": "Cancel",
161 "subscriptionPopup.buttonDone": "Klaar",
162 "tabs.item.reload": "Herlaad",
163 "tabs.item.edit": "Bewerk",
164 "tabs.item.disableNotifications": "Uitschakelen meldingen",
165 "tabs.item.enableNotification": "Inschakelen meldingen",
166 "tabs.item.disableService": "Uitschakelen service",
167 "tabs.item.deleteService": "Verwijderen service"
168}
diff --git a/src/i18n/locales/pl.json b/src/i18n/locales/pl.json
new file mode 100644
index 000000000..1a8e9ad54
--- /dev/null
+++ b/src/i18n/locales/pl.json
@@ -0,0 +1,167 @@
1{
2 "global.api.unhealthy": "Nie można połączyć się z usługą Franz",
3 "global.notConnectedToTheInternet": "Brak połączenia z Internetem.",
4 "welcome.signupButton": "Stwórz darmowe konto",
5 "welcome.loginButton": "Zaloguj się na swoje konto",
6 "welcome.slogan": "Komunikator który działa",
7 "login.headline": "Zaloguj się",
8 "login.email.label": "Adres email",
9 "login.password.label": "Hasło",
10 "login.submit.label": "Zaloguj się",
11 "login.invalidCredentials": "Adres email lub hasło są błędne",
12 "login.tokenExpired": "Twoja sesja wygasła, zaloguj się ponownie.",
13 "login.serverLogout": "Twoja sesja wygasła, zaloguj się ponownie.",
14 "login.link.signup": "Stwórz darmowe konto",
15 "login.link.password": "Zresetuj hasło",
16 "password.headline": "Zresetuj hasło",
17 "password.email.label": "Adres email",
18 "password.submit.label": "Wyślij",
19 "password.noUser": "Nie znaleziono użytkownika z takim adresem email",
20 "password.successInfo": "Sprawdź swoją skrzynkę email",
21 "password.link.signup": "Stwórz darmowe konto",
22 "password.link.login": "Zaloguj się na swoje konto",
23 "signup.headline": "Zarejestruj się",
24 "signup.firstname.label": "Imię",
25 "signup.lastname.label": "Nazwisko",
26 "signup.email.label": "Adres email",
27 "signup.company.label": "Firma",
28 "signup.password.label": "Hasło",
29 "signup.submit.label": "Stwórz konto",
30 "signup.link.login": "Masz już konto, zalogować się?",
31 "signup.emailDuplicate": "Użytkownik z takim adresem email już istnieje",
32 "signup.legal.info": "Poprzez utworzenie konta Franz akceptujesz",
33 "signup.legal.terms": "Warunki świadczenia usług",
34 "signup.legal.privacy": "Polityka prywatności",
35 "pricing.headline": "Wspomóż aplikację Franz",
36 "pricing.support.label": "Wybierz plan wsparcia",
37 "pricing.submit.label": "Chcę wspierać rozwój aplikacji Franz",
38 "pricing.link.skipPayment": "Nie chcę wspierać rozwoju aplikacji Franz.",
39 "import.headline": "Zaimportuj usługi Franz 4",
40 "import.notSupportedHeadline": "Usługi nie są jeszcze wspierane w Franz 5",
41 "import.submit.label": "Zaimportuj usługi",
42 "import.skip.label": "Chcę dodać usługi ręcznie",
43 "invite.submit.label": "Wyślij zaproszenia",
44 "invite.headline.friends": "Zaproś 3 znajomych lub kolegów z pracy",
45 "invite.name.label": "Nazwa",
46 "invite.email.label": "Adres email",
47 "invite.skip.label": "Chcę to zrobić później",
48 "subscription.submit.label": "Chcę wspierać rozwój aplikacji Franz",
49 "subscription.paymentSessionError": "Nie można wczytać formularza płatności",
50 "subscription.includedFeatures": "Płatne konto Franz Premium obejmuje",
51 "subscription.features.onpremise": "Dodawanie lokalnych/hostowanych usług takich jak HipChat",
52 "subscription.features.customServices": "Prywatne usługi dla Ciebie i Twojego zespołu",
53 "subscription.features.encryptedSync": "Szyfrowana synchronizacja sesji",
54 "subscription.features.vpn": "Wsprarcie Proxy i VPN",
55 "subscription.features.ads": "Brak reklam, na zawsze!",
56 "subscription.features.comingSoon": "wkrótce dostępne",
57 "infobar.servicesUpdated": "Twoje usługi zostały zaaktualizowane.",
58 "infobar.updateAvailable": "Aktualizacja aplikacji Franz jest dostępna.",
59 "infobar.buttonReloadServices": "Przeładuj usługi",
60 "infobar.buttonInstallUpdate": "Uruchom ponownie i zainstaluj aktualizacje",
61 "infobar.requiredRequestsFailed": "Nie można wczytać usług i informacji o użytkowniku",
62 "sidebar.settings": "Ustawienia",
63 "services.welcome": "Witaj w aplikcji Franz",
64 "services.getStarted": "Zacznij",
65 "settings.account.headline": "Konto",
66 "settings.account.headlineSubscription": "Twoja subskrypcja",
67 "settings.account.headlineUpgrade": "Ulepsz swoje konto i wspieraj aplikację Franz",
68 "settings.account.headlineInvoices": "Faktury",
69 "settings.account.manageSubscription.label": "Zarządzaj swoimi subskrypcjami",
70 "settings.account.accountType.basic": "Podstawowe konto",
71 "settings.account.accountType.premium": "Konto Premium",
72 "settings.account.account.editButton": "Edytuj konto",
73 "settings.account.invoiceDownload": "Pobieranie",
74 "settings.account.userInfoRequestFailed": "Nie można wczytać informacji o użytkowniku",
75 "settings.account.tryReloadUserInfoRequest": "Spróbuj ponownie",
76 "settings.account.headlineProfile": "Aktualizuj profil",
77 "settings.account.headlineAccount": "Informacje o koncie",
78 "settings.account.headlinePassword": "Zmiana hasła",
79 "settings.account.successInfo": "Zmiany zostały zapisane",
80 "settings.account.buttonSave": "Aktualizuj profil",
81 "settings.account.mining.thankyou": "Dziękuję za wsparcie aplikacji Franz mocą obliczeniową.",
82 "settings.account.mining.active": "Obecnie wykonujesz {hashes} operacji na sekundę.",
83 "settings.account.mining.moreInformation": "Dowiedz się więcej",
84 "settings.account.mining.cancel": "Anuluj kopanie",
85 "settings.navigation.availableServices": "Dostępne usługi",
86 "settings.navigation.yourServices": "Twoje usługi",
87 "settings.navigation.account": "Konto",
88 "settings.navigation.settings": "Ustawienia",
89 "settings.navigation.logout": "Wylogowanie",
90 "settings.recipes.headline": "Dostępne usługi",
91 "settings.recipes.mostPopular": "Najpopularniejsze",
92 "settings.recipes.all": "Wszystkie usługi",
93 "settings.recipes.dev": "Rozwojowe",
94 "settings.recipes.nothingFound": "Żadna usługa nie została znaleziona.",
95 "settings.recipes.servicesSuccessfulAddedInfo": "Usługa została dodana pomyślnie",
96 "settings.service.form.saveButton": "Zapisz usługę",
97 "settings.service.form.deleteButton": "Usuń usługę",
98 "settings.service.form.availableServices": "Dostępne usługi",
99 "settings.service.form.yourServices": "Twoje usługi",
100 "settings.service.form.addServiceHeadline": "Dodaj {name}",
101 "settings.service.form.editServiceHeadline": "Edytuj {name}",
102 "settings.service.form.tabHosted": "Hostowane",
103 "settings.service.form.tabOnPremise": "Hostowane lokalnie ⭐️",
104 "settings.service.form.customUrlValidationError": "Nie można zweryfikować spersonalizowanego {name} serwera.",
105 "settings.service.form.customUrlPremiumInfo": "Aby dodać usługi hostowane lokalnie, musisz posiadać konto Premium.",
106 "settings.service.form.customUrlUpgradeAccount": "Ulepsz swoje konto",
107 "settings.service.form.indirectMessageInfo": "Będziesz informowany o wszystkich nowych wiadomościach na kanale, nie tylko @username, @channel, @here, ...",
108 "settings.service.error.headline": "Błąd",
109 "settings.service.error.goBack": "Wróć do usług",
110 "settings.service.error.message": "Nie można wczytać przepisu usługi.",
111 "settings.services.tooltip.isDisabled": "Usługa jest nieaktywna",
112 "settings.services.tooltip.notificationsDisabled": "Powiadomienia są nieaktywne",
113 "settings.services.headline": "Twoje usługi",
114 "settings.services.noServicesAdded": "Nie dodałeś jeszcze żadnych usług.",
115 "settings.services.discoverServices": "Przeglądaj usługi",
116 "settings.services.updatedInfo": "Zmiany zostały zapisane",
117 "settings.services.deletedInfo": "Usługa została usunięta",
118 "settings.app.headline": "Ustawienia",
119 "settings.app.headlineGeneral": "Ogólne",
120 "settings.app.headlineLanguage": "Język",
121 "settings.app.headlineUpdates": "Aktualizacje",
122 "settings.app.buttonSearchForUpdate": "Sprawdź czy są dostęne aktualizacje",
123 "settings.app.buttonInstallUpdate": "Uruchom ponownie i zainstaluj aktualizacje",
124 "settings.app.updateStatusSearching": "Szukam aktualizacji",
125 "settings.app.updateStatusAvailable": "Dostępna aktualizacja, pobieram...",
126 "settings.app.updateStatusUpToDate": "Używasz najnowszej wersji aplikacji Franz",
127 "settings.app.form.autoLaunchOnStart": "Uruchom aplikację Franz przy starcie systemu",
128 "settings.app.form.autoLaunchInBackground": "Uruchom w tle",
129 "settings.app.form.minimizeToSystemTray": "Zminimalizuj aplikację Franz",
130 "settings.app.form.runInBackground": "Zachowaj aplikację Franz w tle po zamknięciu okna",
131 "settings.app.form.language": "Język",
132 "settings.app.form.beta": "Uwzględniaj wersje beta",
133 "settings.app.currentVersion": "Obecna wersja:",
134 "settings.service.form.name": "Nazwa",
135 "settings.service.form.enableService": "Aktywuj usługę",
136 "settings.service.form.enableNotification": "Aktywuj powiadomienia",
137 "settings.service.form.team": "Zespół",
138 "settings.service.form.customUrl": "Spersonalizowany serwer",
139 "settings.service.form.indirectMessages": "Pokaż ikonę wiadomości dla wszystkich nowych wiadomości",
140 "settings.user.form.firstname": "Imię",
141 "settings.user.form.lastname": "Nazwisko",
142 "settings.user.form.email": "Adres email",
143 "settings.user.form.currentPassword": "Obecne hasło",
144 "settings.user.form.newPassword": "Nowe hasło",
145 "settings.user.form.accountType.label": "Typ konta",
146 "settings.user.form.accountType.individual": "Prywatne",
147 "settings.user.form.accountType.non-profit": "Non-Profit",
148 "settings.user.form.accountType.company": "Firma",
149 "subscription.type.free": "za darmo",
150 "subscription.type.month": "miesiąc",
151 "subscription.type.year": "rok",
152 "subscription.type.mining": "Wspieraj aplikację Franz mocą obliczeniową",
153 "subscription.mining.headline": "Jak to działa?",
154 "subscription.mining.experimental": "eksperymentalne",
155 "subscription.mining.line1": "Włączając \"wspieraj mocą obliczeniową\", aplikacja Franz będzie używać około 20-50% mocy Twojego procesora aby kopać kryptowalutę Monero co jest równe około $5/rok.",
156 "subscription.mining.line2": "Będziemy dostosowywać zużycie procesora do stylu Twojej pracy tak aby nie zużywać baterii i nie spowalniać działania urządzenia.",
157 "subscription.mining.line3": "Tak długo jak kopanie będzie aktywne, będziesz mieć nielimitowany dostęp do wszystkich funkcji dostępnych w koncie Premium.",
158 "subscription.mining.moreInformation": "Dowiedz się więcej o tym planie.",
159 "subscriptionPopup.buttonCancel": "Anuluj",
160 "subscriptionPopup.buttonDone": "Zrobione",
161 "tabs.item.reload": "Przeładuj",
162 "tabs.item.edit": "Edytuj",
163 "tabs.item.disableNotifications": "Wyłącz powiadomienia",
164 "tabs.item.enableNotification": "Włącz powiadomienia",
165 "tabs.item.disableService": "Wyłącz usługę",
166 "tabs.item.deleteService": "Usuń usługę"
167}
diff --git a/src/i18n/locales/pt-BR.json b/src/i18n/locales/pt-BR.json
new file mode 100644
index 000000000..38f0836a7
--- /dev/null
+++ b/src/i18n/locales/pt-BR.json
@@ -0,0 +1,167 @@
1{
2 "global.api.unhealthy": "Não foi possível conectar aos serviços online do Franz",
3 "global.notConnectedToTheInternet": "Você não está conectado à internet.",
4 "welcome.signupButton": "Criar uma conta grátis",
5 "welcome.loginButton": "Fazer login na sua conta",
6 "welcome.slogan": "Mensagens que funcionam para você",
7 "login.headline": "Login",
8 "login.email.label": "Endereço de email",
9 "login.password.label": "Senha",
10 "login.submit.label": "Login",
11 "login.invalidCredentials": "Email ou senha inválida",
12 "login.tokenExpired": "Sua sessão expirou, faça o login novamente.",
13 "login.serverLogout": "Sua sessão expirou, faça o login novamente.",
14 "login.link.signup": "Criar uma conta grátis",
15 "login.link.password": "Trocar a senha",
16 "password.headline": "Trocar a senha",
17 "password.email.label": "Endereço de email",
18 "password.submit.label": "Enviar",
19 "password.noUser": "Nenhum usuário com este email foi encontrado",
20 "password.successInfo": "Por favor, verifique o seu email",
21 "password.link.signup": "Criar uma conta grátis",
22 "password.link.login": "Fazer login na sua conta",
23 "signup.headline": "Cadastrar-se",
24 "signup.firstname.label": "Nome",
25 "signup.lastname.label": "Sobrenome",
26 "signup.email.label": "Endereço de email",
27 "signup.company.label": "Empresa",
28 "signup.password.label": "Senha",
29 "signup.submit.label": "Criar conta",
30 "signup.link.login": "Já tem uma conta. Fazer login?",
31 "signup.emailDuplicate": "Um usuário com esta conta já existe",
32 "signup.legal.info": "Ao criar uma conta Franz você aceita os ",
33 "signup.legal.terms": "Termos de Serviço",
34 "signup.legal.privacy": "Declaração de Privacidade",
35 "pricing.headline": "Apoie o Franz",
36 "pricing.support.label": "Selecione seu plano de apoio",
37 "pricing.submit.label": "Eu quero apoiar o desenvolvimento do Franz",
38 "pricing.link.skipPayment": "Eu não quero apoiar o desenvolvimento do Franz.",
39 "import.headline": "Importe seus serviços do Franz 4",
40 "import.notSupportedHeadline": "Serviços ainda não suportados no Franz 5",
41 "import.submit.label": "Importar serviços",
42 "import.skip.label": "Eu quero adicionar serviços manualmente",
43 "invite.submit.label": "Enviar convites",
44 "invite.headline.friends": "Convide 3 dos seus amigos ou colegas",
45 "invite.name.label": "Nome",
46 "invite.email.label": "Endereço de email",
47 "invite.skip.label": "Eu quero fazer isso depois",
48 "subscription.submit.label": "Eu quero apoiar o desenvolvimento do Franz",
49 "subscription.paymentSessionError": "Não foi possível abrir o formulário de pagamento",
50 "subscription.includedFeatures": "Conta Paga Franz Premium inclui",
51 "subscription.features.onpremise": "Adicionar serviços locais/hospedados como HipChat",
52 "subscription.features.customServices": "Serviços privados para você e sua equipe",
53 "subscription.features.encryptedSync": "Sincronização encriptada das sessões",
54 "subscription.features.vpn": "Suporte à proxy & VPN",
55 "subscription.features.ads": "Sem anúncios, sempre!",
56 "subscription.features.comingSoon": "em breve",
57 "infobar.servicesUpdated": "Seus serviços foram atualizados.",
58 "infobar.updateAvailable": "Uma nova atualização do Franz está disponível.",
59 "infobar.buttonReloadServices": "Recarregar serviços",
60 "infobar.buttonInstallUpdate": "Reiniciar & instalar atualização",
61 "infobar.requiredRequestsFailed": "Não foi possível carregar serviços e informações do usuário",
62 "sidebar.settings": "Configurações",
63 "services.welcome": "Bem-vindo ao Franz",
64 "services.getStarted": "Começar",
65 "settings.account.headline": "Conta",
66 "settings.account.headlineSubscription": "Sua assinatura",
67 "settings.account.headlineUpgrade": "Atualize a sua conta & apoie o Franz",
68 "settings.account.headlineInvoices": "Recibos",
69 "settings.account.manageSubscription.label": "Gerencie a sua assinatura",
70 "settings.account.accountType.basic": "Conta Básica",
71 "settings.account.accountType.premium": "Conta Apoiador Premium",
72 "settings.account.account.editButton": "Editar conta",
73 "settings.account.invoiceDownload": "Download",
74 "settings.account.userInfoRequestFailed": "Não foi possível carregar as informações do usuário",
75 "settings.account.tryReloadUserInfoRequest": "Tente novamente",
76 "settings.account.headlineProfile": "Atualizar perfil",
77 "settings.account.headlineAccount": "Informações de conta",
78 "settings.account.headlinePassword": "Mudar senha",
79 "settings.account.successInfo": "Suas mudanças foram salvas",
80 "settings.account.buttonSave": "Atualizar perfil",
81 "settings.account.mining.thankyou": "Obrigado por apoiar o Franz com poder de processamento.",
82 "settings.account.mining.active": "Você está realizando {hashes} cálculos por segundo agora.",
83 "settings.account.mining.moreInformation": "Obter mais informações",
84 "settings.account.mining.cancel": "Cancelar mineração",
85 "settings.navigation.availableServices": "Serviços disponíveis",
86 "settings.navigation.yourServices": "Seus serviços",
87 "settings.navigation.account": "Conta",
88 "settings.navigation.settings": "Configurações",
89 "settings.navigation.logout": "Logout",
90 "settings.recipes.headline": "Serviços disponíveis",
91 "settings.recipes.mostPopular": "Mais populares",
92 "settings.recipes.all": "Todos serviços",
93 "settings.recipes.dev": "Desenvolvimento",
94 "settings.recipes.nothingFound": "Desculpe, mas nenhum serviço corresponde a sua pesquisa.",
95 "settings.recipes.servicesSuccessfulAddedInfo": "Serviço adicionado com sucesso",
96 "settings.service.form.saveButton": "Salvar serviço",
97 "settings.service.form.deleteButton": "Apagar serviço",
98 "settings.service.form.availableServices": "Serviços disponíveis",
99 "settings.service.form.yourServices": "Seus serviços",
100 "settings.service.form.addServiceHeadline": "Adicionar {name}",
101 "settings.service.form.editServiceHeadline": "Editar {name}",
102 "settings.service.form.tabHosted": "Hospedado",
103 "settings.service.form.tabOnPremise": "Auto-hospedado ⭐️",
104 "settings.service.form.customUrlValidationError": "Não foi possível validar o servidor personalizado {name}.",
105 "settings.service.form.customUrlPremiumInfo": "Para adicionar serviços auto-hospedados, você precisa de uma conta Franz Apoiador Premium.",
106 "settings.service.form.customUrlUpgradeAccount": "Atualize a sua conta",
107 "settings.service.form.indirectMessageInfo": "Você será notificado por todas as mensagens em um canal, não apenas @usuário, @channel, @here, ...",
108 "settings.service.error.headline": "Erro",
109 "settings.service.error.goBack": "Voltar aos serviços",
110 "settings.service.error.message": "Não foi possível carregar a receita de serviço.",
111 "settings.services.tooltip.isDisabled": "Serviço desativado",
112 "settings.services.tooltip.notificationsDisabled": "Notificações desativadas",
113 "settings.services.headline": "Seus serviços",
114 "settings.services.noServicesAdded": "Você ainda não adicionou nenhum serviço.",
115 "settings.services.discoverServices": "Descobrir serviços",
116 "settings.services.updatedInfo": "Suas mudanças foram salvas",
117 "settings.services.deletedInfo": "Serviço apagado",
118 "settings.app.headline": "Configurações",
119 "settings.app.headlineGeneral": "Geral",
120 "settings.app.headlineLanguage": "Idioma",
121 "settings.app.headlineUpdates": "Atualizações",
122 "settings.app.buttonSearchForUpdate": "Verificar por atualizações",
123 "settings.app.buttonInstallUpdate": "Reiniciar & instalar atualização",
124 "settings.app.updateStatusSearching": "Em busca de atualização",
125 "settings.app.updateStatusAvailable": "Atualização disponível, fazendo download...",
126 "settings.app.updateStatusUpToDate": "Você está usando a última versão do Franz",
127 "settings.app.form.autoLaunchOnStart": "Abrir o Franz iniciar o sistema",
128 "settings.app.form.autoLaunchInBackground": "Abrir no fundo",
129 "settings.app.form.minimizeToSystemTray": "Minimizar o Franz para a bandeja do sistema",
130 "settings.app.form.runInBackground": "Manter o Franz no fundo quando fechar a janela",
131 "settings.app.form.language": "Idioma",
132 "settings.app.form.beta": "Incluir versões beta",
133 "settings.app.currentVersion": "Versão atual:",
134 "settings.service.form.name": "Nome",
135 "settings.service.form.enableService": "Ativar serviço",
136 "settings.service.form.enableNotification": "Ativar notificações",
137 "settings.service.form.team": "Equipe",
138 "settings.service.form.customUrl": "Serviços personalizado",
139 "settings.service.form.indirectMessages": "Mostrar avisos para todas as mensagens",
140 "settings.user.form.firstname": "Nome",
141 "settings.user.form.lastname": "Sobrenome",
142 "settings.user.form.email": "Email",
143 "settings.user.form.currentPassword": "Senha atual",
144 "settings.user.form.newPassword": "Nova senha",
145 "settings.user.form.accountType.label": "Tipo de conta",
146 "settings.user.form.accountType.individual": "Individual",
147 "settings.user.form.accountType.non-profit": "Sem fins lucrativos",
148 "settings.user.form.accountType.company": "Empresa",
149 "subscription.type.free": "grátis",
150 "subscription.type.month": "mês",
151 "subscription.type.year": "ano",
152 "subscription.type.mining": "Apoie o Franz com poder de processamento",
153 "subscription.mining.headline": "Como isso funciona?",
154 "subscription.mining.experimental": "experimental",
155 "subscription.mining.line1": "Habilitando o \"Apoio com poder de processamento\", o Franz vai usar cerca de 20-50% da sua CPU para minerar a criptomoeda Monero que equivale a aproximadamente $ 5/ano.",
156 "subscription.mining.line2": "Nós iremos adaptar o uso da CPU baseado nos seus hábitos para não drenar sua bateria nem deixar o seu computador lento.",
157 "subscription.mining.line3": "Enquanto o minerador estiver ativo, você terá acesso ilimitado à todas funções do Franz Apoiador Premium.",
158 "subscription.mining.moreInformation": "Obter mais informações sobre este plano.",
159 "subscriptionPopup.buttonCancel": "Cancelar",
160 "subscriptionPopup.buttonDone": "Feito",
161 "tabs.item.reload": "Recarregar",
162 "tabs.item.edit": "Editar",
163 "tabs.item.disableNotifications": "Desativar notificações",
164 "tabs.item.enableNotification": "Ativar notificações",
165 "tabs.item.disableService": "Desativar serviço",
166 "tabs.item.deleteService": "Apagar serviço"
167}
diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json
new file mode 100644
index 000000000..44ced9e43
--- /dev/null
+++ b/src/i18n/locales/ru.json
@@ -0,0 +1,168 @@
1{
2 "global.api.unhealthy": "Невозможно подключиться к сервисам Franz",
3 "global.notConnectedToTheInternet": "Нет Интернет-соединения",
4 "welcome.signupButton": "Создать аккаунт",
5 "welcome.loginButton": "Вход",
6 "welcome.slogan": "Общение, которое просто работает",
7 "login.headline": "Регистрация",
8 "login.email.label": "Email адрес",
9 "login.password.label": "Пароль",
10 "login.submit.label": "Регистрация",
11 "login.invalidCredentials": "Неправильный email или пароль",
12 "login.tokenExpired": "Сессия устарела, пожалуйста, войдите снова.",
13 "login.serverLogout": "Сессия устарела, пожалуйста, войдите снова.",
14 "login.link.signup": "Создать бесплатный аккаунт",
15 "login.link.password": "Восстановить пароль",
16 "password.headline": "Восстановление пароля",
17 "password.email.label": "Email адрес",
18 "password.submit.label": "Отправить",
19 "password.noUser": "Не найдено пользователя с таким email",
20 "password.successInfo": "Проверьте Ваш email",
21 "password.link.signup": "Создать аккаунт",
22 "password.link.login": "Вход",
23 "signup.headline": "Регистрация",
24 "signup.firstname.label": "Имя",
25 "signup.lastname.label": "Фамилия",
26 "signup.email.label": "Email адрес",
27 "signup.company.label": "Организация",
28 "signup.password.label": "Пароль",
29 "signup.submit.label": "Создать аккаунт",
30 "signup.link.login": "Уже есть аккаунт, войти?",
31 "signup.emailDuplicate": "Пользователь с указанным email уже существует",
32 "signup.legal.info": "Создавая аккаунт Franz, Вы принимаете",
33 "signup.legal.terms": "Условия обслуживания",
34 "signup.legal.privacy": "Политика конфиденциальности",
35 "pricing.headline": "Поддержать Franz",
36 "pricing.support.label": "Выберите план поддержки",
37 "pricing.submit.label": "Я хочу поддержать разработку Franz",
38 "pricing.link.skipPayment": "Я не хочу поддерживать разработку Franz.",
39 "import.headline": "Импортировать сервисы Franz 4",
40 "import.notSupportedHeadline": "Сервисы еще не поддержаны в Franz 5",
41 "import.submit.label": "Импортировать сервисы",
42 "import.skip.label": "Я хочу добавить сервисы вручную",
43 "invite.submit.label": "Выслать приглашения",
44 "invite.headline.friends": "Пригласите 3х друзей или коллег",
45 "invite.name.label": "Имя",
46 "invite.email.label": "Email адрес",
47 "invite.skip.label": "Я сделаю это позже",
48 "subscription.submit.label": "Я хочу поддержать разработку Franz",
49 "subscription.paymentSessionError": "Невозможно загрузить форму оплаты",
50 "subscription.includedFeatures": "Оплаченный Franz Премиум аккаунт включает",
51 "subscription.features.onpremise": "Добавить облачные службы или службы со своим хостингом типа HipChat",
52 "subscription.features.customServices": "Настраиваемые сервисы для Вас и Вашей команды",
53 "subscription.features.encryptedSync": "Шифрованная синхронизация сессии",
54 "subscription.features.vpn": "Поддержка прокси и VPN",
55 "subscription.features.ads": "Без рекламы, навсегда!",
56 "subscription.features.comingSoon": "следите за обновлениями",
57 "infobar.servicesUpdated": "Ваши сервисы были обновлены.",
58 "infobar.updateAvailable": "Доступно обновление Franz.",
59 "infobar.buttonReloadServices": "Перезагрузить сервисы",
60 "infobar.buttonInstallUpdate": "Перезапустить и обновить",
61 "infobar.requiredRequestsFailed": "Невозможно загрузить сервисы и информацию пользователя",
62 "sidebar.settings": "Настройки",
63 "services.welcome": "Добро пожаловать во Franz",
64 "services.getStarted": "Начать работу",
65 "settings.account.headline": "Аккаунт",
66 "settings.account.headlineSubscription": "Ваша подписка",
67 "settings.account.headlineUpgrade": "Улучшить аккаунт и поддержать Franz",
68 "settings.account.headlineInvoices": "Счета",
69 "settings.account.manageSubscription.label": "Управление подпиской",
70 "settings.account.accountType.basic": "Базовый аккаунт",
71 "settings.account.accountType.premium": "Премиум аккаунт",
72 "settings.account.account.editButton": "Редактировать аккаунт",
73 "settings.account.invoiceDownload": "Скачать",
74 "settings.account.userInfoRequestFailed": "Невозможно загрузить информацию пользователя",
75 "settings.account.tryReloadUserInfoRequest": "Попробовать снова",
76 "settings.account.headlineProfile": "Обновить профиль",
77 "settings.account.headlineAccount": "Информация аккаунта",
78 "settings.account.headlinePassword": "Сменить пароль",
79 "settings.account.successInfo": "Изменения сохранены",
80 "settings.account.buttonSave": "Сохранить изменения",
81 "settings.account.mining.thankyou": "Спасибо за поддержку Franz Вашими процессорными мощностями.",
82 "settings.account.mining.active": "Вы выполняете {hashes} вычислений в секунду.",
83 "settings.account.mining.moreInformation": "Больше информации",
84 "settings.account.mining.cancel": "Отменить майнинг",
85 "settings.navigation.availableServices": "Доступные сервисы",
86 "settings.navigation.yourServices": "Ваши сервисы",
87 "settings.navigation.account": "Аккаунт",
88 "settings.navigation.settings": "Настройки",
89 "settings.navigation.logout": "Выход",
90 "settings.recipes.headline": "Доступные сервисы",
91 "settings.recipes.mostPopular": "Популярные",
92 "settings.recipes.all": "Все сервисы",
93 "settings.recipes.dev": "Разработка",
94 "settings.recipes.nothingFound": "Ничего не найдено по Вашему запросу.",
95 "settings.recipes.servicesSuccessfulAddedInfo": "Сервис успешно добавлен",
96 "settings.service.form.saveButton": "Сохранить сервис",
97 "settings.service.form.deleteButton": "Удалить сервис",
98 "settings.service.form.availableServices": "Доступные сервисы",
99 "settings.service.form.yourServices": "Ваши сервисы",
100 "settings.service.form.addServiceHeadline": "Добавление {name}",
101 "settings.service.form.editServiceHeadline": "Редактирование {name}",
102 "settings.service.form.tabHosted": "Hosted",
103 "settings.service.form.tabOnPremise": "Свой хостинг ⭐️",
104 "settings.service.form.customUrlValidationError": "Невозможно проверить сервер {name}.",
105 "settings.service.form.customUrlPremiumInfo": "Для добавния сервиса на своем хостинге, необходим аккаунт Franz Premium.",
106 "settings.service.form.customUrlUpgradeAccount": "Улучшить аккаунт",
107 "settings.service.form.indirectMessageInfo": "Вы будете получать уведомления для всех сообщений, не только для @username, @channel, @here, ...",
108 "settings.service.error.headline": "Ошибка",
109 "settings.service.error.goBack": "Вернуться к сервисам",
110 "settings.service.error.message": "Невозможно загрузить рецепт сервиса.",
111 "settings.services.tooltip.isDisabled": "Сервис отключен",
112 "settings.services.tooltip.notificationsDisabled": "Уведомления отключены",
113 "settings.services.headline": "Ваши сервисы",
114 "settings.services.noServicesAdded": "У Вас пока нет сервисов",
115 "settings.services.discoverServices": "Найти сервисы",
116 "settings.services.updatedInfo": "Изменения сохранены",
117 "settings.services.deletedInfo": "Сервис удален",
118 "settings.app.headline": "Настройки",
119 "settings.app.headlineGeneral": "Общие",
120 "settings.app.headlineLanguage": "Язык",
121 "settings.app.headlineUpdates": "Обновления",
122 "settings.app.buttonSearchForUpdate": "Проверить обновления",
123 "settings.app.buttonInstallUpdate": "Перезапустить и обновить",
124 "settings.app.updateStatusSearching": "Поиск обновлений",
125 "settings.app.updateStatusAvailable": "Доступно обновление, загрука...",
126 "settings.app.updateStatusUpToDate": "Вы используете актуальную версию Franz",
127 "settings.app.form.autoLaunchOnStart": "Запускать Franz при старте",
128 "settings.app.form.autoLaunchInBackground": "Открывать в фоне",
129 "settings.app.form.enableSystemTray": "Показывать Franz в трее",
130 "settings.app.form.minimizeToSystemTray": "Сворачивать Franz в трей",
131 "settings.app.form.runInBackground": "Оставлять Franz в фоне при закрытии окна",
132 "settings.app.form.language": "Язык",
133 "settings.app.form.beta": "Включая бета версии",
134 "settings.app.currentVersion": "Текущая версия:",
135 "settings.service.form.name": "Название",
136 "settings.service.form.enableService": "Включить сервис",
137 "settings.service.form.enableNotification": "Включить уведомления",
138 "settings.service.form.team": "Команда",
139 "settings.service.form.customUrl": "Адрес сервера",
140 "settings.service.form.indirectMessages": "Показывать значок уведомлений для всех новых сообщений",
141 "settings.user.form.firstname": "Имя",
142 "settings.user.form.lastname": "Фамилия",
143 "settings.user.form.email": "Email",
144 "settings.user.form.currentPassword": "Текущий пароль",
145 "settings.user.form.newPassword": "Новый пароль",
146 "settings.user.form.accountType.label": "Тип аккаунта",
147 "settings.user.form.accountType.individual": "Индивидуальный",
148 "settings.user.form.accountType.non-profit": "Некоммерческий",
149 "settings.user.form.accountType.company": "Компания",
150 "subscription.type.free": "бесплатно",
151 "subscription.type.month": "месяц",
152 "subscription.type.year": "год",
153 "subscription.type.mining": "Поддерживать Franz, предоставляя процессорную мощность",
154 "subscription.mining.headline": "Как это работает?",
155 "subscription.mining.experimental": "экспериментально",
156 "subscription.mining.line1": "Включая \"Поддерживать Franz, предоставляя процессорную мощность\", Franz будет использовать 20-50% процессорного времени для майнинга криптовалюты Monero в примерном объеме 5$/год.",
157 "subscription.mining.line2": "Мы будем регулировать использование процессора, чтобы не садить батарею и не мешать Вашей работе",
158 "subscription.mining.line3": "Пока разрешен майнинг, Вам будут достуны все возможности Franz Premium без ограничений",
159 "subscription.mining.moreInformation": "Узнать больше об этом плане.",
160 "subscriptionPopup.buttonCancel": "Отмена",
161 "subscriptionPopup.buttonDone": "Готово",
162 "tabs.item.reload": "Перезагрузить",
163 "tabs.item.edit": "Редактировать",
164 "tabs.item.disableNotifications": "Отключить уведомления",
165 "tabs.item.enableNotification": "Включить уведомления",
166 "tabs.item.disableService": "Отключить сервис",
167 "tabs.item.deleteService": "Удалить сервис"
168}
diff --git a/src/i18n/locales/ua.json b/src/i18n/locales/ua.json
new file mode 100644
index 000000000..63135e52c
--- /dev/null
+++ b/src/i18n/locales/ua.json
@@ -0,0 +1,167 @@
1{
2 "global.api.unhealthy": "Не можна підключитись до онлайн сервісів Franz",
3 "global.notConnectedToTheInternet": "Ви не підключені до Інтернету.",
4 "welcome.signupButton": "Створити безплатний акаунт",
5 "welcome.loginButton": "Увійдіть до свого акаунту",
6 "welcome.slogan": "Обмін повідомленнями, який працює для вас",
7 "login.headline": "Увійти",
8 "login.email.label": "Email адреса",
9 "login.password.label": "Пароль",
10 "login.submit.label": "Увійти",
11 "login.invalidCredentials": "Email або пароль некоректні",
12 "login.tokenExpired": "Ваша сесія закінчилась, будь ласка, зайдіть знову.",
13 "login.serverLogout": "Ваша сесія закінчилась, будь ласка, зайдіть знову.",
14 "login.link.signup": "Створити безплатний акаунт",
15 "login.link.password": "Скинути пароль",
16 "password.headline": "Скинути пароль",
17 "password.email.label": "Email адреса",
18 "password.submit.label": "Подати",
19 "password.noUser": "Не знайдено жодного користувача з цією email адресою",
20 "password.successInfo": "Будь ласка, перевірте ваш email",
21 "password.link.signup": "Створити безплатний акаунт",
22 "password.link.login": "Увійти до вашого акаунту",
23 "signup.headline": "Увійти",
24 "signup.firstname.label": "Ім'я",
25 "signup.lastname.label": "Прізвище",
26 "signup.email.label": "Email адреса",
27 "signup.company.label": "Компанія",
28 "signup.password.label": "Пароль",
29 "signup.submit.label": "Створити акаунт",
30 "signup.link.login": "У вас вже є обліковий запис, увійти?",
31 "signup.emailDuplicate": "Користувач із цією email адресою вже існує",
32 "signup.legal.info": "Створенням акаунту Franz ви приймаєте",
33 "signup.legal.terms": "Умови використання",
34 "signup.legal.privacy": "Заява про конфіденційність",
35 "pricing.headline": "Підтримайте Franz",
36 "pricing.support.label": "Виберіть свій план підтримки",
37 "pricing.submit.label": "Я хочу підтримати розробку Franz",
38 "pricing.link.skipPayment": "Я не хочу підтримувати розробку Franz.",
39 "import.headline": "Імпортувати ваші сервіси з Franz 4",
40 "import.notSupportedHeadline": "Сервіси ще не підтримуються в Franz 5",
41 "import.submit.label": "Імпортувати сервіси",
42 "import.skip.label": "Я хочу додати сервіси вручну",
43 "invite.submit.label": "Відправити запрошення",
44 "invite.headline.friends": "Запросіть 3 ваших друзів або колег",
45 "invite.name.label": "Ім'я",
46 "invite.email.label": "Email адреса",
47 "invite.skip.label": "Я хочу зробити це пізніше",
48 "subscription.submit.label": "Я хочу підтримати розробку Franz",
49 "subscription.paymentSessionError": "Не вдалося ініціалізувати форму платежу",
50 "subscription.includedFeatures": "Платний Преміальний Акаунт Прихильника Franz включає",
51 "subscription.features.onpremise": "Додайте on-premise / hosted сервіси, такі як Hipchat",
52 "subscription.features.customServices": "Приватні сервіси для вас і вашої команди",
53 "subscription.features.encryptedSync": "Шифрована синхронізація сеансу",
54 "subscription.features.vpn": "Підтримка проксі та VPN",
55 "subscription.features.ads": "Жодної реклами!",
56 "subscription.features.comingSoon": "очікуйте незабаром",
57 "infobar.servicesUpdated": "Ваші сервіси було оновлено.",
58 "infobar.updateAvailable": "Нове оновлення для Franz доступне.",
59 "infobar.buttonReloadServices": "Перезавантажити сервіси",
60 "infobar.buttonInstallUpdate": "Перезавантажити і встановити оновлення",
61 "infobar.requiredRequestsFailed": "Не вдалося завантажити сервіси та інформацію користувача",
62 "sidebar.settings": "Налаштування",
63 "services.welcome": "Ласкаво просимо в Franz",
64 "services.getStarted": "Почати",
65 "settings.account.headline": "Акаунт",
66 "settings.account.headlineSubscription": "Ваша підписка",
67 "settings.account.headlineUpgrade": "Оновити ваш акаунт і підтримати Franz",
68 "settings.account.headlineInvoices": "Інвойси",
69 "settings.account.manageSubscription.label": "Керування вашою підпискою",
70 "settings.account.accountType.basic": "Базовий акаунт",
71 "settings.account.accountType.premium": "Преміум Акаунт Прихильника",
72 "settings.account.account.editButton": "Редагувати акаунт",
73 "settings.account.invoiceDownload": "Завантажити",
74 "settings.account.userInfoRequestFailed": "Не вдалося завантажити інформацію користувача",
75 "settings.account.tryReloadUserInfoRequest": "Спробуйте ще раз",
76 "settings.account.headlineProfile": "Оновити профіль",
77 "settings.account.headlineAccount": "Інформація про акаунт",
78 "settings.account.headlinePassword": "Змінити пароль",
79 "settings.account.successInfo": "Ваші зміни були збережені",
80 "settings.account.buttonSave": "Оновити профіль",
81 "settings.account.mining.thankyou": "Дякую, що підтримуєте Franz своєю обчислювальною потужністю.",
82 "settings.account.mining.active": "Ви зараз здійснюєте {hashes} розрахунків за секунду.",
83 "settings.account.mining.moreInformation": "Отримати більше інформації",
84 "settings.account.mining.cancel": "Скасувати видобуток",
85 "settings.navigation.availableServices": "Доступні сервіси",
86 "settings.navigation.yourServices": "Ваші сервіси",
87 "settings.navigation.account": "Акаунт",
88 "settings.navigation.settings": "Налаштування",
89 "settings.navigation.logout": "Вийти",
90 "settings.recipes.headline": "Доступні сервіси",
91 "settings.recipes.mostPopular": "Найбільш популярні",
92 "settings.recipes.all": "Всі сервіси",
93 "settings.recipes.dev": "Розробка",
94 "settings.recipes.nothingFound": "Вибачте, але жоден сервіс не відповідає пошуковому терміну.",
95 "settings.recipes.servicesSuccessfulAddedInfo": "Сервіс успішно додано",
96 "settings.service.form.saveButton": "Зберегти сервіс",
97 "settings.service.form.deleteButton": "Видалити сервіс",
98 "settings.service.form.availableServices": "Доступні сервіси",
99 "settings.service.form.yourServices": "Ваші сервіси",
100 "settings.service.form.addServiceHeadline": "Додати {name}",
101 "settings.service.form.editServiceHeadline": "Редагувати {name}",
102 "settings.service.form.tabHosted": "Розміщений",
103 "settings.service.form.tabOnPremise": "Самостійно розміщений ⭐️",
104 "settings.service.form.customUrlValidationError": "Не вдалось підтвердити власний {name} сервер.",
105 "settings.service.form.customUrlPremiumInfo": "Щоб додати самостійно розміщені сервіси, вам потріьно мати Преміумним Акаунт Прихильника Franz.",
106 "settings.service.form.customUrlUpgradeAccount": "Оновити ваш обліковий запис",
107 "settings.service.form.indirectMessageInfo": "Ви отримаєте сповіщення про всі нові повідомлення в каналі, а не лише про @username, @channel, @here, ...",
108 "settings.service.error.headline": "Помилка",
109 "settings.service.error.goBack": "Повернутись до сервісів",
110 "settings.service.error.message": "Не вдалось завантажити серверний протокол.",
111 "settings.services.tooltip.isDisabled": "Сервіс відключений",
112 "settings.services.tooltip.notificationsDisabled": "Сповіщення відключені",
113 "settings.services.headline": "Ваші сервіси",
114 "settings.services.noServicesAdded": "Ви ще не додавали жодних сервісів.",
115 "settings.services.discoverServices": "Відкрийте для себе сервіси",
116 "settings.services.updatedInfo": "Ваші зміни були збережені",
117 "settings.services.deletedInfo": "Сервіс було видалено",
118 "settings.app.headline": "Налаштування",
119 "settings.app.headlineGeneral": "Загальні",
120 "settings.app.headlineLanguage": "Мова",
121 "settings.app.headlineUpdates": "Оновлення",
122 "settings.app.buttonSearchForUpdate": "Перевірити наявність оновлень",
123 "settings.app.buttonInstallUpdate": "Перезавантажити і встановити оновлення",
124 "settings.app.updateStatusSearching": "Шукає оновлення",
125 "settings.app.updateStatusAvailable": "Оновлення доступне, завантаження...",
126 "settings.app.updateStatusUpToDate": "Ви використовуєте останню версію Franz",
127 "settings.app.form.autoLaunchOnStart": "Запускати Franz на початку",
128 "settings.app.form.autoLaunchInBackground": "Відкрити у фоновому режимі",
129 "settings.app.form.minimizeToSystemTray": "Мінімізувати Franz до системного лотка",
130 "settings.app.form.runInBackground": "Тримати Franz в фоні при закритті вікна",
131 "settings.app.form.language": "Мова",
132 "settings.app.form.beta": "Включити бета-версії",
133 "settings.app.currentVersion": "Поточна версія:",
134 "settings.service.form.name": "Ім'я",
135 "settings.service.form.enableService": "Увімкнути сервіс",
136 "settings.service.form.enableNotification": "Увімкнути сповіщення",
137 "settings.service.form.team": "Команда",
138 "settings.service.form.customUrl": "Користувацький сервер",
139 "settings.service.form.indirectMessages": "Показувати значок повідомлення для всіх нових повідомлень",
140 "settings.user.form.firstname": "Ім'я",
141 "settings.user.form.lastname": "Прізвище",
142 "settings.user.form.email": "Email",
143 "settings.user.form.currentPassword": "Поточний пароль",
144 "settings.user.form.newPassword": "Новий пароль",
145 "settings.user.form.accountType.label": "Тип акаунту",
146 "settings.user.form.accountType.individual": "Індивідуальний",
147 "settings.user.form.accountType.non-profit": "Некомерційний",
148 "settings.user.form.accountType.company": "Компанія",
149 "subscription.type.free": "безплатно",
150 "subscription.type.month": "місяць",
151 "subscription.type.year": "рік",
152 "subscription.type.mining": "Підтримати Franz обчислювальною потужністю",
153 "subscription.mining.headline": "Як це працює?",
154 "subscription.mining.experimental": "експериментальний",
155 "subscription.mining.line1": "Вмикаючи \"Підтримати обчислювальною потужністю\", Franz буде використовувати приблизно 20-50% вашого процесора щоб майнити криптовалюту Monero, що приблизно рівне $ 5/рік.",
156 "subscription.mining.line2": "Ми адаптуємо використання процесора відповідно до вашої поведінки, щоб не виснажувати акумулятор, не сповільнити вашу роботу і роботу вашої машини.",
157 "subscription.mining.line3": "Поки майнер активний, ви матимете необмежений доступ до всіх особливостей підтримки Franz Premium.",
158 "subscription.mining.moreInformation": "Отримати більше інформації про цей план.",
159 "subscriptionPopup.buttonCancel": "Відмінити",
160 "subscriptionPopup.buttonDone": "Готово",
161 "tabs.item.reload": "Перезавантажити",
162 "tabs.item.edit": "Редагувати",
163 "tabs.item.disableNotifications": "Вимкнути сповіщення",
164 "tabs.item.enableNotification": "Увімкнути сповіщення",
165 "tabs.item.disableService": "Вимкнути сервіс",
166 "tabs.item.deleteService": "Видалити сервіс"
167}
diff --git a/src/index.js b/src/index.js
index 3244c44ad..9ca059f48 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,21 +2,22 @@ import { app, BrowserWindow, shell } from 'electron';
2import fs from 'fs-extra'; 2import fs from 'fs-extra';
3import path from 'path'; 3import path from 'path';
4 4
5// eslint-disable-next-line 5/* eslint-disable */
6if (require('electron-squirrel-startup')) app.quit(); 6if (require('electron-squirrel-startup')) app.quit();
7 7
8import windowStateKeeper from 'electron-window-state'; // eslint-disable-line 8import windowStateKeeper from 'electron-window-state';
9 9
10import { isDevMode, isWindows } from './environment'; // eslint-disable-line 10import { isDevMode, isWindows } from './environment';
11import ipcApi from './electron/ipc-api'; // eslint-disable-line 11import ipcApi from './electron/ipc-api';
12import Settings from './electron/Settings'; // eslint-disable-line 12import Tray from './lib/Tray';
13import { appId } from './package.json'; // eslint-disable-line 13import Settings from './electron/Settings';
14import './electron/exception'; // eslint-disable-line 14import { appId } from './package.json';
15import './electron/exception';
16/* eslint-enable */
15 17
16// Keep a global reference of the window object, if you don't, the window will 18// Keep a global reference of the window object, if you don't, the window will
17// be closed automatically when the JavaScript object is garbage collected. 19// be closed automatically when the JavaScript object is garbage collected.
18let mainWindow; 20let mainWindow;
19const settings = new Settings();
20let willQuitApp = false; 21let willQuitApp = false;
21 22
22// Ensure that the recipe directory exists 23// Ensure that the recipe directory exists
@@ -27,6 +28,23 @@ if (isWindows) {
27 app.setAppUserModelId(appId); 28 app.setAppUserModelId(appId);
28} 29}
29 30
31// Force single window
32if (process.platform !== 'darwin') {
33 const isSecondInstance = app.makeSingleInstance(() => {
34 if (mainWindow) {
35 if (mainWindow.isMinimized()) mainWindow.restore();
36 mainWindow.focus();
37 }
38 });
39
40 if (isSecondInstance) {
41 app.quit();
42 }
43}
44
45// Initialize Settings
46const settings = new Settings();
47
30const createWindow = async () => { 48const createWindow = async () => {
31 // Remember window size 49 // Remember window size
32 const mainWindowState = windowStateKeeper({ 50 const mainWindowState = windowStateKeeper({
@@ -47,8 +65,11 @@ const createWindow = async () => {
47 autoHideMenuBar: true, 65 autoHideMenuBar: true,
48 }); 66 });
49 67
68 // Initialize System Tray
69 const trayIcon = new Tray(mainWindow);
70
50 // Initialize ipcApi 71 // Initialize ipcApi
51 ipcApi({ mainWindow, settings }); 72 ipcApi({ mainWindow, settings, trayIcon });
52 73
53 // Manage Window State 74 // Manage Window State
54 mainWindowState.manage(mainWindow); 75 mainWindowState.manage(mainWindow);
@@ -85,6 +106,7 @@ const createWindow = async () => {
85 106
86 if (settings.get('minimizeToSystemTray')) { 107 if (settings.get('minimizeToSystemTray')) {
87 mainWindow.setSkipTaskbar(true); 108 mainWindow.setSkipTaskbar(true);
109 trayIcon.show();
88 } 110 }
89 }); 111 });
90 112
@@ -102,6 +124,10 @@ const createWindow = async () => {
102 if (app.wasMaximized) { 124 if (app.wasMaximized) {
103 mainWindow.maximize(); 125 mainWindow.maximize();
104 } 126 }
127
128 if (!settings.get('enableSystemTray')) {
129 trayIcon.hide();
130 }
105 }); 131 });
106 132
107 mainWindow.on('show', () => { 133 mainWindow.on('show', () => {
diff --git a/src/lib/Menu.js b/src/lib/Menu.js
index 9f23c4d70..a6cde4d36 100644
--- a/src/lib/Menu.js
+++ b/src/lib/Menu.js
@@ -49,6 +49,7 @@ const template = [
49 }, 49 },
50 { 50 {
51 role: 'zoomin', 51 role: 'zoomin',
52 accelerator: 'CommandOrControl+=',
52 }, 53 },
53 { 54 {
54 role: 'zoomout', 55 role: 'zoomout',
diff --git a/src/lib/Tray.js b/src/lib/Tray.js
new file mode 100644
index 000000000..67150971e
--- /dev/null
+++ b/src/lib/Tray.js
@@ -0,0 +1,73 @@
1import { app, Tray, Menu, systemPreferences } from 'electron';
2import path from 'path';
3
4const FILE_EXTENSION = process.platform === 'win32' ? 'ico' : 'png';
5const INDICATOR_TRAY_PLAIN = 'tray';
6const INDICATOR_TRAY_UNREAD = 'tray-unread';
7
8export default class TrayIcon {
9 mainWindow = null;
10 trayIcon = null;
11
12 constructor(mainWindow) {
13 this.mainWindow = mainWindow;
14 }
15
16 show() {
17 if (this.trayIcon) return;
18
19 this.trayIcon = new Tray(this._getAsset('tray', INDICATOR_TRAY_PLAIN));
20 const trayMenuTemplate = [
21 {
22 label: 'Show Franz',
23 click() {
24 this.mainWindow.show();
25 },
26 }, {
27 label: 'Quit Franz',
28 click() {
29 app.quit();
30 },
31 },
32 ];
33
34 const trayMenu = Menu.buildFromTemplate(trayMenuTemplate);
35 this.trayIcon.setContextMenu(trayMenu);
36
37 this.trayIcon.on('click', () => {
38 this.mainWindow.show();
39 });
40 }
41
42 hide() {
43 if (this.trayIcon) {
44 this.trayIcon.destroy();
45 this.trayIcon = null;
46 }
47 }
48
49 setIndicator(indicator) {
50 if (!this.trayIcon) return;
51
52 this.trayIcon.setImage(this._getAsset('tray', indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN));
53
54 if (process.platform === 'darwin') {
55 this.trayIcon.setPressedImage(
56 this._getAsset('tray', `${indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN}-active`),
57 );
58 }
59 }
60
61
62 _getAsset(type, asset) {
63 let platform = process.platform;
64
65 if (platform === 'darwin' && systemPreferences.isDarkMode()) {
66 platform = `${platform}-dark`;
67 }
68
69 return path.join(
70 __dirname, '..', 'assets', 'images', type, platform, `${asset}.${FILE_EXTENSION}`,
71 );
72 }
73}
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index a5e0839f2..7dbef985d 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -16,10 +16,6 @@ import Miner from '../lib/Miner';
16const { app, getCurrentWindow, powerMonitor } = remote; 16const { app, getCurrentWindow, powerMonitor } = remote;
17const defaultLocale = 'en-US'; 17const defaultLocale = 'en-US';
18 18
19const appFolder = path.dirname(process.execPath);
20const updateExe = path.resolve(appFolder, '..', 'Update.exe');
21const exeName = path.basename(process.execPath);
22
23export default class AppStore extends Store { 19export default class AppStore extends Store {
24 updateStatusTypes = { 20 updateStatusTypes = {
25 CHECKING: 'CHECKING', 21 CHECKING: 'CHECKING',
@@ -84,7 +80,7 @@ export default class AppStore extends Store {
84 // Check for updates once every 4 hours 80 // Check for updates once every 4 hours
85 setInterval(() => this._checkForUpdates(), CHECK_INTERVAL); 81 setInterval(() => this._checkForUpdates(), CHECK_INTERVAL);
86 // Check for an update in 30s (need a delay to prevent Squirrel Installer lock file issues) 82 // Check for an update in 30s (need a delay to prevent Squirrel Installer lock file issues)
87 setTimeout(() => this._checkForUpdates(), 3000); 83 setTimeout(() => this._checkForUpdates(), 30000);
88 ipcRenderer.on('autoUpdate', (event, data) => { 84 ipcRenderer.on('autoUpdate', (event, data) => {
89 if (data.available) { 85 if (data.available) {
90 this.updateStatus = this.updateStatusTypes.AVAILABLE; 86 this.updateStatus = this.updateStatusTypes.AVAILABLE;
@@ -125,6 +121,18 @@ export default class AppStore extends Store {
125 this.actions.service.openDevToolsForActiveService(); 121 this.actions.service.openDevToolsForActiveService();
126 }); 122 });
127 123
124 // Set active the next service
125 key(
126 '⌘+pagedown, ctrl+pagedown, ⌘+shift+tab, ctrl+shift+tab', () => {
127 this.actions.service.setActiveNext();
128 });
129
130 // Set active the prev service
131 key(
132 '⌘+pageup, ctrl+pageup, ⌘+tab, ctrl+tab', () => {
133 this.actions.service.setActivePrev();
134 });
135
128 this.locale = this._getDefaultLocale(); 136 this.locale = this._getDefaultLocale();
129 137
130 this._healthCheck(); 138 this._healthCheck();
@@ -161,24 +169,27 @@ export default class AppStore extends Store {
161 @action _launchOnStartup({ enable, openInBackground }) { 169 @action _launchOnStartup({ enable, openInBackground }) {
162 this.autoLaunchOnStart = enable; 170 this.autoLaunchOnStart = enable;
163 171
164 const settings = { 172 let settings = {
165 openAtLogin: enable, 173 openAtLogin: enable,
166 openAsHidden: openInBackground,
167 path: updateExe,
168 args: [
169 '--processStart', `"${exeName}"`,
170 ],
171 }; 174 };
172 175
173 // For Windows 176 // For Windows
174 if (openInBackground) { 177 if (process.platform === 'win32') {
175 settings.args.push( 178 settings = Object.assign({
176 '--process-start-args', '"--hidden"', 179 openAsHidden: openInBackground,
177 ); 180 path: app.getPath('exe'),
181 args: [
182 '--processStart', `"${path.basename(app.getPath('exe'))}"`,
183 ],
184 }, settings);
185
186 if (openInBackground) {
187 settings.args.push(
188 '--process-start-args', '"--hidden"',
189 );
190 }
178 } 191 }
179 192
180 app.setLoginItemSettings(settings);
181
182 gaEvent('App', enable ? 'enable autostart' : 'disable autostart'); 193 gaEvent('App', enable ? 'enable autostart' : 'disable autostart');
183 } 194 }
184 195
@@ -291,6 +302,12 @@ export default class AppStore extends Store {
291 // we need to wait until the settings request is resolved 302 // we need to wait until the settings request is resolved
292 await this.stores.settings.allSettingsRequest; 303 await this.stores.settings.allSettingsRequest;
293 304
305 // We don't set autostart on first launch for macOS as disabling
306 // the option is currently broken
307 // https://github.com/meetfranz/franz/issues/17
308 // https://github.com/electron/electron/issues/10880
309 if (process.platform === 'darwin') return;
310
294 if (!this.stores.settings.all.appStarts) { 311 if (!this.stores.settings.all.appStarts) {
295 this.actions.app.launchOnStartup({ 312 this.actions.app.launchOnStartup({
296 enable: true, 313 enable: true,
@@ -301,7 +318,7 @@ export default class AppStore extends Store {
301 318
302 _checkAutoStart() { 319 _checkAutoStart() {
303 const loginItem = app.getLoginItemSettings({ 320 const loginItem = app.getLoginItemSettings({
304 path: updateExe, 321 path: app.getPath('exe'),
305 }); 322 });
306 323
307 this.autoLaunchOnStart = loginItem.openAtLogin; 324 this.autoLaunchOnStart = loginItem.openAtLogin;
diff --git a/src/stores/RecipesStore.js b/src/stores/RecipesStore.js
index cdc274685..67fee1d50 100644
--- a/src/stores/RecipesStore.js
+++ b/src/stores/RecipesStore.js
@@ -65,6 +65,10 @@ export default class RecipesStore extends Store {
65 @action async _update() { 65 @action async _update() {
66 const recipeIds = this.recipeIdForServices; 66 const recipeIds = this.recipeIdForServices;
67 const recipes = {}; 67 const recipes = {};
68
69 // Hackfix, reference this.all to fetch services
70 console.debug(`Check Recipe updates for ${this.all.map(recipe => recipe.id)}`);
71
68 recipeIds.forEach((r) => { 72 recipeIds.forEach((r) => {
69 const recipe = this.one(r); 73 const recipe = this.one(r);
70 recipes[r] = recipe.version; 74 recipes[r] = recipe.version;
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 77d2e7da4..19db05494 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -24,6 +24,8 @@ export default class ServicesStore extends Store {
24 24
25 // Register action handlers 25 // Register action handlers
26 this.actions.service.setActive.listen(this._setActive.bind(this)); 26 this.actions.service.setActive.listen(this._setActive.bind(this));
27 this.actions.service.setActiveNext.listen(this._setActiveNext.bind(this));
28 this.actions.service.setActivePrev.listen(this._setActivePrev.bind(this));
27 this.actions.service.showAddServiceInterface.listen(this._showAddServiceInterface.bind(this)); 29 this.actions.service.showAddServiceInterface.listen(this._showAddServiceInterface.bind(this));
28 this.actions.service.createService.listen(this._createService.bind(this)); 30 this.actions.service.createService.listen(this._createService.bind(this));
29 this.actions.service.createFromLegacyService.listen(this._createFromLegacyService.bind(this)); 31 this.actions.service.createFromLegacyService.listen(this._createFromLegacyService.bind(this));
@@ -206,6 +208,24 @@ export default class ServicesStore extends Store {
206 service.isActive = true; 208 service.isActive = true;
207 } 209 }
208 210
211 @action _setActiveNext() {
212 const nextIndex = this._wrapIndex(this.enabled.findIndex(service => service.isActive), 1, this.enabled.length);
213
214 this.all.forEach((s, index) => {
215 this.all[index].isActive = false;
216 });
217 this.enabled[nextIndex].isActive = true;
218 }
219
220 @action _setActivePrev() {
221 const prevIndex = this._wrapIndex(this.enabled.findIndex(service => service.isActive), -1, this.enabled.length);
222
223 this.all.forEach((s, index) => {
224 this.all[index].isActive = false;
225 });
226 this.enabled[prevIndex].isActive = true;
227 }
228
209 @action _setUnreadMessageCount({ serviceId, count }) { 229 @action _setUnreadMessageCount({ serviceId, count }) {
210 const service = this.one(serviceId); 230 const service = this.one(serviceId);
211 231
@@ -500,4 +520,8 @@ export default class ServicesStore extends Store {
500 _reorderAnalytics = debounce(() => { 520 _reorderAnalytics = debounce(() => {
501 gaEvent('Service', 'order'); 521 gaEvent('Service', 'order');
502 }, 5000); 522 }, 5000);
523
524 _wrapIndex(index, delta, size) {
525 return (((index + delta) % size) + size) % size;
526 }
503} 527}
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js
index 4927d615f..1cb2ecac3 100644
--- a/src/stores/UserStore.js
+++ b/src/stores/UserStore.js
@@ -192,6 +192,15 @@ export default class UserStore extends Store {
192 @action async _importLegacyServices({ services }) { 192 @action async _importLegacyServices({ services }) {
193 this.isImportLegacyServicesExecuting = true; 193 this.isImportLegacyServicesExecuting = true;
194 194
195 // Reduces recipe duplicates
196 const recipes = services.filter((obj, pos, arr) => arr.map(mapObj => mapObj.recipe.id).indexOf(obj.recipe.id) === pos).map(s => s.recipe.id);
197
198 // Install recipes
199 for (const recipe of recipes) {
200 // eslint-disable-next-line
201 await this.stores.recipes._install({ recipeId: recipe });
202 }
203
195 for (const service of services) { 204 for (const service of services) {
196 this.actions.service.createFromLegacyService({ 205 this.actions.service.createFromLegacyService({
197 data: service, 206 data: service,
diff --git a/src/styles/infobox.scss b/src/styles/infobox.scss
index ad363314d..7ab094058 100644
--- a/src/styles/infobox.scss
+++ b/src/styles/infobox.scss
@@ -31,6 +31,11 @@
31 color: #FFF; 31 color: #FFF;
32 } 32 }
33 33
34 &.infobox--warning {
35 background: $theme-brand-warning;
36 color: #FFF;
37 }
38
34 .mdi { 39 .mdi {
35 margin-right: 10px; 40 margin-right: 10px;
36 } 41 }
diff --git a/src/styles/main.scss b/src/styles/main.scss
index 8afc86f98..0a082729c 100644
--- a/src/styles/main.scss
+++ b/src/styles/main.scss
@@ -20,6 +20,7 @@ $mdi-font-path: '../node_modules/mdi/fonts';
20@import './auth.scss'; 20@import './auth.scss';
21@import './tooltip.scss'; 21@import './tooltip.scss';
22@import './info-bar.scss'; 22@import './info-bar.scss';
23@import './status-bar-target-url.scss';
23@import './animations.scss'; 24@import './animations.scss';
24@import './infobox.scss'; 25@import './infobox.scss';
25@import './badge.scss'; 26@import './badge.scss';
diff --git a/src/styles/status-bar-target-url.scss b/src/styles/status-bar-target-url.scss
new file mode 100644
index 000000000..bc7438be9
--- /dev/null
+++ b/src/styles/status-bar-target-url.scss
@@ -0,0 +1,14 @@
1@import './config.scss';
2
3.status-bar-target-url {
4 height: auto;
5 background: $theme-gray-lighter;
6 padding: 4px;
7 position: absolute;
8 box-shadow: 0 0 8px rgba(black, 0.2);
9 font-size: 12px;
10 color: $theme-gray-dark;
11 bottom: 0;
12 right: 0;
13 border-top-left-radius: 5px;
14}