diff options
34 files changed, 1012 insertions, 188 deletions
diff --git a/.travis.yml b/.travis.yml index 3ece585de..b3ebc4f25 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -1,21 +1,36 @@ | |||
1 | matrix: | ||
2 | include: | ||
3 | - os: linux | ||
4 | dist: trusty | ||
5 | sudo: required | ||
6 | - os: osx | ||
7 | osx_image: xcode8.3 | ||
8 | |||
1 | language: node_js | 9 | language: node_js |
10 | |||
2 | before_script: | 11 | before_script: |
3 | - yarn add global gulp-cli@1.2.2 | 12 | - yarn add global gulp-cli@1.2.2 |
4 | - yarn add global gulpjs/gulp#4.0 | 13 | - yarn add global gulpjs/gulp#4.0 |
5 | - yarn add global node-sass | 14 | - yarn add global node-sass |
6 | - yarn install | 15 | - yarn install |
16 | |||
7 | script: | 17 | script: |
8 | - yarn lint | 18 | - yarn lint |
9 | - travis_wait yarn build | 19 | - travis_wait yarn build |
20 | |||
10 | node_js: | 21 | node_js: |
11 | - '7' | 22 | - '7' |
12 | os: osx | 23 | |
13 | osx_image: xcode8.3 | 24 | before_install: |
25 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt install libx11-dev libxext-dev libxss-dev libxkbfile-dev; fi | ||
26 | |||
14 | cache: yarn | 27 | cache: yarn |
28 | |||
15 | notifications: | 29 | notifications: |
16 | email: false | 30 | email: false |
17 | slack: | 31 | slack: |
18 | secure: NjEDG+6YvJvFNwRT8t8XyVR145m+Pb1pmYgdBeuhqtJbMAr0IOb0lLLW9ixKEsL1NU+0R58QGiG9qqY+lLnMNpDYjzluFo0gQtl2NJrULT4xUFDSu65XTwoutKyvj+hoCsHiwrSrO2dHTx3ZK2vsSueg+8jM/xss7dTLA6BcTYl14wTOU37PqFQZk9JYR+Dfq1Jjhy/mq4BiAsb/1clNIulkjmRjSm6R0XT4ZsZZfj0ifXhL4cLGsUv2n+iePiX6bLwZPFjXV1COYTBafbCu17gw3nRMdNMMTDLbwrXXdJZFS/EjFOPgOhwF7CkZ3kSpB2ZIcAJxG7iAUl5j+jHBXc5dafRbjzE4oYve1vPexLoV3NjV76uANUFkcli6eHYD0uJoUJGBRbRGWp+8Bbw9EcBsn4s3vbf5XqHX3S46zvGgqX+LyhyMJQtEG/iv+9XOsOql18ryyejij0z1K7DxpI0gLV1ATZCphY1Fyz1yZDGlYN4ej/Rl2P1Q3yXilweJRF7Ts04w4U9iuP1u598/w++CKSu4q4EeEuqT/hIeFQUKUkwCEsO4xa39vhLPaxKrG9UEUH8OXN+NPZyTAK/LKuIX7C56O1kwvWNMWlPmTcvsq2RghvNTwgSGUIO0EKZKrQYAEG3Y/veSt5CgZoNzLgc/6Xj+g7daxUo9heLy26A= | 32 | secure: NjEDG+6YvJvFNwRT8t8XyVR145m+Pb1pmYgdBeuhqtJbMAr0IOb0lLLW9ixKEsL1NU+0R58QGiG9qqY+lLnMNpDYjzluFo0gQtl2NJrULT4xUFDSu65XTwoutKyvj+hoCsHiwrSrO2dHTx3ZK2vsSueg+8jM/xss7dTLA6BcTYl14wTOU37PqFQZk9JYR+Dfq1Jjhy/mq4BiAsb/1clNIulkjmRjSm6R0XT4ZsZZfj0ifXhL4cLGsUv2n+iePiX6bLwZPFjXV1COYTBafbCu17gw3nRMdNMMTDLbwrXXdJZFS/EjFOPgOhwF7CkZ3kSpB2ZIcAJxG7iAUl5j+jHBXc5dafRbjzE4oYve1vPexLoV3NjV76uANUFkcli6eHYD0uJoUJGBRbRGWp+8Bbw9EcBsn4s3vbf5XqHX3S46zvGgqX+LyhyMJQtEG/iv+9XOsOql18ryyejij0z1K7DxpI0gLV1ATZCphY1Fyz1yZDGlYN4ej/Rl2P1Q3yXilweJRF7Ts04w4U9iuP1u598/w++CKSu4q4EeEuqT/hIeFQUKUkwCEsO4xa39vhLPaxKrG9UEUH8OXN+NPZyTAK/LKuIX7C56O1kwvWNMWlPmTcvsq2RghvNTwgSGUIO0EKZKrQYAEG3Y/veSt5CgZoNzLgc/6Xj+g7daxUo9heLy26A= |
33 | |||
19 | deploy: | 34 | deploy: |
20 | provider: s3 | 35 | provider: s3 |
21 | access_key_id: AKIAIVRBS4YFL4ZBLCLA | 36 | access_key_id: AKIAIVRBS4YFL4ZBLCLA |
@@ -29,6 +44,7 @@ deploy: | |||
29 | acl: public_read | 44 | acl: public_read |
30 | on: | 45 | on: |
31 | all_branches: true | 46 | all_branches: true |
47 | |||
32 | env: | 48 | env: |
33 | global: | 49 | global: |
34 | - secure: fddJzSmNYVX024jnhnFXEuAK1spEYi3y3RZdWaBtjQnzoObAxkcRW263JNpXQy+b7egnp2hSy8FvlQU+L967911F5Y70Pe3An4oI72hnS3DL4Njp2Dw5PwviwMA+X2ddWhzK4+k/JU6r8jBv1FGQ6ZjwSeaO/t8UKOsE8wDBFLRhnHqoR7QbM7zmKjzh/1oofunGbHsPOHmN4f7jBwSuSFTZltEENcQg3ZP++0NHU8UJdlpfqZOkro8v4AJMngAHeHlNtjwaAHdVv+6+kkwc4E/0Cy6YNyyBkbzipyngNY3GwnwzmNzvsfICD1TGklksjBlMQq7ld7eCiaYRNvyHVEmXJ17qlq7HhxkYgNy32hPRwb5Cv6o4M4tv8qS8UUk4W1RvBJ5fcmfZGQwGXPyQ/m85RJtrNfbYtr84jYcprTnSeji/9PuZv0f87dxELYm3DYmNUa1cgJqEdLUsEd0bMwUYNLnCSfu4ea2zxwir6LSBtJJCbGKxX87s5IOTrHkrWDe+PWd52v+UjQks7MBRlJnntTWo69Yy+ayXV1TnGVOHA5znHvPOvFlAF+y8tLGd4AGvehK1SAkf0+idmc9Q9xKk0QypT3ibjJui4D50p7sSajkzz3P2pUqOS/9HmjMfPMPN+Nl+48GU0CvB2aBGhdmp9vu54VaFzUaAGNGj4WI= | 50 | - secure: fddJzSmNYVX024jnhnFXEuAK1spEYi3y3RZdWaBtjQnzoObAxkcRW263JNpXQy+b7egnp2hSy8FvlQU+L967911F5Y70Pe3An4oI72hnS3DL4Njp2Dw5PwviwMA+X2ddWhzK4+k/JU6r8jBv1FGQ6ZjwSeaO/t8UKOsE8wDBFLRhnHqoR7QbM7zmKjzh/1oofunGbHsPOHmN4f7jBwSuSFTZltEENcQg3ZP++0NHU8UJdlpfqZOkro8v4AJMngAHeHlNtjwaAHdVv+6+kkwc4E/0Cy6YNyyBkbzipyngNY3GwnwzmNzvsfICD1TGklksjBlMQq7ld7eCiaYRNvyHVEmXJ17qlq7HhxkYgNy32hPRwb5Cv6o4M4tv8qS8UUk4W1RvBJ5fcmfZGQwGXPyQ/m85RJtrNfbYtr84jYcprTnSeji/9PuZv0f87dxELYm3DYmNUa1cgJqEdLUsEd0bMwUYNLnCSfu4ea2zxwir6LSBtJJCbGKxX87s5IOTrHkrWDe+PWd52v+UjQks7MBRlJnntTWo69Yy+ayXV1TnGVOHA5znHvPOvFlAF+y8tLGd4AGvehK1SAkf0+idmc9Q9xKk0QypT3ibjJui4D50p7sSajkzz3P2pUqOS/9HmjMfPMPN+Nl+48GU0CvB2aBGhdmp9vu54VaFzUaAGNGj4WI= |
diff --git a/package.json b/package.json index dcb05bf6a..fc0954e94 100644 --- a/package.json +++ b/package.json | |||
@@ -27,12 +27,13 @@ | |||
27 | "license": "Apache-2.0", | 27 | "license": "Apache-2.0", |
28 | "dependencies": { | 28 | "dependencies": { |
29 | "@paulcbetts/system-idle-time": "^1.0.4", | 29 | "@paulcbetts/system-idle-time": "^1.0.4", |
30 | "address-rfc2822": "^2.0.1", | ||
31 | "auto-launch": "https://github.com/meetfranz/node-auto-launch.git", | ||
30 | "babel-polyfill": "^6.23.0", | 32 | "babel-polyfill": "^6.23.0", |
31 | "babel-runtime": "^6.23.0", | 33 | "babel-runtime": "^6.23.0", |
32 | "classnames": "^2.2.5", | 34 | "classnames": "^2.2.5", |
33 | "electron-fetch": "^1.1.0", | 35 | "electron-fetch": "^1.1.0", |
34 | "electron-spellchecker": "^1.2.0", | 36 | "electron-spellchecker": "^1.2.0", |
35 | "electron-squirrel-startup": "^1.0.0", | ||
36 | "electron-updater": "^2.4.3", | 37 | "electron-updater": "^2.4.3", |
37 | "electron-window-state": "^4.1.0", | 38 | "electron-window-state": "^4.1.0", |
38 | "fs-extra": "^3.0.1", | 39 | "fs-extra": "^3.0.1", |
diff --git a/src/actions/service.js b/src/actions/service.js index cdd4bbf16..ea6ea5acc 100644 --- a/src/actions/service.js +++ b/src/actions/service.js | |||
@@ -63,6 +63,7 @@ export default { | |||
63 | needle: PropTypes.string.isRequired, | 63 | needle: PropTypes.string.isRequired, |
64 | }, | 64 | }, |
65 | resetFilter: {}, | 65 | resetFilter: {}, |
66 | resetStatus: {}, | ||
66 | reorder: { | 67 | reorder: { |
67 | oldIndex: PropTypes.number.isRequired, | 68 | oldIndex: PropTypes.number.isRequired, |
68 | newIndex: PropTypes.number.isRequired, | 69 | newIndex: PropTypes.number.isRequired, |
diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js index 8b0b7563c..932b70cdc 100644 --- a/src/api/server/ServerApi.js +++ b/src/api/server/ServerApi.js | |||
@@ -499,7 +499,7 @@ export default class ServerApi { | |||
499 | 499 | ||
500 | return recipe; | 500 | return recipe; |
501 | }), | 501 | }), |
502 | ).catch(err => console.error(err)); | 502 | ).catch(err => console.error('Can\'t load recipe', err)); |
503 | } | 503 | } |
504 | 504 | ||
505 | _mapRecipePreviewModel(recipes) { | 505 | _mapRecipePreviewModel(recipes) { |
@@ -562,9 +562,16 @@ export default class ServerApi { | |||
562 | .filter(file => fs.statSync(path.join(recipesDirectory, file)).isDirectory() && file !== 'temp'); | 562 | .filter(file => fs.statSync(path.join(recipesDirectory, file)).isDirectory() && file !== 'temp'); |
563 | 563 | ||
564 | const recipes = paths.map((id) => { | 564 | const recipes = paths.map((id) => { |
565 | // eslint-disable-next-line | 565 | let Recipe; |
566 | const Recipe = require(id)(RecipeModel); | 566 | try { |
567 | return new Recipe(loadRecipeConfig(id)); | 567 | // eslint-disable-next-line |
568 | Recipe = require(id)(RecipeModel); | ||
569 | return new Recipe(loadRecipeConfig(id)); | ||
570 | } catch (err) { | ||
571 | console.error(err); | ||
572 | } | ||
573 | |||
574 | return false; | ||
568 | }).filter(recipe => recipe.id).map((data) => { | 575 | }).filter(recipe => recipe.id).map((data) => { |
569 | const recipe = data; | 576 | const recipe = data; |
570 | 577 | ||
@@ -579,7 +586,7 @@ export default class ServerApi { | |||
579 | 586 | ||
580 | return recipes; | 587 | return recipes; |
581 | } catch (err) { | 588 | } catch (err) { |
582 | console.debug('Folder `recipe/dev` does not exist'); | 589 | console.debug('Could not load dev recipes'); |
583 | return false; | 590 | return false; |
584 | } | 591 | } |
585 | } | 592 | } |
diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js index 4aee1ec60..6a5c0f365 100644 --- a/src/components/layout/Sidebar.js +++ b/src/components/layout/Sidebar.js | |||
@@ -52,7 +52,7 @@ export default class Sidebar extends Component { | |||
52 | <button | 52 | <button |
53 | onClick={openSettings} | 53 | onClick={openSettings} |
54 | className="sidebar__settings-button" | 54 | className="sidebar__settings-button" |
55 | data-tip={`Settings (${ctrlKey}+,)`} | 55 | data-tip={`${intl.formatMessage(messages.settings)} (${ctrlKey}+,)`} |
56 | > | 56 | > |
57 | {isPremiumUser && ( | 57 | {isPremiumUser && ( |
58 | <span className="emoji"> | 58 | <span className="emoji"> |
diff --git a/src/components/services/tabs/TabBarSortableList.js b/src/components/services/tabs/TabBarSortableList.js index c0a68d1a5..e5ae36419 100644 --- a/src/components/services/tabs/TabBarSortableList.js +++ b/src/components/services/tabs/TabBarSortableList.js | |||
@@ -1,44 +1,78 @@ | |||
1 | import React from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import { observer } from 'mobx-react'; | 2 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; |
3 | import PropTypes from 'prop-types'; | ||
3 | import { SortableContainer } from 'react-sortable-hoc'; | 4 | import { SortableContainer } from 'react-sortable-hoc'; |
5 | import { defineMessages, intlShape } from 'react-intl'; | ||
4 | 6 | ||
5 | import TabItem from './TabItem'; | 7 | import TabItem from './TabItem'; |
6 | import { ctrlKey } from '../../../environment'; | 8 | import { ctrlKey } from '../../../environment'; |
7 | 9 | ||
8 | export default SortableContainer(observer(({ | 10 | const messages = defineMessages({ |
9 | services, | 11 | addNewService: { |
10 | setActive, | 12 | id: 'sidebar.addNewService', |
11 | reload, | 13 | defaultMessage: '!!!Add new service', |
12 | toggleNotifications, | 14 | }, |
13 | deleteService, | 15 | }); |
14 | disableService, | 16 | |
15 | openSettings, | 17 | @observer |
16 | }) => ( | 18 | class TabBarSortableList extends Component { |
17 | <ul | 19 | static propTypes = { |
18 | className="tabs" | 20 | services: MobxPropTypes.arrayOrObservableArray.isRequired, |
19 | > | 21 | setActive: PropTypes.func.isRequired, |
20 | {services.map((service, index) => ( | 22 | openSettings: PropTypes.func.isRequired, |
21 | <TabItem | 23 | reload: PropTypes.func.isRequired, |
22 | key={service.id} | 24 | toggleNotifications: PropTypes.func.isRequired, |
23 | clickHandler={() => setActive({ serviceId: service.id })} | 25 | deleteService: PropTypes.func.isRequired, |
24 | service={service} | 26 | disableService: PropTypes.func.isRequired, |
25 | index={index} | 27 | } |
26 | shortcutIndex={index + 1} | 28 | |
27 | reload={() => reload({ serviceId: service.id })} | 29 | static contextTypes = { |
28 | toggleNotifications={() => toggleNotifications({ serviceId: service.id })} | 30 | intl: intlShape, |
29 | deleteService={() => deleteService({ serviceId: service.id })} | 31 | }; |
30 | disableService={() => disableService({ serviceId: service.id })} | 32 | |
31 | openSettings={openSettings} | 33 | render() { |
32 | /> | 34 | const { |
33 | ))} | 35 | services, |
34 | <li> | 36 | setActive, |
35 | <button | 37 | reload, |
36 | className="sidebar__add-service" | 38 | toggleNotifications, |
37 | onClick={() => openSettings({ path: 'recipes' })} | 39 | deleteService, |
38 | data-tip={`Add new service (${ctrlKey}+N)`} | 40 | disableService, |
41 | openSettings, | ||
42 | } = this.props; | ||
43 | |||
44 | const { intl } = this.context; | ||
45 | |||
46 | return ( | ||
47 | <ul | ||
48 | className="tabs" | ||
39 | > | 49 | > |
40 | <span className="mdi mdi-plus" /> | 50 | {services.map((service, index) => ( |
41 | </button> | 51 | <TabItem |
42 | </li> | 52 | key={service.id} |
43 | </ul> | 53 | clickHandler={() => setActive({ serviceId: service.id })} |
44 | ))); | 54 | service={service} |
55 | index={index} | ||
56 | shortcutIndex={index + 1} | ||
57 | reload={() => reload({ serviceId: service.id })} | ||
58 | toggleNotifications={() => toggleNotifications({ serviceId: service.id })} | ||
59 | deleteService={() => deleteService({ serviceId: service.id })} | ||
60 | disableService={() => disableService({ serviceId: service.id })} | ||
61 | openSettings={openSettings} | ||
62 | /> | ||
63 | ))} | ||
64 | <li> | ||
65 | <button | ||
66 | className="sidebar__add-service" | ||
67 | onClick={() => openSettings({ path: 'recipes' })} | ||
68 | data-tip={`${intl.formatMessage(messages.addNewService)} (${ctrlKey}+N)`} | ||
69 | > | ||
70 | <span className="mdi mdi-plus" /> | ||
71 | </button> | ||
72 | </li> | ||
73 | </ul> | ||
74 | ); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | export default SortableContainer(TabBarSortableList); | ||
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index fac0f6b9a..9b359a78e 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js | |||
@@ -69,10 +69,6 @@ const messages = defineMessages({ | |||
69 | export default class EditServiceForm extends Component { | 69 | export default class EditServiceForm extends Component { |
70 | static propTypes = { | 70 | static propTypes = { |
71 | recipe: PropTypes.instanceOf(Recipe).isRequired, | 71 | recipe: PropTypes.instanceOf(Recipe).isRequired, |
72 | // service: PropTypes.oneOfType([ | ||
73 | // PropTypes.object, | ||
74 | // PropTypes.instanceOf(Service), | ||
75 | // ]), | ||
76 | service(props, propName) { | 72 | service(props, propName) { |
77 | if (props.action === 'edit' && !(props[propName] instanceof Service)) { | 73 | if (props.action === 'edit' && !(props[propName] instanceof Service)) { |
78 | return new Error(`'${propName}'' is expected to be of type 'Service' | 74 | return new Error(`'${propName}'' is expected to be of type 'Service' |
@@ -207,7 +203,7 @@ export default class EditServiceForm extends Component { | |||
207 | )} | 203 | )} |
208 | {recipe.hasCustomUrl && ( | 204 | {recipe.hasCustomUrl && ( |
209 | <TabItem title={intl.formatMessage(messages.tabOnPremise)}> | 205 | <TabItem title={intl.formatMessage(messages.tabOnPremise)}> |
210 | {user.isPremium ? ( | 206 | {user.isPremium || recipe.author.find(a => a.email === user.email) ? ( |
211 | <div> | 207 | <div> |
212 | <Input field={form.$('customUrl')} /> | 208 | <Input field={form.$('customUrl')} /> |
213 | {form.error === 'url-validation-error' && ( | 209 | {form.error === 'url-validation-error' && ( |
diff --git a/src/containers/settings/ServicesScreen.js b/src/containers/settings/ServicesScreen.js index d0580041f..8cfe5efbf 100644 --- a/src/containers/settings/ServicesScreen.js +++ b/src/containers/settings/ServicesScreen.js | |||
@@ -18,6 +18,7 @@ export default class ServicesScreen extends Component { | |||
18 | 18 | ||
19 | componentWillUnmount() { | 19 | componentWillUnmount() { |
20 | this.props.actions.service.resetFilter(); | 20 | this.props.actions.service.resetFilter(); |
21 | this.props.actions.service.resetStatus(); | ||
21 | } | 22 | } |
22 | 23 | ||
23 | deleteService() { | 24 | deleteService() { |
@@ -70,6 +71,7 @@ ServicesScreen.wrappedComponent.propTypes = { | |||
70 | toggleService: PropTypes.func.isRequired, | 71 | toggleService: PropTypes.func.isRequired, |
71 | filter: PropTypes.func.isRequired, | 72 | filter: PropTypes.func.isRequired, |
72 | resetFilter: PropTypes.func.isRequired, | 73 | resetFilter: PropTypes.func.isRequired, |
74 | resetStatus: PropTypes.func.isRequired, | ||
73 | }).isRequired, | 75 | }).isRequired, |
74 | }).isRequired, | 76 | }).isRequired, |
75 | }; | 77 | }; |
diff --git a/src/i18n/languages.js b/src/i18n/languages.js index 9860295b3..72d7b26c1 100644 --- a/src/i18n/languages.js +++ b/src/i18n/languages.js | |||
@@ -10,4 +10,8 @@ module.exports = { | |||
10 | pl: 'Polish', | 10 | pl: 'Polish', |
11 | ru: 'РуÑÑкий', | 11 | ru: 'РуÑÑкий', |
12 | ua: 'УкраїнÑька', | 12 | ua: 'УкраїнÑька', |
13 | it: 'Italian', | ||
14 | 'es-ES': 'Español - España', | ||
15 | 'zh-Hant': 'Chinese (Traditional)', | ||
16 | 'nb-NO': 'Norsk', | ||
13 | }; | 17 | }; |
diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index 0964169a8..80b66db08 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json | |||
@@ -60,6 +60,7 @@ | |||
60 | "infobar.buttonInstallUpdate": "Neustarten & Aktualisierung installieren", | 60 | "infobar.buttonInstallUpdate": "Neustarten & Aktualisierung installieren", |
61 | "infobar.requiredRequestsFailed": "Dienste und Benutzerinformationen konnten nicht geladen werden", | 61 | "infobar.requiredRequestsFailed": "Dienste und Benutzerinformationen konnten nicht geladen werden", |
62 | "sidebar.settings": "Einstellungen", | 62 | "sidebar.settings": "Einstellungen", |
63 | "sidebar.addNewService": "!!!Add new service", | ||
63 | "services.welcome": "Willkommen bei Franz", | 64 | "services.welcome": "Willkommen bei Franz", |
64 | "services.getStarted": "Loslegen", | 65 | "services.getStarted": "Loslegen", |
65 | "settings.account.headline": "Konto", | 66 | "settings.account.headline": "Konto", |
diff --git a/src/i18n/locales/el-GR.json b/src/i18n/locales/el-GR.json index dfada77a2..3710bc9a2 100644 --- a/src/i18n/locales/el-GR.json +++ b/src/i18n/locales/el-GR.json | |||
@@ -60,6 +60,7 @@ | |||
60 | "infobar.buttonInstallUpdate": "Επανεκκίνηση & εγκατάσταση ενημεÏώσεων", | 60 | "infobar.buttonInstallUpdate": "Επανεκκίνηση & εγκατάσταση ενημεÏώσεων", |
61 | "infobar.requiredRequestsFailed": "Δεν ήταν δυνατή η φόÏτωση υπηÏεσιών και πληÏοφοÏιών χÏηστών", | 61 | "infobar.requiredRequestsFailed": "Δεν ήταν δυνατή η φόÏτωση υπηÏεσιών και πληÏοφοÏιών χÏηστών", |
62 | "sidebar.settings": "Ρυθμίσεις", | 62 | "sidebar.settings": "Ρυθμίσεις", |
63 | "sidebar.addNewService": "!!!Add new service", | ||
63 | "services.welcome": "Καλώς οÏίσατε στον Franz", | 64 | "services.welcome": "Καλώς οÏίσατε στον Franz", |
64 | "services.getStarted": "Ξεκινήστε", | 65 | "services.getStarted": "Ξεκινήστε", |
65 | "settings.account.headline": "ΛογαÏιασμός", | 66 | "settings.account.headline": "ΛογαÏιασμός", |
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index b9ed51b83..b1d260f0a 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -60,6 +60,7 @@ | |||
60 | "infobar.buttonInstallUpdate": "Restart & install update", | 60 | "infobar.buttonInstallUpdate": "Restart & install update", |
61 | "infobar.requiredRequestsFailed": "Could not load services and user information", | 61 | "infobar.requiredRequestsFailed": "Could not load services and user information", |
62 | "sidebar.settings": "Settings", | 62 | "sidebar.settings": "Settings", |
63 | "sidebar.addNewService": "Add new service", | ||
63 | "services.welcome": "Welcome to Franz", | 64 | "services.welcome": "Welcome to Franz", |
64 | "services.getStarted": "Get started", | 65 | "services.getStarted": "Get started", |
65 | "settings.account.headline": "Account", | 66 | "settings.account.headline": "Account", |
diff --git a/src/i18n/locales/es-ES.json b/src/i18n/locales/es-ES.json new file mode 100644 index 000000000..f71b07b2d --- /dev/null +++ b/src/i18n/locales/es-ES.json | |||
@@ -0,0 +1,168 @@ | |||
1 | { | ||
2 | "global.api.unhealthy": "No se pudo conectar con los servicios online de Franz", | ||
3 | "global.notConnectedToTheInternet": "No estás conectado a internet.", | ||
4 | "welcome.signupButton": "Crea una cuenta gratuita", | ||
5 | "welcome.loginButton": "Accede a tu cuenta", | ||
6 | "welcome.slogan": "MensajerÃa hecha para ti", | ||
7 | "login.headline": "Acceder", | ||
8 | "login.email.label": "Dirección de Email", | ||
9 | "login.password.label": "Contraseña", | ||
10 | "login.submit.label": "Acceder", | ||
11 | "login.invalidCredentials": "Email o contraseña no válidos", | ||
12 | "login.tokenExpired": "Tu sesión ha expirado. Por favor, accede de nuevo.", | ||
13 | "login.serverLogout": "Tu sesión ha expirado. Por favor, accede de nuevo.", | ||
14 | "login.link.signup": "Crea una cuenta gratuita", | ||
15 | "login.link.password": "Restablecer contraseña", | ||
16 | "password.headline": "Restablecer contraseña", | ||
17 | "password.email.label": "Dirección de Email", | ||
18 | "password.submit.label": "Enviar", | ||
19 | "password.noUser": "No hemos encontrado un usuario con ese email", | ||
20 | "password.successInfo": "Por favor, comprueba tu email", | ||
21 | "password.link.signup": "Crea una cuenta gratuita", | ||
22 | "password.link.login": "Accede a tu cuenta", | ||
23 | "signup.headline": "Crea tu cuenta", | ||
24 | "signup.firstname.label": "Nombre", | ||
25 | "signup.lastname.label": "Apellidos", | ||
26 | "signup.email.label": "Dirección de Email", | ||
27 | "signup.company.label": "Empresa", | ||
28 | "signup.password.label": "Contraseña", | ||
29 | "signup.submit.label": "Crear cuenta", | ||
30 | "signup.link.login": "¿Tienes ya una cuenta? Accede", | ||
31 | "signup.emailDuplicate": "Ya existe un usuario con esa dirección de email", | ||
32 | "signup.legal.info": "Al crear una cuenta de Franz aceptas los", | ||
33 | "signup.legal.terms": "Términos de servicio", | ||
34 | "signup.legal.privacy": "PolÃtica de privacidad", | ||
35 | "pricing.headline": "Ayuda a Franz", | ||
36 | "pricing.support.label": "Selecciona tu plan de ayuda", | ||
37 | "pricing.submit.label": "Quiero ayudar al desarrollo de Franz", | ||
38 | "pricing.link.skipPayment": "No quiero ayudar al desarrollo de Franz.", | ||
39 | "import.headline": "Importa tus servicios de Franz 4", | ||
40 | "import.notSupportedHeadline": "Servicios aún no disponibles en Franz 5", | ||
41 | "import.submit.label": "Importar servicios", | ||
42 | "import.skip.label": "Quiero añadir los servicios manualmente", | ||
43 | "invite.submit.label": "Enviar invitaciones", | ||
44 | "invite.headline.friends": "Invita a 3 de tus amigos o compañeros", | ||
45 | "invite.name.label": "Nombre", | ||
46 | "invite.email.label": "Dirección de Email", | ||
47 | "invite.skip.label": "Prefiero hacer esto luego", | ||
48 | "subscription.submit.label": "Quiero ayudar al desarrollo de Franz", | ||
49 | "subscription.paymentSessionError": "No se ha podido inicializar el formulario de pago", | ||
50 | "subscription.includedFeatures": "La cuenta de Franz Premium Supporter incluye", | ||
51 | "subscription.features.onpremise": "Añadir servicios in-situ/alojados como HipChat", | ||
52 | "subscription.features.customServices": "Servicios privados para ti y tu equipo", | ||
53 | "subscription.features.encryptedSync": "Sincronización de sesión encriptada", | ||
54 | "subscription.features.vpn": "Soporte para Proxy y VPN", | ||
55 | "subscription.features.ads": "¡Sin anuncios, para siempre!", | ||
56 | "subscription.features.comingSoon": "próximamente", | ||
57 | "infobar.servicesUpdated": "Tus servicios han sido actualizados.", | ||
58 | "infobar.updateAvailable": "Una nueva actualización para Franz está disponible.", | ||
59 | "infobar.buttonReloadServices": "Volver a cargar servicios", | ||
60 | "infobar.buttonInstallUpdate": "Reiniciar e instalar actualizaciones", | ||
61 | "infobar.requiredRequestsFailed": "No se han podido cargar los servicios y la información de usuario", | ||
62 | "sidebar.settings": "Ajustes", | ||
63 | "services.welcome": "Bienvenido a Franz", | ||
64 | "services.getStarted": "Comienza", | ||
65 | "settings.account.headline": "Mi cuenta", | ||
66 | "settings.account.headlineSubscription": "Tu suscripción", | ||
67 | "settings.account.headlineUpgrade": "Mejora tu cuenta y ayuda a Franz", | ||
68 | "settings.account.headlineInvoices": "Recibos", | ||
69 | "settings.account.manageSubscription.label": "Administra tu suscripción", | ||
70 | "settings.account.accountType.basic": "Cuenta Básica", | ||
71 | "settings.account.accountType.premium": "Cuenta Premium Supporter", | ||
72 | "settings.account.account.editButton": "Editar cuenta", | ||
73 | "settings.account.invoiceDownload": "Descargar", | ||
74 | "settings.account.userInfoRequestFailed": "No se ha podido cargar la información de usuario", | ||
75 | "settings.account.tryReloadUserInfoRequest": "TPrueba otra vez", | ||
76 | "settings.account.headlineProfile": "Actualizar perfil", | ||
77 | "settings.account.headlineAccount": "Información de la cuenta", | ||
78 | "settings.account.headlinePassword": "Cambiar contraseña", | ||
79 | "settings.account.successInfo": "Tus cambios han sido guardados", | ||
80 | "settings.account.buttonSave": "Actualizar perfil", | ||
81 | "settings.account.mining.thankyou": "Gracias por ayudar a Franz con tu procesador.", | ||
82 | "settings.account.mining.active": "Ahora mismo estás haciendo {hashes} cálculos por segundo.", | ||
83 | "settings.account.mining.moreInformation": "Obtén más información", | ||
84 | "settings.account.mining.cancel": "Cancelar minado", | ||
85 | "settings.navigation.availableServices": "Servicios disponibles", | ||
86 | "settings.navigation.yourServices": "Tus servicios", | ||
87 | "settings.navigation.account": "Cuenta", | ||
88 | "settings.navigation.settings": "Ajustes", | ||
89 | "settings.navigation.logout": "Desconectar", | ||
90 | "settings.recipes.headline": "Servicios disponibles", | ||
91 | "settings.recipes.mostPopular": "Más populares", | ||
92 | "settings.recipes.all": "Todos los servicios", | ||
93 | "settings.recipes.dev": "Desarrollo", | ||
94 | "settings.recipes.nothingFound": "Lo sentimos, no hemos encontrado nada.", | ||
95 | "settings.recipes.servicesSuccessfulAddedInfo": "Servicio añadido con éxito", | ||
96 | "settings.service.form.saveButton": "Guardar servicio", | ||
97 | "settings.service.form.deleteButton": "Eliminar servicio", | ||
98 | "settings.service.form.availableServices": "Servicios disponibles", | ||
99 | "settings.service.form.yourServices": "Tus servicios", | ||
100 | "settings.service.form.addServiceHeadline": "Añadir {name}", | ||
101 | "settings.service.form.editServiceHeadline": "Editar {name}", | ||
102 | "settings.service.form.tabHosted": "Alojados", | ||
103 | "settings.service.form.tabOnPremise": "Autoalojados âï¸", | ||
104 | "settings.service.form.customUrlValidationError": "No se ha podido validar el servidor personalizado {name}.", | ||
105 | "settings.service.form.customUrlPremiumInfo": "Para añadir servicios autoalojados necesitas una cuenta de Franz Premium Supporter.", | ||
106 | "settings.service.form.customUrlUpgradeAccount": "Mejora tu cuenta", | ||
107 | "settings.service.form.indirectMessageInfo": "Serás notificado sobre todos los nuevos mensajes en un canal, no solo @username, @channel, @here, ...", | ||
108 | "settings.service.error.headline": "Error", | ||
109 | "settings.service.error.goBack": "Volver a los servicios", | ||
110 | "settings.service.error.message": "No se ha podido cargar el servicio.", | ||
111 | "settings.services.tooltip.isDisabled": "Servicio deshabilitado", | ||
112 | "settings.services.tooltip.notificationsDisabled": "Notificaciones deshabilitadas", | ||
113 | "settings.services.headline": "Tus servicios", | ||
114 | "settings.services.noServicesAdded": "Aún no has añadido ningún servicio.", | ||
115 | "settings.services.discoverServices": "Descubrir servicios", | ||
116 | "settings.services.updatedInfo": "Tu cambios han sido guardados", | ||
117 | "settings.services.deletedInfo": "Se ha eliminado el servicio", | ||
118 | "settings.app.headline": "Ajustes", | ||
119 | "settings.app.headlineGeneral": "Generales", | ||
120 | "settings.app.headlineLanguage": "Idioma", | ||
121 | "settings.app.headlineUpdates": "Actualizaciones", | ||
122 | "settings.app.buttonSearchForUpdate": "Buscar actualizaciones", | ||
123 | "settings.app.buttonInstallUpdate": "Reiniciar e instalar actualizaciones", | ||
124 | "settings.app.updateStatusSearching": "Buscando actualizaciones", | ||
125 | "settings.app.updateStatusAvailable": "Actualización disponible, descargando...", | ||
126 | "settings.app.updateStatusUpToDate": "Estás utilizando la última versión de Franz", | ||
127 | "settings.app.form.autoLaunchOnStart": "Iniciar Franz al encender", | ||
128 | "settings.app.form.autoLaunchInBackground": "Abrir en segundo plano", | ||
129 | "settings.app.form.enableSystemTray": "Mostrar Franz en la barra de tareas", | ||
130 | "settings.app.form.minimizeToSystemTray": "Minimizar Franz a la barra de tareas", | ||
131 | "settings.app.form.runInBackground": "Mantener Franz abierto en segundo plano al cerrar la ventana", | ||
132 | "settings.app.form.language": "Idioma", | ||
133 | "settings.app.form.beta": "Incluir versiones beta", | ||
134 | "settings.app.currentVersion": "Versión actual:", | ||
135 | "settings.service.form.name": "Nombre", | ||
136 | "settings.service.form.enableService": "Habilitar servicio", | ||
137 | "settings.service.form.enableNotification": "Habilitar notificaciones", | ||
138 | "settings.service.form.team": "Equipo", | ||
139 | "settings.service.form.customUrl": "Servidor personalizado", | ||
140 | "settings.service.form.indirectMessages": "Mostrar señal para todos los mensajes nuevos", | ||
141 | "settings.user.form.firstname": "Nombre", | ||
142 | "settings.user.form.lastname": "Apellidos", | ||
143 | "settings.user.form.email": "Email", | ||
144 | "settings.user.form.currentPassword": "Contraseña actual", | ||
145 | "settings.user.form.newPassword": "Nueva contraseña", | ||
146 | "settings.user.form.accountType.label": "Tipo de cuenta", | ||
147 | "settings.user.form.accountType.individual": "Individual", | ||
148 | "settings.user.form.accountType.non-profit": "Sin ánimo de lucro", | ||
149 | "settings.user.form.accountType.company": "Empresa", | ||
150 | "subscription.type.free": "gratis", | ||
151 | "subscription.type.month": "mensual", | ||
152 | "subscription.type.year": "anual", | ||
153 | "subscription.type.mining": "Ayuda a Franz con tu procesador", | ||
154 | "subscription.mining.headline": "¿Cómo funciona?", | ||
155 | "subscription.mining.experimental": "experimental", | ||
156 | "subscription.mining.line1": "Al habilitar \"Ayuda a Franz con tu procesador\", Franz utilizará entre un 20-50% de tu CPU para minar la criptomoneda Monero, lo que equivale a aproximadamente 5$ anuales.", | ||
157 | "subscription.mining.line2": "Adaptaremos el uso de CPU basándonos en tu carga de trabajo para no vaciar tu baterÃa ni realentizar tu ordenador.", | ||
158 | "subscription.mining.line3": "Siempre que el minero esté activo, tendrás acceso ilimitado a todas las ventajas de la cuenta Franz Premium Supporter.", | ||
159 | "subscription.mining.moreInformation": "Obtén más información sobre este plan.", | ||
160 | "subscriptionPopup.buttonCancel": "Cancelar", | ||
161 | "subscriptionPopup.buttonDone": "Hecho", | ||
162 | "tabs.item.reload": "Recargar", | ||
163 | "tabs.item.edit": "Editar", | ||
164 | "tabs.item.disableNotifications": "Desactivar notificaciones", | ||
165 | "tabs.item.enableNotification": "Activar notificaciones", | ||
166 | "tabs.item.disableService": "Deshabilitar servicio", | ||
167 | "tabs.item.deleteService": "Eliminar servicio" | ||
168 | } | ||
diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 84cf54492..2863f47e4 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json | |||
@@ -60,6 +60,7 @@ | |||
60 | "infobar.buttonInstallUpdate": "Redémarrer et installer la mise à jour", | 60 | "infobar.buttonInstallUpdate": "Redémarrer et installer la mise à jour", |
61 | "infobar.requiredRequestsFailed": "Impossible de charger les services et les informations de l'utilisateur", | 61 | "infobar.requiredRequestsFailed": "Impossible de charger les services et les informations de l'utilisateur", |
62 | "sidebar.settings": "Paramètres", | 62 | "sidebar.settings": "Paramètres", |
63 | "sidebar.addNewService": "!!!Add new service", | ||
63 | "services.welcome": "Bienvenue sur Franz", | 64 | "services.welcome": "Bienvenue sur Franz", |
64 | "services.getStarted": "Commencer", | 65 | "services.getStarted": "Commencer", |
65 | "settings.account.headline": "Compte", | 66 | "settings.account.headline": "Compte", |
diff --git a/src/i18n/locales/it.json b/src/i18n/locales/it.json new file mode 100644 index 000000000..dd87599bb --- /dev/null +++ b/src/i18n/locales/it.json | |||
@@ -0,0 +1,168 @@ | |||
1 | { | ||
2 | "global.api.unhealthy": "Impossibile connettersi ai servizi online di Franz", | ||
3 | "global.notConnectedToTheInternet": "Non sei connesso ad internet.", | ||
4 | "welcome.signupButton": "Iscriviti gratis", | ||
5 | "welcome.loginButton": "Accedi", | ||
6 | "welcome.slogan": "Messagistica che lavora per te", | ||
7 | "login.headline": "Accedi", | ||
8 | "login.email.label": "Indirizzo email", | ||
9 | "login.password.label": "Password", | ||
10 | "login.submit.label": "Accedi", | ||
11 | "login.invalidCredentials": "Email o password non validi", | ||
12 | "login.tokenExpired": "La tua sessione è scaduta, accedi di nuovo per favore.", | ||
13 | "login.serverLogout": "La tua sessione è scaduta, accedi di nuovo per favore.", | ||
14 | "login.link.signup": "Iscriviti gratis", | ||
15 | "login.link.password": "Reimposta password", | ||
16 | "password.headline": "Reimposta password", | ||
17 | "password.email.label": "Indirizzo email", | ||
18 | "password.submit.label": "Invia", | ||
19 | "password.noUser": "Non è stato trovato nessun utente con questa email", | ||
20 | "password.successInfo": "Per favore controlla la tua email", | ||
21 | "password.link.signup": "Iscriviti gratis", | ||
22 | "password.link.login": "Accedi", | ||
23 | "signup.headline": "Accedi", | ||
24 | "signup.firstname.label": "Nome", | ||
25 | "signup.lastname.label": "Cognome", | ||
26 | "signup.email.label": "Indirizzo email", | ||
27 | "signup.company.label": "Azienda", | ||
28 | "signup.password.label": "Password", | ||
29 | "signup.submit.label": "Registrati", | ||
30 | "signup.link.login": "Hai già fatto l'iscrizione? Accedi", | ||
31 | "signup.emailDuplicate": "Esiste già un utente con questo indirizzo email", | ||
32 | "signup.legal.info": "Iscrivendoti a Franz accetti", | ||
33 | "signup.legal.terms": "Termini di servizio", | ||
34 | "signup.legal.privacy": "Informativa sulla Privacy", | ||
35 | "pricing.headline": "Supporta Franz", | ||
36 | "pricing.support.label": "Seleziona il tuo piano di sostegno", | ||
37 | "pricing.submit.label": "Voglio sostenere lo sviluppo di Franz", | ||
38 | "pricing.link.skipPayment": "Non voglio sostenere lo sviluppo Franz.", | ||
39 | "import.headline": "Importa i tuoi servizi di Franz 4", | ||
40 | "import.notSupportedHeadline": "Servzi non ancora supportati in Franz 5", | ||
41 | "import.submit.label": "Importa servizi", | ||
42 | "import.skip.label": "Voglio aggiungere i servizi a mano", | ||
43 | "invite.submit.label": "Manda inviti", | ||
44 | "invite.headline.friends": "Invita 3 dei tuoi amici o colleghi", | ||
45 | "invite.name.label": "Nome", | ||
46 | "invite.email.label": "Indirizzo email", | ||
47 | "invite.skip.label": "Voglio farlo dopo", | ||
48 | "subscription.submit.label": "Voglio sostenere lo sviluppo di Franz", | ||
49 | "subscription.paymentSessionError": "Impossibile inizializzare il modulo di pagamento", | ||
50 | "subscription.includedFeatures": "La sottoscrizione a pagamento Franz Premium Supporter include", | ||
51 | "subscription.features.onpremise": "Agiunge servizi on-premise/hosted come HipChat", | ||
52 | "subscription.features.customServices": "Servizi privati per te ed il tuo team", | ||
53 | "subscription.features.encryptedSync": "Sincronizzazione sessione crittografata", | ||
54 | "subscription.features.vpn": "Supporto di Proxy e VPN", | ||
55 | "subscription.features.ads": "Nessuna pubblicità ", | ||
56 | "subscription.features.comingSoon": "Presto disponibile", | ||
57 | "infobar.servicesUpdated": "I tuoi servizi sono stati aggiornati.", | ||
58 | "infobar.updateAvailable": "È disponibile un nuovo aggiornamento per Franz.", | ||
59 | "infobar.buttonReloadServices": "Ricarica i servizi", | ||
60 | "infobar.buttonInstallUpdate": "Riavvia e installa l'aggiornamento", | ||
61 | "infobar.requiredRequestsFailed": "Impossibile caricare i servizi e le informazioni dell'utente", | ||
62 | "sidebar.settings": "Impostazioni", | ||
63 | "services.welcome": "Benvenuto in Franz", | ||
64 | "services.getStarted": "Inizia", | ||
65 | "settings.account.headline": "Conto", | ||
66 | "settings.account.headlineSubscription": "La tua sottoscrizione", | ||
67 | "settings.account.headlineUpgrade": "Aggiorna il tuo conto e supporta Franz", | ||
68 | "settings.account.headlineInvoices": "Fatture", | ||
69 | "settings.account.manageSubscription.label": "Gestisci la tua sottoscrizione", | ||
70 | "settings.account.accountType.basic": "Conto Base", | ||
71 | "settings.account.accountType.premium": "Conto Premium Supporter", | ||
72 | "settings.account.account.editButton": "Modifica conto", | ||
73 | "settings.account.invoiceDownload": "Scarica", | ||
74 | "settings.account.userInfoRequestFailed": "Impossibile caricare le informazioni dell'utente", | ||
75 | "settings.account.tryReloadUserInfoRequest": "Prova ancora", | ||
76 | "settings.account.headlineProfile": "Aggiorna profilo", | ||
77 | "settings.account.headlineAccount": "Informazioni sul conto", | ||
78 | "settings.account.headlinePassword": "Cambia la password", | ||
79 | "settings.account.successInfo": "Le tue modifiche sono state salvate", | ||
80 | "settings.account.buttonSave": "Aggiorna profilo", | ||
81 | "settings.account.mining.thankyou": "Grazie per supportare Franz con la tua potenza di calcolo.", | ||
82 | "settings.account.mining.active": "Al momento stai eseguendo {hashes} calcoli al secondo.", | ||
83 | "settings.account.mining.moreInformation": "Ottieni piú informazioni", | ||
84 | "settings.account.mining.cancel": "Annulla mining", | ||
85 | "settings.navigation.availableServices": "Servizi disponibili", | ||
86 | "settings.navigation.yourServices": "I tuoi servizi", | ||
87 | "settings.navigation.account": "Conto", | ||
88 | "settings.navigation.settings": "Impostazioni", | ||
89 | "settings.navigation.logout": "Disconnetti", | ||
90 | "settings.recipes.headline": "Servizi disponibili", | ||
91 | "settings.recipes.mostPopular": "Piú popolari", | ||
92 | "settings.recipes.all": "Tutti i servizi", | ||
93 | "settings.recipes.dev": "Sviluppo", | ||
94 | "settings.recipes.nothingFound": "Mi dispiace, nessuno servizio corrisponde alla tua ricerca.", | ||
95 | "settings.recipes.servicesSuccessfulAddedInfo": "Servizio aggiunto con successo", | ||
96 | "settings.service.form.saveButton": "Salva servizio", | ||
97 | "settings.service.form.deleteButton": "Elimina servizio", | ||
98 | "settings.service.form.availableServices": "Servizi disponibili", | ||
99 | "settings.service.form.yourServices": "I tuoi servizi", | ||
100 | "settings.service.form.addServiceHeadline": "Aggiungi {name}", | ||
101 | "settings.service.form.editServiceHeadline": "Modifica {name}", | ||
102 | "settings.service.form.tabHosted": "Hosted", | ||
103 | "settings.service.form.tabOnPremise": "Self hosted âï¸", | ||
104 | "settings.service.form.customUrlValidationError": "Impossibile validare il server personale {name}.", | ||
105 | "settings.service.form.customUrlPremiumInfo": "Per aggiungere servizi self hosted devi avere un conto Franz Premium Supporter.", | ||
106 | "settings.service.form.customUrlUpgradeAccount": "Aggiorna il tuo conto", | ||
107 | "settings.service.form.indirectMessageInfo": "Riceverai notifiche per tutti i nuovi messaggi in un canale, non solo @username, @channel, @here, ...", | ||
108 | "settings.service.error.headline": "Errore", | ||
109 | "settings.service.error.goBack": "Torna ai servizi", | ||
110 | "settings.service.error.message": "Impossibile caricare le specifiche del servizio.", | ||
111 | "settings.services.tooltip.isDisabled": "Il servizio è disabilitato", | ||
112 | "settings.services.tooltip.notificationsDisabled": "Le notifiche sono disabilitate", | ||
113 | "settings.services.headline": "I tuoi servizi", | ||
114 | "settings.services.noServicesAdded": "Non hai ancora aggiunto nessun servizio.", | ||
115 | "settings.services.discoverServices": "Trova servizi", | ||
116 | "settings.services.updatedInfo": "Le tue modifiche sono state salvate", | ||
117 | "settings.services.deletedInfo": "Il servizio è stato eliminato", | ||
118 | "settings.app.headline": "Impostazioni", | ||
119 | "settings.app.headlineGeneral": "Generale", | ||
120 | "settings.app.headlineLanguage": "Lingua", | ||
121 | "settings.app.headlineUpdates": "Aggiornamento", | ||
122 | "settings.app.buttonSearchForUpdate": "Controlla aggiornamento versione", | ||
123 | "settings.app.buttonInstallUpdate": "Riavvia e installa l'aggiornamento", | ||
124 | "settings.app.updateStatusSearching": "Sto cercando l'aggiornamento", | ||
125 | "settings.app.updateStatusAvailable": "Aggiornamento disponibile, scarico...", | ||
126 | "settings.app.updateStatusUpToDate": "You are using the latest version of Franz", | ||
127 | "settings.app.form.autoLaunchOnStart": "Lancia Franz all'avvio", | ||
128 | "settings.app.form.autoLaunchInBackground": "Apri in background", | ||
129 | "settings.app.form.enableSystemTray": "Mostra Franz nella zona delle notifiche di sistema", | ||
130 | "settings.app.form.minimizeToSystemTray": "Minimizza Franz nella zona delle notifiche di sistema", | ||
131 | "settings.app.form.runInBackground": "Maniteni Franz attivo in background quando chiudi la finestra", | ||
132 | "settings.app.form.language": "Lingua", | ||
133 | "settings.app.form.beta": "Includi versioni beta", | ||
134 | "settings.app.currentVersion": "Versione corrente:", | ||
135 | "settings.service.form.name": "Nome", | ||
136 | "settings.service.form.enableService": "Abilita servizio", | ||
137 | "settings.service.form.enableNotification": "Abilita notifiche", | ||
138 | "settings.service.form.team": "Team", | ||
139 | "settings.service.form.customUrl": "Server personale", | ||
140 | "settings.service.form.indirectMessages": "Mostra il badge del messaggio per tutti i nuovi messaggi", | ||
141 | "settings.user.form.firstname": "Nome", | ||
142 | "settings.user.form.lastname": "Cognome", | ||
143 | "settings.user.form.email": "Email", | ||
144 | "settings.user.form.currentPassword": "Password corrente", | ||
145 | "settings.user.form.newPassword": "Nuova password", | ||
146 | "settings.user.form.accountType.label": "Tipo di conto", | ||
147 | "settings.user.form.accountType.individual": "Individuale", | ||
148 | "settings.user.form.accountType.non-profit": "Non-Profit", | ||
149 | "settings.user.form.accountType.company": "Azienda", | ||
150 | "subscription.type.free": "gratis", | ||
151 | "subscription.type.month": "mese", | ||
152 | "subscription.type.year": "anno", | ||
153 | "subscription.type.mining": "Supporta Franz con della potenza di calcolo", | ||
154 | "subscription.mining.headline": "Come funziona?", | ||
155 | "subscription.mining.experimental": "sperimentale", | ||
156 | "subscription.mining.line1": "Abilitando \"Supporta Franz con della potenza di calcolo\",Franz userà circa il 20-50% della tua CPU per fare il mining della criptovaluta Monero che equivale approssimativamente a 5$/anno.", | ||
157 | "subscription.mining.line2": "Adatteremo l'utilizzo della CPU in base all tue abitudini di lavoro per non scaricare la tua batteria e rallentare la tua macchina.", | ||
158 | "subscription.mining.line3": "Fino a che il mining è attivo, avrai accesso illimitato a tutte le funzionalità del conto Franz Premium Supporter.", | ||
159 | "subscription.mining.moreInformation": "Ottieni più informazioni su questo piano.", | ||
160 | "subscriptionPopup.buttonCancel": "Annulla", | ||
161 | "subscriptionPopup.buttonDone": "Fatto", | ||
162 | "tabs.item.reload": "Ricarica", | ||
163 | "tabs.item.edit": "Modifica", | ||
164 | "tabs.item.disableNotifications": "Disabilita le notifiche", | ||
165 | "tabs.item.enableNotification": "Abilita le notifiche", | ||
166 | "tabs.item.disableService": "Disabilita servizio", | ||
167 | "tabs.item.deleteService": "Elimina servizio" | ||
168 | } | ||
diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json index a283154c9..98b7cbb19 100644 --- a/src/i18n/locales/ja.json +++ b/src/i18n/locales/ja.json | |||
@@ -60,12 +60,13 @@ | |||
60 | "infobar.buttonInstallUpdate": "å†èµ·å‹•ã—ã¦æ›´æ–°ã‚’インストールã™ã‚‹", | 60 | "infobar.buttonInstallUpdate": "å†èµ·å‹•ã—ã¦æ›´æ–°ã‚’インストールã™ã‚‹", |
61 | "infobar.requiredRequestsFailed": "サービスã¨ãƒ¦ãƒ¼ã‚¶ãƒ¼æƒ…å ±ãŒèªã¿è¾¼ã‚ã¾ã›ã‚“", | 61 | "infobar.requiredRequestsFailed": "サービスã¨ãƒ¦ãƒ¼ã‚¶ãƒ¼æƒ…å ±ãŒèªã¿è¾¼ã‚ã¾ã›ã‚“", |
62 | "sidebar.settings": "è¨å®š", | 62 | "sidebar.settings": "è¨å®š", |
63 | "sidebar.addNewService": "!!!Add new service", | ||
63 | "services.welcome": "Franzã«ã‚ˆã†ã“ã", | 64 | "services.welcome": "Franzã«ã‚ˆã†ã“ã", |
64 | "services.getStarted": "ã¯ã˜ã‚ã‚‹", | 65 | "services.getStarted": "ã¯ã˜ã‚ã‚‹", |
65 | "settings.account.headline": "アカウント", | 66 | "settings.account.headline": "アカウント", |
66 | "settings.account.headlineSubscription": "サブスクリプション内容", | 67 | "settings.account.headlineSubscription": "サブスクリプション内容", |
67 | "settings.account.headlineUpgrade": "アカウントをアップグレードã—ã€Franzを支æ´ã™ã‚‹", | 68 | "settings.account.headlineUpgrade": "アカウントをアップグレードã—ã€Franzを支æ´ã™ã‚‹", |
68 | "settings.account.headlineInvoices": "Invoices", | 69 | "settings.account.headlineInvoices": "インボイス", |
69 | "settings.account.manageSubscription.label": "サブスクリプションã®ç®¡ç†", | 70 | "settings.account.manageSubscription.label": "サブスクリプションã®ç®¡ç†", |
70 | "settings.account.accountType.basic": "Basicアカウント", | 71 | "settings.account.accountType.basic": "Basicアカウント", |
71 | "settings.account.accountType.premium": "Premium Supporterアカウント", | 72 | "settings.account.accountType.premium": "Premium Supporterアカウント", |
@@ -126,6 +127,7 @@ | |||
126 | "settings.app.updateStatusUpToDate": "ãŠä½¿ã„ã®Franzã¯æœ€æ–°ã§ã™", | 127 | "settings.app.updateStatusUpToDate": "ãŠä½¿ã„ã®Franzã¯æœ€æ–°ã§ã™", |
127 | "settings.app.form.autoLaunchOnStart": "システム起動時ã«Franzã‚’é–‹ã", | 128 | "settings.app.form.autoLaunchOnStart": "システム起動時ã«Franzã‚’é–‹ã", |
128 | "settings.app.form.autoLaunchInBackground": "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ã§é–‹ã", | 129 | "settings.app.form.autoLaunchInBackground": "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ã§é–‹ã", |
130 | "settings.app.form.enableSystemTray": "Franzをシステムトレイã«è¡¨ç¤ºã™ã‚‹", | ||
129 | "settings.app.form.minimizeToSystemTray": "Franzをシステムトレイã«æœ€å°åŒ–ã™ã‚‹", | 131 | "settings.app.form.minimizeToSystemTray": "Franzをシステムトレイã«æœ€å°åŒ–ã™ã‚‹", |
130 | "settings.app.form.runInBackground": "ウインドウを閉ã˜ãŸéš›ã«Franzã‚’ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ã§å®Ÿè¡Œã•ã›ã¦ãŠã", | 132 | "settings.app.form.runInBackground": "ウインドウを閉ã˜ãŸéš›ã«Franzã‚’ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ã§å®Ÿè¡Œã•ã›ã¦ãŠã", |
131 | "settings.app.form.language": "言語", | 133 | "settings.app.form.language": "言語", |
@@ -150,7 +152,7 @@ | |||
150 | "subscription.type.month": "月間", | 152 | "subscription.type.month": "月間", |
151 | "subscription.type.year": "å¹´é–“", | 153 | "subscription.type.year": "å¹´é–“", |
152 | "subscription.type.mining": "PCã®å‡¦ç†èƒ½åŠ›ã‚’使ã£ã¦Franzを支æ´ã™ã‚‹", | 154 | "subscription.type.mining": "PCã®å‡¦ç†èƒ½åŠ›ã‚’使ã£ã¦Franzを支æ´ã™ã‚‹", |
153 | "subscription.mining.headline": "ã“ã‚Œã¯ã©ã®ã‚ˆã†ã«å‹•ä½œã—ã¦ã„ã‚‹ã‹", | 155 | "subscription.mining.headline": "ã“ã‚Œã¯ã©ã®ã‚ˆã†ãªä»•çµ„ã¿ã§ã™ã‹", |
154 | "subscription.mining.experimental": "実験的", | 156 | "subscription.mining.experimental": "実験的", |
155 | "subscription.mining.line1": "\"PCã®å‡¦ç†èƒ½åŠ›ã‚’使ã£ã¦Franzを支æ´ã™ã‚‹\"を有効ã«ã™ã‚‹ã“ã¨ã§ã€Franzã¯ãŠã‚ˆã20-50%ã®CPUパワーを暗å·é€šè²¨Moneroã®ãƒžã‚¤ãƒ‹ãƒ³ã‚°ã«ä½¿ç”¨ã—ã€ã“ã‚Œã¯ãŠã‚ˆãå¹´é–“ã§5ドル分ã«ã‚ãŸã‚Šã¾ã™ã€‚", | 157 | "subscription.mining.line1": "\"PCã®å‡¦ç†èƒ½åŠ›ã‚’使ã£ã¦Franzを支æ´ã™ã‚‹\"を有効ã«ã™ã‚‹ã“ã¨ã§ã€Franzã¯ãŠã‚ˆã20-50%ã®CPUパワーを暗å·é€šè²¨Moneroã®ãƒžã‚¤ãƒ‹ãƒ³ã‚°ã«ä½¿ç”¨ã—ã€ã“ã‚Œã¯ãŠã‚ˆãå¹´é–“ã§5ドル分ã«ã‚ãŸã‚Šã¾ã™ã€‚", |
156 | "subscription.mining.line2": "処ç†èƒ½åŠ›ã«åŸºã¥ã„ã¦CPUã®ä½¿ç”¨çŽ‡ã‚’é©å¿œã—ã¾ã™ã®ã§ãƒãƒƒãƒ†ãƒªãƒ¼ã‚’無駄ã«æ¶ˆè²»ã—ãŸã‚Šã€ã‚·ã‚¹ãƒ†ãƒ ã‚’é…ãã™ã‚‹ã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“。", | 158 | "subscription.mining.line2": "処ç†èƒ½åŠ›ã«åŸºã¥ã„ã¦CPUã®ä½¿ç”¨çŽ‡ã‚’é©å¿œã—ã¾ã™ã®ã§ãƒãƒƒãƒ†ãƒªãƒ¼ã‚’無駄ã«æ¶ˆè²»ã—ãŸã‚Šã€ã‚·ã‚¹ãƒ†ãƒ ã‚’é…ãã™ã‚‹ã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“。", |
diff --git a/src/i18n/locales/nb-NO.json b/src/i18n/locales/nb-NO.json new file mode 100644 index 000000000..976c54787 --- /dev/null +++ b/src/i18n/locales/nb-NO.json | |||
@@ -0,0 +1,169 @@ | |||
1 | { | ||
2 | "global.api.unhealthy": "Kan ikke koble til Franz' tjenester", | ||
3 | "global.notConnectedToTheInternet": "Du er ikke koblet til internett.", | ||
4 | "welcome.signupButton": "Opprett en gratis konto", | ||
5 | "welcome.loginButton": "Logg inn til din konto", | ||
6 | "welcome.slogan": "Teksting som funker for deg", | ||
7 | "login.headline": "Logg inn", | ||
8 | "login.email.label": "Email adresse", | ||
9 | "login.password.label": "Passord", | ||
10 | "login.submit.label": "Logg inn", | ||
11 | "login.invalidCredentials": "Ugyldig email eller passord", | ||
12 | "login.tokenExpired": "Din økt utløpte, vennligst logg inn igjen.", | ||
13 | "login.serverLogout": "Din økt utløpte, vennligst logg inn igjen.", | ||
14 | "login.link.signup": "Opprett en gratis konto", | ||
15 | "login.link.password": "Reset passord", | ||
16 | "password.headline": "Reset passord", | ||
17 | "password.email.label": "Email adresse", | ||
18 | "password.submit.label": "Send inn", | ||
19 | "password.noUser": "Ingen bruker med den emailen finnes", | ||
20 | "password.successInfo": "Vennligst sjekk din email", | ||
21 | "password.link.signup": "Opprett en gratis konto", | ||
22 | "password.link.login": "Logg inn til din konto", | ||
23 | "signup.headline": "Registrer deg", | ||
24 | "signup.firstname.label": "Fornavn", | ||
25 | "signup.lastname.label": "Etternavn", | ||
26 | "signup.email.label": "Email adresse", | ||
27 | "signup.company.label": "Firma", | ||
28 | "signup.password.label": "Passord", | ||
29 | "signup.submit.label": "Opprett konto", | ||
30 | "signup.link.login": "Har du allerede en konto? Logg inn", | ||
31 | "signup.emailDuplicate": "En konto med den epost adresse eksiterer allerede", | ||
32 | "signup.legal.info": "Ved å opprette en Franz konto aksepterer du", | ||
33 | "signup.legal.terms": "Vilkår for bruk", | ||
34 | "signup.legal.privacy": "Personvern", | ||
35 | "pricing.headline": "Støtt Franz", | ||
36 | "pricing.support.label": "Velg din støtteplan", | ||
37 | "pricing.submit.label": "Jeg vil støtte utviklingen av Franz", | ||
38 | "pricing.link.skipPayment": "Jeg vil ikke støtte utviklingen av Franz.", | ||
39 | "import.headline": "Importer dine Franz 4 tjenester", | ||
40 | "import.notSupportedHeadline": "Tjenester ikke enda støttet i Franz 5", | ||
41 | "import.submit.label": "Importer tjenester", | ||
42 | "import.skip.label": "Jeg vil legge til en tjeneste manuelt", | ||
43 | "invite.submit.label": "Send invitasjoner", | ||
44 | "invite.headline.friends": "Inviter 3 av dine venner eller kolleger", | ||
45 | "invite.name.label": "Navn", | ||
46 | "invite.email.label": "Email adresse", | ||
47 | "invite.skip.label": "Jeg vil gjøre dette senere", | ||
48 | "subscription.submit.label": "Jeg vil ikke støtte utviklingen av Franz", | ||
49 | "subscription.paymentSessionError": "Kunne ikke laste betalingsskjemaet", | ||
50 | "subscription.includedFeatures": "Betalte Franz Premium konto inkluderer", | ||
51 | "subscription.features.onpremise": "Legg til on-premise/hosted tjenester som HipChat", | ||
52 | "subscription.features.customServices": "Private tjenester for deg og ditt lag", | ||
53 | "subscription.features.encryptedSync": "Kryptert øktsynkronisering", | ||
54 | "subscription.features.vpn": "Proxy & VPN støtte", | ||
55 | "subscription.features.ads": "Ingen annonser, noensinne!", | ||
56 | "subscription.features.comingSoon": "Kommer snart", | ||
57 | "infobar.servicesUpdated": "Dine tjenester er oppdatert.", | ||
58 | "infobar.updateAvailable": "En ny oppdatering for Franz er tilgjengelig.", | ||
59 | "infobar.buttonReloadServices": "Oppdater tjenester", | ||
60 | "infobar.buttonInstallUpdate": "Restart & installer oppdatering", | ||
61 | "infobar.requiredRequestsFailed": "Kunne ikke laste tjenester og brukerinformasjon", | ||
62 | "sidebar.settings": "Innstillinger", | ||
63 | "sidebar.addNewService": "Legg til ny tjeneste", | ||
64 | "services.welcome": "Velkommen til Franz", | ||
65 | "services.getStarted": "Kom i gang", | ||
66 | "settings.account.headline": "Konto", | ||
67 | "settings.account.headlineSubscription": "Ditt abonnement", | ||
68 | "settings.account.headlineUpgrade": "Oppgrader din konto og støtt Franz", | ||
69 | "settings.account.headlineInvoices": "Fakturaer", | ||
70 | "settings.account.manageSubscription.label": "Administrer dine abonnement", | ||
71 | "settings.account.accountType.basic": "Enkel Konto", | ||
72 | "settings.account.accountType.premium": "Premium Konto", | ||
73 | "settings.account.account.editButton": "Rediger konto", | ||
74 | "settings.account.invoiceDownload": "Last ned", | ||
75 | "settings.account.userInfoRequestFailed": "Kunne ikke laste brukerinformasjon", | ||
76 | "settings.account.tryReloadUserInfoRequest": "Prøv igjen", | ||
77 | "settings.account.headlineProfile": "Oppdater profil", | ||
78 | "settings.account.headlineAccount": "Kontoinformasjon", | ||
79 | "settings.account.headlinePassword": "Endre passord", | ||
80 | "settings.account.successInfo": "Dine endringer er lagret", | ||
81 | "settings.account.buttonSave": "Oppdater profil", | ||
82 | "settings.account.mining.thankyou": "Takk for at du støtter Franz med din prosessorkraft.", | ||
83 | "settings.account.mining.active": "Du utfører nå {hashes} beregninger per sekund.", | ||
84 | "settings.account.mining.moreInformation": "FÃ¥ mer informasjon", | ||
85 | "settings.account.mining.cancel": "Avbryt mining", | ||
86 | "settings.navigation.availableServices": "Tilgjengelige tjenester", | ||
87 | "settings.navigation.yourServices": "Dine tjenester", | ||
88 | "settings.navigation.account": "Konto", | ||
89 | "settings.navigation.settings": "Innstillinger", | ||
90 | "settings.navigation.logout": "Logg ut", | ||
91 | "settings.recipes.headline": "Tilgjengelige tjenester", | ||
92 | "settings.recipes.mostPopular": "Mest populære", | ||
93 | "settings.recipes.all": "Alle tjenester", | ||
94 | "settings.recipes.dev": "Utvikling", | ||
95 | "settings.recipes.nothingFound": "Beklager, men ingen tjeneste samsvarer med søkeordet ditt.", | ||
96 | "settings.recipes.servicesSuccessfulAddedInfo": "Tjenesten ble lagt til", | ||
97 | "settings.service.form.saveButton": "Lagre tjeneste", | ||
98 | "settings.service.form.deleteButton": "Slett tjeneste", | ||
99 | "settings.service.form.availableServices": "Tilgjengelige tjenester", | ||
100 | "settings.service.form.yourServices": "Dine tjenester", | ||
101 | "settings.service.form.addServiceHeadline": "Legg til {name}", | ||
102 | "settings.service.form.editServiceHeadline": "Rediger {name}", | ||
103 | "settings.service.form.tabHosted": "Hosted", | ||
104 | "settings.service.form.tabOnPremise": "Selv hosted âï¸", | ||
105 | "settings.service.form.customUrlValidationError": "Kunne ikke validere egendefinert {name} server.", | ||
106 | "settings.service.form.customUrlPremiumInfo": "For å legge til selvhost-baserte tjenester trenger du en Franz Premium konto.", | ||
107 | "settings.service.form.customUrlUpgradeAccount": "Oppgrader din konto", | ||
108 | "settings.service.form.indirectMessageInfo": "Du vil bli varslet om alle nye meldinger i en kanal, ikke bare @brukernavn, @kanal, @here, ...", | ||
109 | "settings.service.error.headline": "Error", | ||
110 | "settings.service.error.goBack": "Tilbake til tjenester", | ||
111 | "settings.service.error.message": "Kunne ikke laste tjeneste oppskrift.", | ||
112 | "settings.services.tooltip.isDisabled": "Tjenesten er deaktivert", | ||
113 | "settings.services.tooltip.notificationsDisabled": "Varsler er deaktivert", | ||
114 | "settings.services.headline": "Dine tjenester", | ||
115 | "settings.services.noServicesAdded": "Du har ikke lagt til noen tjenester enda.", | ||
116 | "settings.services.discoverServices": "Oppdag tjenester", | ||
117 | "settings.services.updatedInfo": "Dine endringer er lagret", | ||
118 | "settings.services.deletedInfo": "Tjenester har blitt slettet", | ||
119 | "settings.app.headline": "Innstillinger", | ||
120 | "settings.app.headlineGeneral": "Genelert", | ||
121 | "settings.app.headlineLanguage": "Språk", | ||
122 | "settings.app.headlineUpdates": "Oppdateringer", | ||
123 | "settings.app.buttonSearchForUpdate": "Se etter oppdateringer", | ||
124 | "settings.app.buttonInstallUpdate": "Restart & installer oppdatering", | ||
125 | "settings.app.updateStatusSearching": "Søker etter en oppdatering", | ||
126 | "settings.app.updateStatusAvailable": "Oppdatering tilgjengelig, laster ned...", | ||
127 | "settings.app.updateStatusUpToDate": "Du bruker siste versjon av Franz", | ||
128 | "settings.app.form.autoLaunchOnStart": "Start Franz ved oppstart", | ||
129 | "settings.app.form.autoLaunchInBackground": "Ã…pne i bakgrunnen", | ||
130 | "settings.app.form.enableSystemTray": "Vis Franz i systemfeltet", | ||
131 | "settings.app.form.minimizeToSystemTray": "Minimer Franz til systemfeltet", | ||
132 | "settings.app.form.runInBackground": "Behold Franz i bakgrunnen når du lukker vinduet", | ||
133 | "settings.app.form.language": "Språk", | ||
134 | "settings.app.form.beta": "Inkluder beta versjoner", | ||
135 | "settings.app.currentVersion": "Gjeldende versjon:", | ||
136 | "settings.service.form.name": "Navn", | ||
137 | "settings.service.form.enableService": "Slå på tjeneste", | ||
138 | "settings.service.form.enableNotification": "Slå på varsler", | ||
139 | "settings.service.form.team": "Lag", | ||
140 | "settings.service.form.customUrl": "Egendefinert server", | ||
141 | "settings.service.form.indirectMessages": "Vis merke for alle nye meldinger", | ||
142 | "settings.user.form.firstname": "Fornavn", | ||
143 | "settings.user.form.lastname": "Etternavn", | ||
144 | "settings.user.form.email": "Email", | ||
145 | "settings.user.form.currentPassword": "Gjeldende passord", | ||
146 | "settings.user.form.newPassword": "Nytt passord", | ||
147 | "settings.user.form.accountType.label": "Konto type", | ||
148 | "settings.user.form.accountType.individual": "Individuell", | ||
149 | "settings.user.form.accountType.non-profit": "Non-Profit", | ||
150 | "settings.user.form.accountType.company": "Firma", | ||
151 | "subscription.type.free": "gratis", | ||
152 | "subscription.type.month": "måned", | ||
153 | "subscription.type.year": "Ã¥r", | ||
154 | "subscription.type.mining": "Støtt Franz med prosessorkraft", | ||
155 | "subscription.mining.headline": "Hvordan fungerer dette?", | ||
156 | "subscription.mining.experimental": "eksperimental", | ||
157 | "subscription.mining.line1": "Ved å aktivere \"Støtt Franz med prosessorkraft\" vil Franz bruke cirka 20-50% av prosessore din til å mine kryptovalutaen Monero, som vil tilsvare omtrent $5/år", | ||
158 | "subscription.mining.line2": "Vi vil tilpasse prosessor bruken basert på arbeidsadferd for å ikke tømme batteriet og senke hastigheten på maskinen din.", | ||
159 | "subscription.mining.line3": "SÃ¥ lenge du miner, har du ubegrenset tilgang til alle Franz Premium funksjoner.", | ||
160 | "subscription.mining.moreInformation": "FÃ¥ mer informasjon om denne planen.", | ||
161 | "subscriptionPopup.buttonCancel": "Kanseller", | ||
162 | "subscriptionPopup.buttonDone": "Ferdig", | ||
163 | "tabs.item.reload": "Reload", | ||
164 | "tabs.item.edit": "Rediger", | ||
165 | "tabs.item.disableNotifications": "Deaktiver varsler", | ||
166 | "tabs.item.enableNotification": "Aktiver varsler", | ||
167 | "tabs.item.disableService": "Deaktiver tjeneste", | ||
168 | "tabs.item.deleteService": "Slett tjeneste" | ||
169 | } | ||
diff --git a/src/i18n/locales/nl-BE.json b/src/i18n/locales/nl-BE.json index 40cc14c50..a19d51b2b 100644 --- a/src/i18n/locales/nl-BE.json +++ b/src/i18n/locales/nl-BE.json | |||
@@ -54,12 +54,13 @@ | |||
54 | "subscription.features.vpn": "Proxy & VPN ondersteuning", | 54 | "subscription.features.vpn": "Proxy & VPN ondersteuning", |
55 | "subscription.features.ads": "Geen reclame, nooit!", | 55 | "subscription.features.ads": "Geen reclame, nooit!", |
56 | "subscription.features.comingSoon": "komt binnenkort", | 56 | "subscription.features.comingSoon": "komt binnenkort", |
57 | "infobar.servicesUpdated": "Je services zijn geüpdated.", | 57 | "infobar.servicesUpdated": "Je services zijn geüpdatet.", |
58 | "infobar.updateAvailable": "Er is een nieuwe update van Franz beschikbaar.", | 58 | "infobar.updateAvailable": "Er is een nieuwe update van Franz beschikbaar.", |
59 | "infobar.buttonReloadServices": "Services herladen", | 59 | "infobar.buttonReloadServices": "Services herladen", |
60 | "infobar.buttonInstallUpdate": "Herstarten & update installeren", | 60 | "infobar.buttonInstallUpdate": "Herstarten & update installeren", |
61 | "infobar.requiredRequestsFailed": "Kon services en gebruikersinformatie niet laden", | 61 | "infobar.requiredRequestsFailed": "Kon services en gebruikersinformatie niet laden", |
62 | "sidebar.settings": "Instellingen", | 62 | "sidebar.settings": "Instellingen", |
63 | "sidebar.addNewService": "!!!Add new service", | ||
63 | "services.welcome": "Welkom bij Franz", | 64 | "services.welcome": "Welkom bij Franz", |
64 | "services.getStarted": "Begin", | 65 | "services.getStarted": "Begin", |
65 | "settings.account.headline": "Account", | 66 | "settings.account.headline": "Account", |
@@ -76,7 +77,7 @@ | |||
76 | "settings.account.headlineProfile": "Profiel aanpassen", | 77 | "settings.account.headlineProfile": "Profiel aanpassen", |
77 | "settings.account.headlineAccount": "Accountinformatie", | 78 | "settings.account.headlineAccount": "Accountinformatie", |
78 | "settings.account.headlinePassword": "Wachtwoord veranderen", | 79 | "settings.account.headlinePassword": "Wachtwoord veranderen", |
79 | "settings.account.successInfo": "Je wijzigingen werden bewaard", | 80 | "settings.account.successInfo": "Je wijzigingen zijn opgeslagen", |
80 | "settings.account.buttonSave": "Profiel aanpassen", | 81 | "settings.account.buttonSave": "Profiel aanpassen", |
81 | "settings.account.mining.thankyou": "Bedankt om Franz te steunen met je rekenkracht.", | 82 | "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.active": "Op dit moment maak je {hashes} berekeningen per seconde.", |
@@ -113,7 +114,7 @@ | |||
113 | "settings.services.headline": "Jouw services", | 114 | "settings.services.headline": "Jouw services", |
114 | "settings.services.noServicesAdded": "Je hebt nog geen services toegevoegd.", | 115 | "settings.services.noServicesAdded": "Je hebt nog geen services toegevoegd.", |
115 | "settings.services.discoverServices": "Services ontdekken", | 116 | "settings.services.discoverServices": "Services ontdekken", |
116 | "settings.services.updatedInfo": "Je veranderingen werden bewaard", | 117 | "settings.services.updatedInfo": "Je wijzigingen werden bewaard", |
117 | "settings.services.deletedInfo": "Service werd verwijderd", | 118 | "settings.services.deletedInfo": "Service werd verwijderd", |
118 | "settings.app.headline": "Instellingen", | 119 | "settings.app.headline": "Instellingen", |
119 | "settings.app.headlineGeneral": "Algemeen", | 120 | "settings.app.headlineGeneral": "Algemeen", |
diff --git a/src/i18n/locales/nl.json b/src/i18n/locales/nl.json index 159d1f328..aee1a52c8 100644 --- a/src/i18n/locales/nl.json +++ b/src/i18n/locales/nl.json | |||
@@ -10,7 +10,7 @@ | |||
10 | "login.submit.label": "Inloggen", | 10 | "login.submit.label": "Inloggen", |
11 | "login.invalidCredentials": "E-mailadres of wachtwoord ongeldig", | 11 | "login.invalidCredentials": "E-mailadres of wachtwoord ongeldig", |
12 | "login.tokenExpired": "De sessie is verlopen, log opnieuw in alsjeblieft.", | 12 | "login.tokenExpired": "De sessie is verlopen, log opnieuw in alsjeblieft.", |
13 | "login.serverLogout": "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", | 14 | "login.link.signup": "Maak een gratis account", |
15 | "login.link.password": "Wachtwoord vergeten", | 15 | "login.link.password": "Wachtwoord vergeten", |
16 | "password.headline": "Wachtwoord vergeten", | 16 | "password.headline": "Wachtwoord vergeten", |
@@ -60,6 +60,7 @@ | |||
60 | "infobar.buttonInstallUpdate": "Herstart & installeer update", | 60 | "infobar.buttonInstallUpdate": "Herstart & installeer update", |
61 | "infobar.requiredRequestsFailed": "Kon services en gebruikerinformatie niet laden", | 61 | "infobar.requiredRequestsFailed": "Kon services en gebruikerinformatie niet laden", |
62 | "sidebar.settings": "Instellingen", | 62 | "sidebar.settings": "Instellingen", |
63 | "sidebar.addNewService": "Voeg nieuwe service toe", | ||
63 | "services.welcome": "Welkom bij Franz", | 64 | "services.welcome": "Welkom bij Franz", |
64 | "services.getStarted": "Beginnen", | 65 | "services.getStarted": "Beginnen", |
65 | "settings.account.headline": "Account", | 66 | "settings.account.headline": "Account", |
@@ -157,7 +158,7 @@ | |||
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.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.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 | "subscription.mining.moreInformation": "Verkrijg meer informatie over dit plan.", |
160 | "subscriptionPopup.buttonCancel": "Cancel", | 161 | "subscriptionPopup.buttonCancel": "Annuleer", |
161 | "subscriptionPopup.buttonDone": "Klaar", | 162 | "subscriptionPopup.buttonDone": "Klaar", |
162 | "tabs.item.reload": "Herlaad", | 163 | "tabs.item.reload": "Herlaad", |
163 | "tabs.item.edit": "Bewerk", | 164 | "tabs.item.edit": "Bewerk", |
diff --git a/src/i18n/locales/pl.json b/src/i18n/locales/pl.json index 1a8e9ad54..a884ef319 100644 --- a/src/i18n/locales/pl.json +++ b/src/i18n/locales/pl.json | |||
@@ -60,6 +60,7 @@ | |||
60 | "infobar.buttonInstallUpdate": "Uruchom ponownie i zainstaluj aktualizacje", | 60 | "infobar.buttonInstallUpdate": "Uruchom ponownie i zainstaluj aktualizacje", |
61 | "infobar.requiredRequestsFailed": "Nie można wczytać usług i informacji o użytkowniku", | 61 | "infobar.requiredRequestsFailed": "Nie można wczytać usług i informacji o użytkowniku", |
62 | "sidebar.settings": "Ustawienia", | 62 | "sidebar.settings": "Ustawienia", |
63 | "sidebar.addNewService": "!!!Add new service", | ||
63 | "services.welcome": "Witaj w aplikcji Franz", | 64 | "services.welcome": "Witaj w aplikcji Franz", |
64 | "services.getStarted": "Zacznij", | 65 | "services.getStarted": "Zacznij", |
65 | "settings.account.headline": "Konto", | 66 | "settings.account.headline": "Konto", |
diff --git a/src/i18n/locales/pt-BR.json b/src/i18n/locales/pt-BR.json index 38f0836a7..8a139a4f5 100644 --- a/src/i18n/locales/pt-BR.json +++ b/src/i18n/locales/pt-BR.json | |||
@@ -59,7 +59,8 @@ | |||
59 | "infobar.buttonReloadServices": "Recarregar serviços", | 59 | "infobar.buttonReloadServices": "Recarregar serviços", |
60 | "infobar.buttonInstallUpdate": "Reiniciar & instalar atualização", | 60 | "infobar.buttonInstallUpdate": "Reiniciar & instalar atualização", |
61 | "infobar.requiredRequestsFailed": "Não foi possÃvel carregar serviços e informações do usuário", | 61 | "infobar.requiredRequestsFailed": "Não foi possÃvel carregar serviços e informações do usuário", |
62 | "sidebar.settings": "Configurações", | 62 | "sidebar.addNewService": "!!!Add new service", |
63 | "sidebar.settings": "Ajustes", | ||
63 | "services.welcome": "Bem-vindo ao Franz", | 64 | "services.welcome": "Bem-vindo ao Franz", |
64 | "services.getStarted": "Começar", | 65 | "services.getStarted": "Começar", |
65 | "settings.account.headline": "Conta", | 66 | "settings.account.headline": "Conta", |
@@ -85,7 +86,7 @@ | |||
85 | "settings.navigation.availableServices": "Serviços disponÃveis", | 86 | "settings.navigation.availableServices": "Serviços disponÃveis", |
86 | "settings.navigation.yourServices": "Seus serviços", | 87 | "settings.navigation.yourServices": "Seus serviços", |
87 | "settings.navigation.account": "Conta", | 88 | "settings.navigation.account": "Conta", |
88 | "settings.navigation.settings": "Configurações", | 89 | "settings.navigation.settings": "Ajustes", |
89 | "settings.navigation.logout": "Logout", | 90 | "settings.navigation.logout": "Logout", |
90 | "settings.recipes.headline": "Serviços disponÃveis", | 91 | "settings.recipes.headline": "Serviços disponÃveis", |
91 | "settings.recipes.mostPopular": "Mais populares", | 92 | "settings.recipes.mostPopular": "Mais populares", |
@@ -115,7 +116,7 @@ | |||
115 | "settings.services.discoverServices": "Descobrir serviços", | 116 | "settings.services.discoverServices": "Descobrir serviços", |
116 | "settings.services.updatedInfo": "Suas mudanças foram salvas", | 117 | "settings.services.updatedInfo": "Suas mudanças foram salvas", |
117 | "settings.services.deletedInfo": "Serviço apagado", | 118 | "settings.services.deletedInfo": "Serviço apagado", |
118 | "settings.app.headline": "Configurações", | 119 | "settings.app.headline": "Ajustes", |
119 | "settings.app.headlineGeneral": "Geral", | 120 | "settings.app.headlineGeneral": "Geral", |
120 | "settings.app.headlineLanguage": "Idioma", | 121 | "settings.app.headlineLanguage": "Idioma", |
121 | "settings.app.headlineUpdates": "Atualizações", | 122 | "settings.app.headlineUpdates": "Atualizações", |
@@ -126,6 +127,7 @@ | |||
126 | "settings.app.updateStatusUpToDate": "Você está usando a última versão do Franz", | 127 | "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.autoLaunchOnStart": "Abrir o Franz iniciar o sistema", |
128 | "settings.app.form.autoLaunchInBackground": "Abrir no fundo", | 129 | "settings.app.form.autoLaunchInBackground": "Abrir no fundo", |
130 | "settings.app.form.enableSystemTray": "Mostrar o Franz na bandeja do sistema", | ||
129 | "settings.app.form.minimizeToSystemTray": "Minimizar o Franz para a bandeja do sistema", | 131 | "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", | 132 | "settings.app.form.runInBackground": "Manter o Franz no fundo quando fechar a janela", |
131 | "settings.app.form.language": "Idioma", | 133 | "settings.app.form.language": "Idioma", |
diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index 44ced9e43..97b746097 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json | |||
@@ -60,6 +60,7 @@ | |||
60 | "infobar.buttonInstallUpdate": "ПерезапуÑтить и обновить", | 60 | "infobar.buttonInstallUpdate": "ПерезапуÑтить и обновить", |
61 | "infobar.requiredRequestsFailed": "Ðевозможно загрузить ÑервиÑÑ‹ и информацию пользователÑ", | 61 | "infobar.requiredRequestsFailed": "Ðевозможно загрузить ÑервиÑÑ‹ и информацию пользователÑ", |
62 | "sidebar.settings": "ÐаÑтройки", | 62 | "sidebar.settings": "ÐаÑтройки", |
63 | "sidebar.addNewService": "!!!Add new service", | ||
63 | "services.welcome": "Добро пожаловать во Franz", | 64 | "services.welcome": "Добро пожаловать во Franz", |
64 | "services.getStarted": "Ðачать работу", | 65 | "services.getStarted": "Ðачать работу", |
65 | "settings.account.headline": "Ðккаунт", | 66 | "settings.account.headline": "Ðккаунт", |
diff --git a/src/i18n/locales/ua.json b/src/i18n/locales/ua.json index 63135e52c..fcb99c4e4 100644 --- a/src/i18n/locales/ua.json +++ b/src/i18n/locales/ua.json | |||
@@ -60,6 +60,7 @@ | |||
60 | "infobar.buttonInstallUpdate": "Перезавантажити Ñ– вÑтановити оновленнÑ", | 60 | "infobar.buttonInstallUpdate": "Перезавантажити Ñ– вÑтановити оновленнÑ", |
61 | "infobar.requiredRequestsFailed": "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ ÑервіÑи та інформацію кориÑтувача", | 61 | "infobar.requiredRequestsFailed": "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ ÑервіÑи та інформацію кориÑтувача", |
62 | "sidebar.settings": "ÐалаштуваннÑ", | 62 | "sidebar.settings": "ÐалаштуваннÑ", |
63 | "sidebar.addNewService": "!!!Add new service", | ||
63 | "services.welcome": "ЛаÑкаво проÑимо в Franz", | 64 | "services.welcome": "ЛаÑкаво проÑимо в Franz", |
64 | "services.getStarted": "Почати", | 65 | "services.getStarted": "Почати", |
65 | "settings.account.headline": "Ðкаунт", | 66 | "settings.account.headline": "Ðкаунт", |
diff --git a/src/i18n/locales/zh-Hant.json b/src/i18n/locales/zh-Hant.json new file mode 100644 index 000000000..e52b9ca26 --- /dev/null +++ b/src/i18n/locales/zh-Hant.json | |||
@@ -0,0 +1,168 @@ | |||
1 | { | ||
2 | "global.api.unhealthy": "無法連接到Franz網路æœå‹™", | ||
3 | "global.notConnectedToTheInternet": "您未連上網際網路", | ||
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": "在建立帳戶åŒæ™‚,您åŒæ„:", | ||
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": "Send invites", | ||
44 | "invite.headline.friends": "邀請三個人", | ||
45 | "invite.name.label": "åå", | ||
46 | "invite.email.label": "é›»å郵件信箱", | ||
47 | "invite.skip.label": "我想晚點進行", | ||
48 | "subscription.submit.label": "我想å”助 Franz 的開發", | ||
49 | "subscription.paymentSessionError": "無法åˆå§‹åŒ–付費表單", | ||
50 | "subscription.includedFeatures": "Paid Franz Premium Supporter Account includes", | ||
51 | "subscription.features.onpremise": "Add on-premise/hosted services like HipChat", | ||
52 | "subscription.features.customServices": "Private services for you and your team", | ||
53 | "subscription.features.encryptedSync": "Encrypted session synchronization", | ||
54 | "subscription.features.vpn": "æ”¯æ´ Proxy & VPN", | ||
55 | "subscription.features.ads": "ä¸å†æœ‰ä»»ä½•å»£å‘Š", | ||
56 | "subscription.features.comingSoon": "敬請期待", | ||
57 | "infobar.servicesUpdated": "您的æœå‹™å·²æ›´æ–°", | ||
58 | "infobar.updateAvailable": "有新的更新å¯å®‰è£", | ||
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": "Invoices", | ||
69 | "settings.account.manageSubscription.label": "管ç†è¨‚é–±", | ||
70 | "settings.account.accountType.basic": "基本帳戶", | ||
71 | "settings.account.accountType.premium": "Premium Supporter Account", | ||
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": "æ„Ÿè¬æ‚¨è´ŠåŠ©é‹ç®—能力", | ||
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": "Self hosted âï¸", | ||
104 | "settings.service.form.customUrlValidationError": "Could not validate custom {name} server.", | ||
105 | "settings.service.form.customUrlPremiumInfo": "To add self hosted services, you need a Franz Premium Supporter Account.", | ||
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": "已經是最新版本了", | ||
127 | "settings.app.form.autoLaunchOnStart": "開機時啟動", | ||
128 | "settings.app.form.autoLaunchInBackground": "背景啟動", | ||
129 | "settings.app.form.enableSystemTray": "在系統匣上顯示", | ||
130 | "settings.app.form.minimizeToSystemTray": "最å°åŒ–至系統匣", | ||
131 | "settings.app.form.runInBackground": "關閉時ä¿æŒåœ¨èƒŒæ™¯é‹ä½œ", | ||
132 | "settings.app.form.language": "語言", | ||
133 | "settings.app.form.beta": "包å«é–‹ç™¼ä¸ç‰ˆæœ¬", | ||
134 | "settings.app.currentVersion": "當å‰ç‰ˆæœ¬ï¼š", | ||
135 | "settings.service.form.name": "Name", | ||
136 | "settings.service.form.enableService": "啟用æœå‹™", | ||
137 | "settings.service.form.enableNotification": "啟用通知", | ||
138 | "settings.service.form.team": "Team", | ||
139 | "settings.service.form.customUrl": "Custom server", | ||
140 | "settings.service.form.indirectMessages": "é‡å°å…¨éƒ¨è¨Šæ¯é¡¯ç¤ºé€šçŸ¥", | ||
141 | "settings.user.form.firstname": "åå", | ||
142 | "settings.user.form.lastname": "姓æ°", | ||
143 | "settings.user.form.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 é‹ç”¨æ‚¨CPUçš„20%至50%çš„é‹ç®—能力來挖門羅幣(一種開æºåŠ 密貨幣),æ¯å¹´ç´„莫å¯å¾—到5美元。", | ||
157 | "subscription.mining.line2": "我們會調整é‹ç®—強度,é¿å…消耗éŽå¤šé›»æ± é›»é‡åŠå½±éŸ¿æ•ˆèƒ½ã€‚", | ||
158 | "subscription.mining.line3": "當您å…許我們挖掘門羅幣之時,我們便å…è¨±æ‚¨ä½¿ç”¨å…¨éƒ¨çš„åŠ å€¼æœå‹™ã€‚", | ||
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/index.js b/src/index.js index 9ca059f48..a3aa14732 100644 --- a/src/index.js +++ b/src/index.js | |||
@@ -2,18 +2,14 @@ import { app, BrowserWindow, shell } from 'electron'; | |||
2 | import fs from 'fs-extra'; | 2 | import fs from 'fs-extra'; |
3 | import path from 'path'; | 3 | import path from 'path'; |
4 | 4 | ||
5 | /* eslint-disable */ | ||
6 | if (require('electron-squirrel-startup')) app.quit(); | ||
7 | |||
8 | import windowStateKeeper from 'electron-window-state'; | 5 | import windowStateKeeper from 'electron-window-state'; |
9 | 6 | ||
10 | import { isDevMode, isWindows } from './environment'; | 7 | import { isDevMode, isWindows } from './environment'; |
11 | import ipcApi from './electron/ipc-api'; | 8 | import ipcApi from './electron/ipc-api'; |
12 | import Tray from './lib/Tray'; | 9 | import Tray from './lib/Tray'; |
13 | import Settings from './electron/Settings'; | 10 | import Settings from './electron/Settings'; |
14 | import { appId } from './package.json'; | 11 | import { appId } from './package.json'; // eslint-disable-line import/no-unresolved |
15 | import './electron/exception'; | 12 | import './electron/exception'; |
16 | /* eslint-enable */ | ||
17 | 13 | ||
18 | // Keep a global reference of the window object, if you don't, the window will | 14 | // Keep a global reference of the window object, if you don't, the window will |
19 | // be closed automatically when the JavaScript object is garbage collected. | 15 | // be closed automatically when the JavaScript object is garbage collected. |
@@ -22,6 +18,7 @@ let willQuitApp = false; | |||
22 | 18 | ||
23 | // Ensure that the recipe directory exists | 19 | // Ensure that the recipe directory exists |
24 | fs.ensureDir(path.join(app.getPath('userData'), 'recipes')); | 20 | fs.ensureDir(path.join(app.getPath('userData'), 'recipes')); |
21 | fs.emptyDirSync(path.join(app.getPath('userData'), 'recipes', 'temp')); | ||
25 | 22 | ||
26 | // Set App ID for Windows | 23 | // Set App ID for Windows |
27 | if (isWindows) { | 24 | if (isWindows) { |
@@ -66,7 +63,7 @@ const createWindow = async () => { | |||
66 | }); | 63 | }); |
67 | 64 | ||
68 | // Initialize System Tray | 65 | // Initialize System Tray |
69 | const trayIcon = new Tray(mainWindow); | 66 | const trayIcon = new Tray(); |
70 | 67 | ||
71 | // Initialize ipcApi | 68 | // Initialize ipcApi |
72 | ipcApi({ mainWindow, settings, trayIcon }); | 69 | ipcApi({ mainWindow, settings, trayIcon }); |
@@ -114,6 +111,13 @@ const createWindow = async () => { | |||
114 | app.isMaximized = true; | 111 | app.isMaximized = true; |
115 | }); | 112 | }); |
116 | 113 | ||
114 | mainWindow.on('close', (e) => { | ||
115 | if (settings.get('minimizeToSystemTray')) { | ||
116 | e.preventDefault(); | ||
117 | mainWindow.minimize(); | ||
118 | } | ||
119 | }); | ||
120 | |||
117 | mainWindow.on('unmaximize', () => { | 121 | mainWindow.on('unmaximize', () => { |
118 | app.isMaximized = false; | 122 | app.isMaximized = false; |
119 | }); | 123 | }); |
diff --git a/src/lib/Menu.js b/src/lib/Menu.js index a6cde4d36..8f0a92c3d 100644 --- a/src/lib/Menu.js +++ b/src/lib/Menu.js | |||
@@ -1,9 +1,9 @@ | |||
1 | import { remote, shell } from 'electron'; | 1 | import { remote, shell } from 'electron'; |
2 | import { autorun, computed, observable, toJS } from 'mobx'; | 2 | import { autorun, computed, observable, toJS } from 'mobx'; |
3 | 3 | ||
4 | import { isDevMode, isMac } from '../environment'; | 4 | import { isMac } from '../environment'; |
5 | 5 | ||
6 | const { app, Menu } = remote; | 6 | const { app, Menu, dialog } = remote; |
7 | 7 | ||
8 | const template = [ | 8 | const template = [ |
9 | { | 9 | { |
@@ -84,6 +84,28 @@ const template = [ | |||
84 | label: 'Learn More', | 84 | label: 'Learn More', |
85 | click() { shell.openExternal('http://meetfranz.com'); }, | 85 | click() { shell.openExternal('http://meetfranz.com'); }, |
86 | }, | 86 | }, |
87 | { | ||
88 | label: 'Changelog', | ||
89 | click() { shell.openExternal('https://github.com/meetfranz/franz/blob/master/CHANGELOG.md'); }, | ||
90 | }, | ||
91 | { | ||
92 | type: 'separator', | ||
93 | }, | ||
94 | { | ||
95 | label: 'Support', | ||
96 | click() { shell.openExternal('http://meetfranz.com/support'); }, | ||
97 | }, | ||
98 | { | ||
99 | type: 'separator', | ||
100 | }, | ||
101 | { | ||
102 | label: 'Terms of Service', | ||
103 | click() { shell.openExternal('https://meetfranz.com/terms'); }, | ||
104 | }, | ||
105 | { | ||
106 | label: 'Privacy Statement', | ||
107 | click() { shell.openExternal('https://meetfranz.com/privacy'); }, | ||
108 | }, | ||
87 | ], | 109 | ], |
88 | }, | 110 | }, |
89 | ]; | 111 | ]; |
@@ -101,17 +123,15 @@ export default class FranzMenu { | |||
101 | _build() { | 123 | _build() { |
102 | const tpl = toJS(this.tpl); | 124 | const tpl = toJS(this.tpl); |
103 | 125 | ||
104 | if (isDevMode) { | 126 | tpl[1].submenu.push({ |
105 | tpl[1].submenu.push({ | 127 | role: 'toggledevtools', |
106 | role: 'toggledevtools', | 128 | }, { |
107 | }, { | 129 | label: 'Toggle Service Developer Tools', |
108 | label: 'Toggle Service Developer Tools', | 130 | accelerator: 'CmdOrCtrl+Shift+Alt+i', |
109 | accelerator: 'CmdOrCtrl+Shift+Alt+i', | 131 | click: () => { |
110 | click: () => { | 132 | this.actions.service.openDevToolsForActiveService(); |
111 | this.actions.service.openDevToolsForActiveService(); | 133 | }, |
112 | }, | 134 | }); |
113 | }); | ||
114 | } | ||
115 | 135 | ||
116 | tpl[1].submenu.unshift({ | 136 | tpl[1].submenu.unshift({ |
117 | label: 'Reload Service', | 137 | label: 'Reload Service', |
@@ -218,6 +238,18 @@ export default class FranzMenu { | |||
218 | role: 'front', | 238 | role: 'front', |
219 | }, | 239 | }, |
220 | ]; | 240 | ]; |
241 | } else { | ||
242 | tpl[4].submenu.unshift({ | ||
243 | role: 'about', | ||
244 | click: () => { | ||
245 | dialog.showMessageBox({ | ||
246 | type: 'info', | ||
247 | title: 'Franz', | ||
248 | message: 'Franz', | ||
249 | detail: `Version: ${remote.app.getVersion()}\nRelease: ${process.versions.electron} / ${process.platform} / ${process.arch}`, | ||
250 | }); | ||
251 | }, | ||
252 | }); | ||
221 | } | 253 | } |
222 | 254 | ||
223 | const serviceTpl = this.serviceTpl; | 255 | const serviceTpl = this.serviceTpl; |
diff --git a/src/lib/Tray.js b/src/lib/Tray.js index 67150971e..2efe71a71 100644 --- a/src/lib/Tray.js +++ b/src/lib/Tray.js | |||
@@ -6,12 +6,9 @@ const INDICATOR_TRAY_PLAIN = 'tray'; | |||
6 | const INDICATOR_TRAY_UNREAD = 'tray-unread'; | 6 | const INDICATOR_TRAY_UNREAD = 'tray-unread'; |
7 | 7 | ||
8 | export default class TrayIcon { | 8 | export default class TrayIcon { |
9 | mainWindow = null; | ||
10 | trayIcon = null; | 9 | trayIcon = null; |
11 | 10 | indicator = 0; | |
12 | constructor(mainWindow) { | 11 | themeChangeSubscriberId = null; |
13 | this.mainWindow = mainWindow; | ||
14 | } | ||
15 | 12 | ||
16 | show() { | 13 | show() { |
17 | if (this.trayIcon) return; | 14 | if (this.trayIcon) return; |
@@ -21,7 +18,7 @@ export default class TrayIcon { | |||
21 | { | 18 | { |
22 | label: 'Show Franz', | 19 | label: 'Show Franz', |
23 | click() { | 20 | click() { |
24 | this.mainWindow.show(); | 21 | app.mainWindow.show(); |
25 | }, | 22 | }, |
26 | }, { | 23 | }, { |
27 | label: 'Quit Franz', | 24 | label: 'Quit Franz', |
@@ -35,30 +32,45 @@ export default class TrayIcon { | |||
35 | this.trayIcon.setContextMenu(trayMenu); | 32 | this.trayIcon.setContextMenu(trayMenu); |
36 | 33 | ||
37 | this.trayIcon.on('click', () => { | 34 | this.trayIcon.on('click', () => { |
38 | this.mainWindow.show(); | 35 | app.mainWindow.show(); |
39 | }); | 36 | }); |
37 | |||
38 | if (process.platform === 'darwin') { | ||
39 | this.themeChangeSubscriberId = systemPreferences.subscribeNotification('AppleInterfaceThemeChangedNotification', () => { | ||
40 | this._refreshIcon(); | ||
41 | }); | ||
42 | } | ||
40 | } | 43 | } |
41 | 44 | ||
42 | hide() { | 45 | hide() { |
43 | if (this.trayIcon) { | 46 | if (!this.trayIcon) return; |
44 | this.trayIcon.destroy(); | 47 | |
45 | this.trayIcon = null; | 48 | this.trayIcon.destroy(); |
49 | this.trayIcon = null; | ||
50 | |||
51 | if (process.platform === 'darwin' && this.themeChangeSubscriberId) { | ||
52 | systemPreferences.unsubscribeNotification(this.themeChangeSubscriberId); | ||
53 | this.themeChangeSubscriberId = null; | ||
46 | } | 54 | } |
47 | } | 55 | } |
48 | 56 | ||
49 | setIndicator(indicator) { | 57 | setIndicator(indicator) { |
58 | this.indicator = indicator; | ||
59 | this._refreshIcon(); | ||
60 | } | ||
61 | |||
62 | _refreshIcon() { | ||
50 | if (!this.trayIcon) return; | 63 | if (!this.trayIcon) return; |
51 | 64 | ||
52 | this.trayIcon.setImage(this._getAsset('tray', indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN)); | 65 | this.trayIcon.setImage(this._getAsset('tray', this.indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN)); |
53 | 66 | ||
54 | if (process.platform === 'darwin') { | 67 | if (process.platform === 'darwin') { |
55 | this.trayIcon.setPressedImage( | 68 | this.trayIcon.setPressedImage( |
56 | this._getAsset('tray', `${indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN}-active`), | 69 | this._getAsset('tray', `${this.indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN}-active`), |
57 | ); | 70 | ); |
58 | } | 71 | } |
59 | } | 72 | } |
60 | 73 | ||
61 | |||
62 | _getAsset(type, asset) { | 74 | _getAsset(type, asset) { |
63 | let platform = process.platform; | 75 | let platform = process.platform; |
64 | 76 | ||
diff --git a/src/models/Recipe.js b/src/models/Recipe.js index 43a3450b1..9971df77c 100644 --- a/src/models/Recipe.js +++ b/src/models/Recipe.js | |||
@@ -1,7 +1,8 @@ | |||
1 | import emailParser from 'address-rfc2822'; | ||
2 | |||
1 | export default class Recipe { | 3 | export default class Recipe { |
2 | id = ''; | 4 | id = ''; |
3 | name = ''; | 5 | name = ''; |
4 | author = ''; | ||
5 | description = ''; | 6 | description = ''; |
6 | version = '1.0'; | 7 | version = '1.0'; |
7 | path = ''; | 8 | path = ''; |
@@ -25,12 +26,13 @@ export default class Recipe { | |||
25 | } | 26 | } |
26 | 27 | ||
27 | if (!data.id) { | 28 | if (!data.id) { |
28 | throw Error('Recipe requires Id'); | 29 | // Franz 4 recipes do not have an Id |
30 | throw Error(`Recipe '${data.name}' requires Id`); | ||
29 | } | 31 | } |
30 | 32 | ||
31 | this.id = data.id || this.id; | 33 | this.id = data.id || this.id; |
32 | this.name = data.name || this.name; | 34 | this.name = data.name || this.name; |
33 | this.author = data.author || this.author; | 35 | this.rawAuthor = data.author || this.author; |
34 | this.description = data.description || this.description; | 36 | this.description = data.description || this.description; |
35 | this.version = data.version || this.version; | 37 | this.version = data.version || this.version; |
36 | this.path = data.path; | 38 | this.path = data.path; |
@@ -49,4 +51,15 @@ export default class Recipe { | |||
49 | 51 | ||
50 | this.message = data.config.message || this.message; | 52 | this.message = data.config.message || this.message; |
51 | } | 53 | } |
54 | |||
55 | get author() { | ||
56 | try { | ||
57 | const addresses = emailParser.parse(this.rawAuthor); | ||
58 | return addresses.map(a => ({ email: a.address, name: a.phrase })); | ||
59 | } catch (err) { | ||
60 | console.warn(`Not a valid author for ${this.name}`); | ||
61 | } | ||
62 | |||
63 | return []; | ||
64 | } | ||
52 | } | 65 | } |
diff --git a/src/models/Service.js b/src/models/Service.js index 7a0310ebc..484252e7c 100644 --- a/src/models/Service.js +++ b/src/models/Service.js | |||
@@ -58,7 +58,12 @@ export default class Service { | |||
58 | 58 | ||
59 | @computed get url() { | 59 | @computed get url() { |
60 | if (this.recipe.hasCustomUrl && this.customUrl) { | 60 | if (this.recipe.hasCustomUrl && this.customUrl) { |
61 | let url = normalizeUrl(this.customUrl); | 61 | let url; |
62 | try { | ||
63 | url = normalizeUrl(this.customUrl); | ||
64 | } catch (err) { | ||
65 | console.error(`Service (${this.recipe.name}): '${this.customUrl}' is not a valid Url.`); | ||
66 | } | ||
62 | 67 | ||
63 | if (typeof this.recipe.buildUrl === 'function') { | 68 | if (typeof this.recipe.buildUrl === 'function') { |
64 | url = this.recipe.buildUrl(url); | 69 | url = this.recipe.buildUrl(url); |
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js index 7dbef985d..d8ef66a92 100644 --- a/src/stores/AppStore.js +++ b/src/stores/AppStore.js | |||
@@ -2,19 +2,23 @@ import { remote, ipcRenderer, shell } from 'electron'; | |||
2 | import { action, observable } from 'mobx'; | 2 | import { action, observable } from 'mobx'; |
3 | import moment from 'moment'; | 3 | import moment from 'moment'; |
4 | import key from 'keymaster'; | 4 | import key from 'keymaster'; |
5 | import path from 'path'; | 5 | // import path from 'path'; |
6 | import idleTimer from '@paulcbetts/system-idle-time'; | 6 | import idleTimer from '@paulcbetts/system-idle-time'; |
7 | import AutoLaunch from 'auto-launch'; | ||
7 | 8 | ||
8 | import Store from './lib/Store'; | 9 | import Store from './lib/Store'; |
9 | import Request from './lib/Request'; | 10 | import Request from './lib/Request'; |
10 | import { CHECK_INTERVAL } from '../config'; | 11 | import { CHECK_INTERVAL } from '../config'; |
11 | import { isMac, isLinux } from '../environment'; | 12 | import { isMac } from '../environment'; |
12 | import locales from '../i18n/translations'; | 13 | import locales from '../i18n/translations'; |
13 | import { gaEvent } from '../lib/analytics'; | 14 | import { gaEvent } from '../lib/analytics'; |
14 | import Miner from '../lib/Miner'; | 15 | import Miner from '../lib/Miner'; |
15 | 16 | ||
16 | const { app, getCurrentWindow, powerMonitor } = remote; | 17 | const { app, powerMonitor } = remote; |
17 | const defaultLocale = 'en-US'; | 18 | const defaultLocale = 'en-US'; |
19 | const autoLauncher = new AutoLaunch({ | ||
20 | name: 'Franz', | ||
21 | }); | ||
18 | 22 | ||
19 | export default class AppStore extends Store { | 23 | export default class AppStore extends Store { |
20 | updateStatusTypes = { | 24 | updateStatusTypes = { |
@@ -41,7 +45,7 @@ export default class AppStore extends Store { | |||
41 | miner = null; | 45 | miner = null; |
42 | @observable minerHashrate = 0.0; | 46 | @observable minerHashrate = 0.0; |
43 | 47 | ||
44 | constructor(...args: any) { | 48 | constructor(...args) { |
45 | super(...args); | 49 | super(...args); |
46 | 50 | ||
47 | // Register action handlers | 51 | // Register action handlers |
@@ -112,24 +116,15 @@ export default class AppStore extends Store { | |||
112 | setTimeout(window.location.reload, 5000); | 116 | setTimeout(window.location.reload, 5000); |
113 | }); | 117 | }); |
114 | 118 | ||
115 | // Open Dev Tools (even in production mode) | ||
116 | key('⌘+ctrl+shift+alt+i, ctrl+shift+alt+i', () => { | ||
117 | getCurrentWindow().toggleDevTools(); | ||
118 | }); | ||
119 | |||
120 | key('⌘+ctrl+shift+alt+pageup, ctrl+shift+alt+pageup', () => { | ||
121 | this.actions.service.openDevToolsForActiveService(); | ||
122 | }); | ||
123 | |||
124 | // Set active the next service | 119 | // Set active the next service |
125 | key( | 120 | key( |
126 | '⌘+pagedown, ctrl+pagedown, ⌘+shift+tab, ctrl+shift+tab', () => { | 121 | '⌘+pagedown, ctrl+pagedown, ⌘+tab, ctrl+tab', () => { |
127 | this.actions.service.setActiveNext(); | 122 | this.actions.service.setActiveNext(); |
128 | }); | 123 | }); |
129 | 124 | ||
130 | // Set active the prev service | 125 | // Set active the prev service |
131 | key( | 126 | key( |
132 | '⌘+pageup, ctrl+pageup, ⌘+tab, ctrl+tab', () => { | 127 | '⌘+pageup, ctrl+pageup, ⌘+shift+tab, ctrl+shift+tab', () => { |
133 | this.actions.service.setActivePrev(); | 128 | this.actions.service.setActivePrev(); |
134 | }); | 129 | }); |
135 | 130 | ||
@@ -166,28 +161,17 @@ export default class AppStore extends Store { | |||
166 | ipcRenderer.send('updateAppIndicator', { indicator }); | 161 | ipcRenderer.send('updateAppIndicator', { indicator }); |
167 | } | 162 | } |
168 | 163 | ||
169 | @action _launchOnStartup({ enable, openInBackground }) { | 164 | @action _launchOnStartup({ enable }) { |
170 | this.autoLaunchOnStart = enable; | 165 | this.autoLaunchOnStart = enable; |
171 | 166 | ||
172 | let settings = { | 167 | try { |
173 | openAtLogin: enable, | 168 | if (enable) { |
174 | }; | 169 | autoLauncher.enable(); |
175 | 170 | } else { | |
176 | // For Windows | 171 | autoLauncher.disable(); |
177 | if (process.platform === 'win32') { | ||
178 | settings = Object.assign({ | ||
179 | openAsHidden: openInBackground, | ||
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 | } | 172 | } |
173 | } catch (err) { | ||
174 | console.warn(err); | ||
191 | } | 175 | } |
192 | 176 | ||
193 | gaEvent('App', enable ? 'enable autostart' : 'disable autostart'); | 177 | gaEvent('App', enable ? 'enable autostart' : 'disable autostart'); |
@@ -296,31 +280,19 @@ export default class AppStore extends Store { | |||
296 | } | 280 | } |
297 | 281 | ||
298 | async _autoStart() { | 282 | async _autoStart() { |
299 | if (!isLinux) { | 283 | this.autoLaunchOnStart = await this._checkAutoStart(); |
300 | this._checkAutoStart(); | ||
301 | |||
302 | // we need to wait until the settings request is resolved | ||
303 | await this.stores.settings.allSettingsRequest; | ||
304 | 284 | ||
305 | // We don't set autostart on first launch for macOS as disabling | 285 | // we need to wait until the settings request is resolved |
306 | // the option is currently broken | 286 | await this.stores.settings.allSettingsRequest; |
307 | // https://github.com/meetfranz/franz/issues/17 | ||
308 | // https://github.com/electron/electron/issues/10880 | ||
309 | if (process.platform === 'darwin') return; | ||
310 | 287 | ||
311 | if (!this.stores.settings.all.appStarts) { | 288 | if (!this.stores.settings.all.appStarts) { |
312 | this.actions.app.launchOnStartup({ | 289 | this.actions.app.launchOnStartup({ |
313 | enable: true, | 290 | enable: true, |
314 | }); | 291 | }); |
315 | } | ||
316 | } | 292 | } |
317 | } | 293 | } |
318 | 294 | ||
319 | _checkAutoStart() { | 295 | async _checkAutoStart() { |
320 | const loginItem = app.getLoginItemSettings({ | 296 | return autoLauncher.isEnabled() || false; |
321 | path: app.getPath('exe'), | ||
322 | }); | ||
323 | |||
324 | this.autoLaunchOnStart = loginItem.openAtLogin; | ||
325 | } | 297 | } |
326 | } | 298 | } |
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index 19db05494..1d895d532 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js | |||
@@ -41,6 +41,7 @@ export default class ServicesStore extends Store { | |||
41 | this.actions.service.openWindow.listen(this._openWindow.bind(this)); | 41 | this.actions.service.openWindow.listen(this._openWindow.bind(this)); |
42 | this.actions.service.filter.listen(this._filter.bind(this)); | 42 | this.actions.service.filter.listen(this._filter.bind(this)); |
43 | this.actions.service.resetFilter.listen(this._resetFilter.bind(this)); | 43 | this.actions.service.resetFilter.listen(this._resetFilter.bind(this)); |
44 | this.actions.service.resetStatus.listen(this._resetStatus.bind(this)); | ||
44 | this.actions.service.reload.listen(this._reload.bind(this)); | 45 | this.actions.service.reload.listen(this._reload.bind(this)); |
45 | this.actions.service.reloadActive.listen(this._reloadActive.bind(this)); | 46 | this.actions.service.reloadActive.listen(this._reloadActive.bind(this)); |
46 | this.actions.service.reloadAll.listen(this._reloadAll.bind(this)); | 47 | this.actions.service.reloadAll.listen(this._reloadAll.bind(this)); |
@@ -144,12 +145,12 @@ export default class ServicesStore extends Store { | |||
144 | serviceData.name = data.name; | 145 | serviceData.name = data.name; |
145 | } | 146 | } |
146 | 147 | ||
147 | if (data.team) { | 148 | if (data.team && !data.customURL) { |
148 | serviceData.team = data.team; | 149 | serviceData.team = data.team; |
149 | } | 150 | } |
150 | 151 | ||
151 | if (data.team) { | 152 | if (data.team && data.customURL) { |
152 | serviceData.customUrl = data.customURL; | 153 | serviceData.customUrl = data.team; |
153 | } | 154 | } |
154 | 155 | ||
155 | this.actions.service.createService({ | 156 | this.actions.service.createService({ |
@@ -157,8 +158,6 @@ export default class ServicesStore extends Store { | |||
157 | serviceData, | 158 | serviceData, |
158 | redirect: false, | 159 | redirect: false, |
159 | }); | 160 | }); |
160 | |||
161 | return 'hello world'; | ||
162 | } | 161 | } |
163 | 162 | ||
164 | @action async _updateService({ serviceId, serviceData, redirect = true }) { | 163 | @action async _updateService({ serviceId, serviceData, redirect = true }) { |
@@ -295,9 +294,12 @@ export default class ServicesStore extends Store { | |||
295 | } | 294 | } |
296 | 295 | ||
297 | if (service.isNotificationEnabled) { | 296 | if (service.isNotificationEnabled) { |
297 | const title = typeof args[0].title === 'string' ? args[0].title : service.name; | ||
298 | options.body = typeof options.body === 'string' ? options.body : ''; | ||
299 | |||
298 | this.actions.app.notify({ | 300 | this.actions.app.notify({ |
299 | notificationId: args[0].notificationId, | 301 | notificationId: args[0].notificationId, |
300 | title: args[0].title, | 302 | title, |
301 | options, | 303 | options, |
302 | serviceId, | 304 | serviceId, |
303 | }); | 305 | }); |
@@ -338,6 +340,10 @@ export default class ServicesStore extends Store { | |||
338 | this.filterNeedle = null; | 340 | this.filterNeedle = null; |
339 | } | 341 | } |
340 | 342 | ||
343 | @action _resetStatus() { | ||
344 | this.actionStatus = []; | ||
345 | } | ||
346 | |||
341 | @action _reload({ serviceId }) { | 347 | @action _reload({ serviceId }) { |
342 | const service = this.one(serviceId); | 348 | const service = this.one(serviceId); |
343 | service.resetMessageCount(); | 349 | service.resetMessageCount(); |
@@ -383,7 +389,7 @@ export default class ServicesStore extends Store { | |||
383 | data.forEach((s) => { | 389 | data.forEach((s) => { |
384 | const service = s; | 390 | const service = s; |
385 | 391 | ||
386 | service.order = this.one(s.id).order; | 392 | service.order = services[s.id]; |
387 | }); | 393 | }); |
388 | }); | 394 | }); |
389 | 395 | ||
diff --git a/src/webview/lib/RecipeWebview.js b/src/webview/lib/RecipeWebview.js index 1787f85e2..b8acc1258 100644 --- a/src/webview/lib/RecipeWebview.js +++ b/src/webview/lib/RecipeWebview.js | |||
@@ -64,6 +64,12 @@ class RecipeWebview { | |||
64 | }); | 64 | }); |
65 | } | 65 | } |
66 | 66 | ||
67 | onNotify(fn) { | ||
68 | if (typeof fn === 'function') { | ||
69 | window.Notification.onNotify = fn; | ||
70 | } | ||
71 | } | ||
72 | |||
67 | initialize(fn) { | 73 | initialize(fn) { |
68 | if (typeof fn === 'function') { | 74 | if (typeof fn === 'function') { |
69 | fn(); | 75 | fn(); |
diff --git a/src/webview/notifications.js b/src/webview/notifications.js index 97ce9d69b..4055b10de 100644 --- a/src/webview/notifications.js +++ b/src/webview/notifications.js | |||
@@ -1,45 +1,46 @@ | |||
1 | const { ipcRenderer } = require('electron'); | 1 | const { ipcRenderer } = require('electron'); |
2 | const uuidV1 = require('uuid/v1'); | 2 | const uuidV1 = require('uuid/v1'); |
3 | // const FranzNotificationStore = []; | ||
4 | 3 | ||
5 | class Notification { | 4 | class Notification { |
5 | static permission = 'granted'; | ||
6 | |||
6 | constructor(title = '', options = {}) { | 7 | constructor(title = '', options = {}) { |
7 | this.title = title; | 8 | this.title = title; |
8 | this.options = options; | 9 | this.options = options; |
9 | this.notificationId = uuidV1(); | 10 | this.notificationId = uuidV1(); |
10 | this.onclick = () => {}; | ||
11 | 11 | ||
12 | ipcRenderer.sendToHost('notification', { | 12 | ipcRenderer.sendToHost('notification', this.onNotify({ |
13 | notificationId: this.notificationId, | 13 | notificationId: this.notificationId, |
14 | title, | 14 | title, |
15 | options, | 15 | options, |
16 | }); | 16 | })); |
17 | 17 | ||
18 | ipcRenderer.on(`notification-onclick:${this.notificationId}`, () => { | 18 | ipcRenderer.once(`notification-onclick:${this.notificationId}`, () => { |
19 | this.onclick(); | 19 | this.onclick(); |
20 | }); | 20 | }); |
21 | } | 21 | } |
22 | } | ||
23 | 22 | ||
24 | Notification.permission = 'granted'; | 23 | static requestPermission(cb = null) { |
24 | if (!cb) { | ||
25 | return new Promise((resolve) => { | ||
26 | resolve(Notification.permission); | ||
27 | }); | ||
28 | } | ||
25 | 29 | ||
26 | Notification.requestPermission = (cb = null) => { | 30 | if (typeof (cb) === 'function') { |
27 | console.log(this); | 31 | return cb(Notification.permission); |
28 | if (!cb) { | 32 | } |
29 | return new Promise((resolve) => { | 33 | |
30 | resolve(Notification.permission); | 34 | return Notification.permission; |
31 | }); | ||
32 | } | 35 | } |
33 | 36 | ||
34 | if (typeof (cb) === 'function') { | 37 | onNotify(data) { |
35 | return cb(Notification.permission); | 38 | return data; |
36 | } | 39 | } |
37 | 40 | ||
38 | return Notification.permission; | 41 | onClick() {} |
39 | }; | ||
40 | 42 | ||
41 | Notification.close = () => { | 43 | close() {} |
42 | // no implementation yet | 44 | } |
43 | }; | ||
44 | 45 | ||
45 | window.Notification = Notification; | 46 | window.Notification = Notification; |
@@ -32,8 +32,8 @@ | |||
32 | underscore "^1.6.0" | 32 | underscore "^1.6.0" |
33 | 33 | ||
34 | "@paulcbetts/spellchecker@^4.0.5": | 34 | "@paulcbetts/spellchecker@^4.0.5": |
35 | version "4.0.5" | 35 | version "4.0.6" |
36 | resolved "https://registry.yarnpkg.com/@paulcbetts/spellchecker/-/spellchecker-4.0.5.tgz#4ea9bfb85faba53c094c0809a18986bf44265c5f" | 36 | resolved "https://registry.yarnpkg.com/@paulcbetts/spellchecker/-/spellchecker-4.0.6.tgz#79ef1f9c19c5a3156921ccaa9ffdc3efbbee47e3" |
37 | dependencies: | 37 | dependencies: |
38 | nan "^2.0.0" | 38 | nan "^2.0.0" |
39 | 39 | ||
@@ -80,6 +80,12 @@ acorn@^5.1.1: | |||
80 | version "5.1.2" | 80 | version "5.1.2" |
81 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7" | 81 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7" |
82 | 82 | ||
83 | address-rfc2822@^2.0.1: | ||
84 | version "2.0.1" | ||
85 | resolved "https://registry.yarnpkg.com/address-rfc2822/-/address-rfc2822-2.0.1.tgz#1a1bdb942b5e20e2c1ba5d5f396d5824ff7ae6ea" | ||
86 | dependencies: | ||
87 | email-addresses "^3.0.0" | ||
88 | |||
83 | after@0.8.2: | 89 | after@0.8.2: |
84 | version "0.8.2" | 90 | version "0.8.2" |
85 | resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" | 91 | resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" |
@@ -151,6 +157,10 @@ anymatch@^1.3.0: | |||
151 | micromatch "^2.1.5" | 157 | micromatch "^2.1.5" |
152 | normalize-path "^2.0.0" | 158 | normalize-path "^2.0.0" |
153 | 159 | ||
160 | applescript@^1.0.0: | ||
161 | version "1.0.0" | ||
162 | resolved "https://registry.yarnpkg.com/applescript/-/applescript-1.0.0.tgz#bb87af568cad034a4e48c4bdaf6067a3a2701317" | ||
163 | |||
154 | aproba@^1.0.3: | 164 | aproba@^1.0.3: |
155 | version "1.1.2" | 165 | version "1.1.2" |
156 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" | 166 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" |
@@ -319,6 +329,16 @@ asynckit@^0.4.0: | |||
319 | version "0.4.0" | 329 | version "0.4.0" |
320 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" | 330 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" |
321 | 331 | ||
332 | "auto-launch@https://github.com/meetfranz/node-auto-launch.git": | ||
333 | version "5.0.1" | ||
334 | resolved "https://github.com/meetfranz/node-auto-launch.git#b90a0470467eb84435e6554ae9db1e2c6db79e61" | ||
335 | dependencies: | ||
336 | applescript "^1.0.0" | ||
337 | mkdirp "^0.5.1" | ||
338 | path-is-absolute "^1.0.0" | ||
339 | untildify "^3.0.2" | ||
340 | winreg "1.2.2" | ||
341 | |||
322 | aws-sign2@~0.6.0: | 342 | aws-sign2@~0.6.0: |
323 | version "0.6.0" | 343 | version "0.6.0" |
324 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" | 344 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" |
@@ -1998,12 +2018,6 @@ electron-spellchecker@^1.2.0: | |||
1998 | rxjs-serial-subscription "^0.1.1" | 2018 | rxjs-serial-subscription "^0.1.1" |
1999 | spawn-rx "^2.0.7" | 2019 | spawn-rx "^2.0.7" |
2000 | 2020 | ||
2001 | electron-squirrel-startup@^1.0.0: | ||
2002 | version "1.0.0" | ||
2003 | resolved "https://registry.yarnpkg.com/electron-squirrel-startup/-/electron-squirrel-startup-1.0.0.tgz#19b4e55933fa0ef8f556784b9c660f772546a0b8" | ||
2004 | dependencies: | ||
2005 | debug "^2.2.0" | ||
2006 | |||
2007 | electron-to-chromium@^1.3.18: | 2021 | electron-to-chromium@^1.3.18: |
2008 | version "1.3.20" | 2022 | version "1.3.20" |
2009 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.20.tgz#2eedd5ccbae7ddc557f68ad1fce9c172e915e4e5" | 2023 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.20.tgz#2eedd5ccbae7ddc557f68ad1fce9c172e915e4e5" |
@@ -2041,6 +2055,10 @@ electron@^1.7.9: | |||
2041 | electron-download "^3.0.1" | 2055 | electron-download "^3.0.1" |
2042 | extract-zip "^1.0.3" | 2056 | extract-zip "^1.0.3" |
2043 | 2057 | ||
2058 | email-addresses@^3.0.0: | ||
2059 | version "3.0.1" | ||
2060 | resolved "https://registry.yarnpkg.com/email-addresses/-/email-addresses-3.0.1.tgz#c1fc20c189e7f96d4012d375db5feaccdd24391c" | ||
2061 | |||
2044 | emojis-list@^2.0.0: | 2062 | emojis-list@^2.0.0: |
2045 | version "2.1.0" | 2063 | version "2.1.0" |
2046 | resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" | 2064 | resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" |
@@ -5949,6 +5967,10 @@ universalify@^0.1.0: | |||
5949 | version "0.1.1" | 5967 | version "0.1.1" |
5950 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" | 5968 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" |
5951 | 5969 | ||
5970 | untildify@^3.0.2: | ||
5971 | version "3.0.2" | ||
5972 | resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.2.tgz#7f1f302055b3fea0f3e81dc78eb36766cb65e3f1" | ||
5973 | |||
5952 | unzip-response@^2.0.1: | 5974 | unzip-response@^2.0.1: |
5953 | version "2.0.1" | 5975 | version "2.0.1" |
5954 | resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" | 5976 | resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" |
@@ -6133,6 +6155,10 @@ window-size@^0.1.4: | |||
6133 | version "0.1.4" | 6155 | version "0.1.4" |
6134 | resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" | 6156 | resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" |
6135 | 6157 | ||
6158 | winreg@1.2.2: | ||
6159 | version "1.2.2" | ||
6160 | resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.2.tgz#8509afa3b71c5bbd110a6d7c6247ec67736c598f" | ||
6161 | |||
6136 | word-wrap@^1.0.3: | 6162 | word-wrap@^1.0.3: |
6137 | version "1.2.3" | 6163 | version "1.2.3" |
6138 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" | 6164 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" |