diff options
Diffstat (limited to 'src')
24 files changed, 897 insertions, 318 deletions
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index 3dba793b2..f1e70ce59 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js | |||
@@ -21,6 +21,8 @@ import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; | |||
21 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; | 21 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; |
22 | import { serviceLimitStore } from '../../../features/serviceLimit'; | 22 | import { serviceLimitStore } from '../../../features/serviceLimit'; |
23 | 23 | ||
24 | import { isMac } from '../../../environment'; | ||
25 | |||
24 | const messages = defineMessages({ | 26 | const messages = defineMessages({ |
25 | saveService: { | 27 | saveService: { |
26 | id: 'settings.service.form.saveButton', | 28 | id: 'settings.service.form.saveButton', |
@@ -401,14 +403,16 @@ export default @observer class EditServiceForm extends Component { | |||
401 | </div> | 403 | </div> |
402 | </div> | 404 | </div> |
403 | 405 | ||
404 | <PremiumFeatureContainer | 406 | {!isMac && ( |
405 | condition={!isSpellcheckerIncludedInCurrentPlan} | 407 | <PremiumFeatureContainer |
406 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} | 408 | condition={!isSpellcheckerIncludedInCurrentPlan} |
407 | > | 409 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} |
408 | <div className="settings__settings-group"> | 410 | > |
409 | <Select field={form.$('spellcheckerLanguage')} /> | 411 | <div className="settings__settings-group"> |
410 | </div> | 412 | <Select field={form.$('spellcheckerLanguage')} multiple /> |
411 | </PremiumFeatureContainer> | 413 | </div> |
414 | </PremiumFeatureContainer> | ||
415 | )} | ||
412 | 416 | ||
413 | {isProxyFeatureEnabled && ( | 417 | {isProxyFeatureEnabled && ( |
414 | <PremiumFeatureContainer | 418 | <PremiumFeatureContainer |
diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js index 78038e86a..826dbb176 100644 --- a/src/components/settings/services/ServicesDashboard.js +++ b/src/components/settings/services/ServicesDashboard.js | |||
@@ -7,6 +7,7 @@ import { defineMessages, intlShape } from 'react-intl'; | |||
7 | import SearchInput from '../../ui/SearchInput'; | 7 | import SearchInput from '../../ui/SearchInput'; |
8 | import Infobox from '../../ui/Infobox'; | 8 | import Infobox from '../../ui/Infobox'; |
9 | import Loader from '../../ui/Loader'; | 9 | import Loader from '../../ui/Loader'; |
10 | import FAB from '../../ui/FAB'; | ||
10 | import ServiceItem from './ServiceItem'; | 11 | import ServiceItem from './ServiceItem'; |
11 | import Appear from '../../ui/effects/Appear'; | 12 | import Appear from '../../ui/effects/Appear'; |
12 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; | 13 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; |
@@ -175,6 +176,12 @@ export default @observer class ServicesDashboard extends Component { | |||
175 | </tbody> | 176 | </tbody> |
176 | </table> | 177 | </table> |
177 | )} | 178 | )} |
179 | |||
180 | <FAB> | ||
181 | <Link to="/settings/recipes"> | ||
182 | + | ||
183 | </Link> | ||
184 | </FAB> | ||
178 | </div> | 185 | </div> |
179 | </div> | 186 | </div> |
180 | ); | 187 | ); |
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index 50358c36f..ba7cb7317 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js | |||
@@ -91,6 +91,10 @@ const messages = defineMessages({ | |||
91 | id: 'settings.app.translationHelp', | 91 | id: 'settings.app.translationHelp', |
92 | defaultMessage: '!!!Help us to translate Ferdi into your language.', | 92 | defaultMessage: '!!!Help us to translate Ferdi into your language.', |
93 | }, | 93 | }, |
94 | spellCheckerLanguageInfo: { | ||
95 | id: 'settings.app.spellCheckerLanguageInfo', | ||
96 | defaultMessage: '!!!Ferdi uses your Mac\'s build-in spellchecker to check for typos. If you want to change the languages the spellchecker checks for, you can do so in your Mac\'s System Preferences.', | ||
97 | }, | ||
94 | subheadlineCache: { | 98 | subheadlineCache: { |
95 | id: 'settings.app.subheadlineCache', | 99 | id: 'settings.app.subheadlineCache', |
96 | defaultMessage: '!!!Cache', | 100 | defaultMessage: '!!!Cache', |
@@ -518,8 +522,11 @@ export default @observer class EditSettingsForm extends Component { | |||
518 | <Toggle | 522 | <Toggle |
519 | field={form.$('enableSpellchecking')} | 523 | field={form.$('enableSpellchecking')} |
520 | /> | 524 | /> |
521 | {form.$('enableSpellchecking').value && ( | 525 | {form.$('enableSpellchecking').value && !isMac && ( |
522 | <Select field={form.$('spellcheckerLanguage')} /> | 526 | <Select field={form.$('spellcheckerLanguage')} multiple /> |
527 | )} | ||
528 | {form.$('enableSpellchecking').value && isMac && ( | ||
529 | <p>{intl.formatMessage(messages.spellCheckerLanguageInfo)}</p> | ||
523 | )} | 530 | )} |
524 | </Fragment> | 531 | </Fragment> |
525 | </PremiumFeatureContainer> | 532 | </PremiumFeatureContainer> |
diff --git a/src/components/ui/FAB.js b/src/components/ui/FAB.js new file mode 100644 index 000000000..9359a3c6c --- /dev/null +++ b/src/components/ui/FAB.js | |||
@@ -0,0 +1,72 @@ | |||
1 | /** | ||
2 | * Floating Action Button (FAB) | ||
3 | */ | ||
4 | import React, { Component } from 'react'; | ||
5 | import PropTypes from 'prop-types'; | ||
6 | import { observer, inject } from 'mobx-react'; | ||
7 | import classnames from 'classnames'; | ||
8 | |||
9 | export default @inject('stores') @observer class Button extends Component { | ||
10 | static propTypes = { | ||
11 | className: PropTypes.string, | ||
12 | disabled: PropTypes.bool, | ||
13 | onClick: PropTypes.func, | ||
14 | type: PropTypes.string, | ||
15 | htmlForm: PropTypes.string, | ||
16 | stores: PropTypes.shape({ | ||
17 | settings: PropTypes.shape({ | ||
18 | app: PropTypes.shape({ | ||
19 | accentColor: PropTypes.string.isRequired, | ||
20 | }).isRequired, | ||
21 | }).isRequired, | ||
22 | }).isRequired, | ||
23 | }; | ||
24 | |||
25 | static defaultProps = { | ||
26 | className: null, | ||
27 | disabled: false, | ||
28 | onClick: () => { }, | ||
29 | type: 'button', | ||
30 | htmlForm: '', | ||
31 | }; | ||
32 | |||
33 | element = null; | ||
34 | |||
35 | render() { | ||
36 | const { | ||
37 | className, | ||
38 | disabled, | ||
39 | onClick, | ||
40 | type, | ||
41 | children, | ||
42 | htmlForm, | ||
43 | } = this.props; | ||
44 | |||
45 | const buttonProps = { | ||
46 | className: classnames({ | ||
47 | ferdi__fab: true, | ||
48 | [`${className}`]: className, | ||
49 | }), | ||
50 | type, | ||
51 | }; | ||
52 | |||
53 | if (disabled) { | ||
54 | buttonProps.disabled = true; | ||
55 | } | ||
56 | |||
57 | if (onClick) { | ||
58 | buttonProps.onClick = onClick; | ||
59 | } | ||
60 | |||
61 | if (htmlForm) { | ||
62 | buttonProps.form = htmlForm; | ||
63 | } | ||
64 | |||
65 | return ( | ||
66 | // disabling rule as button has type defined in `buttonProps` | ||
67 | <button {...buttonProps} type="button"> | ||
68 | {children} | ||
69 | </button> | ||
70 | ); | ||
71 | } | ||
72 | } | ||
diff --git a/src/components/ui/Select.js b/src/components/ui/Select.js index da52243ca..b4511433c 100644 --- a/src/components/ui/Select.js +++ b/src/components/ui/Select.js | |||
@@ -10,22 +10,60 @@ export default @observer class Select extends Component { | |||
10 | className: PropTypes.string, | 10 | className: PropTypes.string, |
11 | showLabel: PropTypes.bool, | 11 | showLabel: PropTypes.bool, |
12 | disabled: PropTypes.bool, | 12 | disabled: PropTypes.bool, |
13 | multiple: PropTypes.bool, | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | static defaultProps = { | 16 | static defaultProps = { |
16 | className: null, | 17 | className: null, |
17 | showLabel: true, | 18 | showLabel: true, |
18 | disabled: false, | 19 | disabled: false, |
20 | multiple: false, | ||
19 | }; | 21 | }; |
20 | 22 | ||
23 | constructor(props) { | ||
24 | super(props); | ||
25 | |||
26 | this.element = React.createRef(); | ||
27 | } | ||
28 | |||
29 | multipleChange() { | ||
30 | const element = this.element.current; | ||
31 | |||
32 | const result = []; | ||
33 | const options = element && element.options; | ||
34 | |||
35 | for (const option of options) { | ||
36 | if (option.selected) { | ||
37 | result.push(option.value || option.text); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | const { field } = this.props; | ||
42 | field.value = result; | ||
43 | } | ||
44 | |||
21 | render() { | 45 | render() { |
22 | const { | 46 | const { |
23 | field, | 47 | field, |
24 | className, | 48 | className, |
25 | showLabel, | 49 | showLabel, |
26 | disabled, | 50 | disabled, |
51 | multiple, | ||
27 | } = this.props; | 52 | } = this.props; |
28 | 53 | ||
54 | let selected = field.value; | ||
55 | |||
56 | if (multiple) { | ||
57 | if (typeof field.value === 'string' && field.value.substr(0, 1) === '[') { | ||
58 | // Value is JSON encoded | ||
59 | selected = JSON.parse(field.value); | ||
60 | } else if (typeof field.value === 'object') { | ||
61 | selected = field.value; | ||
62 | } else { | ||
63 | selected = [field.value]; | ||
64 | } | ||
65 | } | ||
66 | |||
29 | return ( | 67 | return ( |
30 | <div | 68 | <div |
31 | className={classnames({ | 69 | className={classnames({ |
@@ -44,11 +82,13 @@ export default @observer class Select extends Component { | |||
44 | </label> | 82 | </label> |
45 | )} | 83 | )} |
46 | <select | 84 | <select |
47 | onChange={field.onChange} | 85 | onChange={multiple ? e => this.multipleChange(e) : field.onChange} |
48 | id={field.id} | 86 | id={field.id} |
49 | defaultValue={field.value} | 87 | defaultValue={selected} |
50 | className="franz-form__select" | 88 | className="franz-form__select" |
51 | disabled={field.disabled || disabled} | 89 | disabled={field.disabled || disabled} |
90 | multiple={multiple} | ||
91 | ref={this.element} | ||
52 | > | 92 | > |
53 | {field.options.map(type => ( | 93 | {field.options.map(type => ( |
54 | <option | 94 | <option |
diff --git a/src/config.js b/src/config.js index b8af16419..f9eecf375 100644 --- a/src/config.js +++ b/src/config.js | |||
@@ -98,7 +98,7 @@ export const DEFAULT_APP_SETTINGS = { | |||
98 | showMessageBadgeWhenMuted: true, | 98 | showMessageBadgeWhenMuted: true, |
99 | showDragArea: false, | 99 | showDragArea: false, |
100 | enableSpellchecking: true, | 100 | enableSpellchecking: true, |
101 | spellcheckerLanguage: 'en-us', | 101 | spellcheckerLanguage: '["en-US"]', |
102 | darkMode: process.platform === 'darwin' ? nativeTheme.shouldUseDarkColors : false, // We can't use refs from `./environment` at this time | 102 | darkMode: process.platform === 'darwin' ? nativeTheme.shouldUseDarkColors : false, // We can't use refs from `./environment` at this time |
103 | locale: '', | 103 | locale: '', |
104 | fallbackLocale: 'en-US', | 104 | fallbackLocale: 'en-US', |
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index 3dba3bc11..c6149fd9e 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js | |||
@@ -247,7 +247,7 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e | |||
247 | showMessageBadgeWhenMuted: settingsData.showMessageBadgeWhenMuted, | 247 | showMessageBadgeWhenMuted: settingsData.showMessageBadgeWhenMuted, |
248 | showDragArea: settingsData.showDragArea, | 248 | showDragArea: settingsData.showDragArea, |
249 | enableSpellchecking: settingsData.enableSpellchecking, | 249 | enableSpellchecking: settingsData.enableSpellchecking, |
250 | spellcheckerLanguage: settingsData.spellcheckerLanguage, | 250 | spellcheckerLanguage: JSON.stringify(settingsData.spellcheckerLanguage), |
251 | beta: settingsData.beta, // we need this info in the main process as well | 251 | beta: settingsData.beta, // we need this info in the main process as well |
252 | automaticUpdates: settingsData.automaticUpdates, // we need this info in the main process as well | 252 | automaticUpdates: settingsData.automaticUpdates, // we need this info in the main process as well |
253 | locale: settingsData.locale, // we need this info in the main process as well | 253 | locale: settingsData.locale, // we need this info in the main process as well |
diff --git a/src/electron/ipc-api/settings.js b/src/electron/ipc-api/settings.js index b651db306..6d48c54e3 100644 --- a/src/electron/ipc-api/settings.js +++ b/src/electron/ipc-api/settings.js | |||
@@ -2,9 +2,11 @@ import { ipcMain } from 'electron'; | |||
2 | 2 | ||
3 | export default (params) => { | 3 | export default (params) => { |
4 | ipcMain.on('getAppSettings', (event, type) => { | 4 | ipcMain.on('getAppSettings', (event, type) => { |
5 | const cleanData = JSON.parse(JSON.stringify(params.settings[type].all)); | ||
6 | |||
5 | params.mainWindow.webContents.send('appSettings', { | 7 | params.mainWindow.webContents.send('appSettings', { |
6 | type, | 8 | type, |
7 | data: params.settings[type].all, | 9 | data: cleanData, |
8 | }); | 10 | }); |
9 | }); | 11 | }); |
10 | 12 | ||
diff --git a/src/electron/webview-ime-focus.js b/src/electron/webview-ime-focus.js index 1213b518e..b41232b63 100644 --- a/src/electron/webview-ime-focus.js +++ b/src/electron/webview-ime-focus.js | |||
@@ -1,3 +1,4 @@ | |||
1 | const { remote } = require('electron'); | ||
1 | const { releaseDocumentFocus } = require('./webview-ime-focus-helpers'); | 2 | const { releaseDocumentFocus } = require('./webview-ime-focus-helpers'); |
2 | 3 | ||
3 | function giveWebviewDocumentFocus(element) { | 4 | function giveWebviewDocumentFocus(element) { |
@@ -9,7 +10,7 @@ function giveWebviewDocumentFocus(element) { | |||
9 | } | 10 | } |
10 | 11 | ||
11 | function elementIsUnfocusedWebview(element) { | 12 | function elementIsUnfocusedWebview(element) { |
12 | return element.tagName === 'WEBVIEW' && !element.getWebContents().isFocused(); | 13 | return element.tagName === 'WEBVIEW' && !remote.webContents.fromId(element.getWebContentsId()).isFocused(); |
13 | } | 14 | } |
14 | 15 | ||
15 | function webviewDidAutofocus(element) { | 16 | function webviewDidAutofocus(element) { |
diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index 244ceb521..ce78f34a3 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json | |||
@@ -285,104 +285,104 @@ | |||
285 | "defaultMessage": "!!!Locked", | 285 | "defaultMessage": "!!!Locked", |
286 | "end": { | 286 | "end": { |
287 | "column": 3, | 287 | "column": 3, |
288 | "line": 22 | 288 | "line": 23 |
289 | }, | 289 | }, |
290 | "file": "src/components/auth/Locked.js", | 290 | "file": "src/components/auth/Locked.js", |
291 | "id": "locked.headline", | 291 | "id": "locked.headline", |
292 | "start": { | 292 | "start": { |
293 | "column": 12, | 293 | "column": 12, |
294 | "line": 19 | 294 | "line": 20 |
295 | } | 295 | } |
296 | }, | 296 | }, |
297 | { | 297 | { |
298 | "defaultMessage": "!!!Ferdi is currently locked. Please unlock Ferdi with your password to see your messages.", | 298 | "defaultMessage": "!!!Ferdi is currently locked. Please unlock Ferdi with your password to see your messages.", |
299 | "end": { | 299 | "end": { |
300 | "column": 3, | 300 | "column": 3, |
301 | "line": 26 | 301 | "line": 27 |
302 | }, | 302 | }, |
303 | "file": "src/components/auth/Locked.js", | 303 | "file": "src/components/auth/Locked.js", |
304 | "id": "locked.info", | 304 | "id": "locked.info", |
305 | "start": { | 305 | "start": { |
306 | "column": 8, | 306 | "column": 8, |
307 | "line": 23 | 307 | "line": 24 |
308 | } | 308 | } |
309 | }, | 309 | }, |
310 | { | 310 | { |
311 | "defaultMessage": "!!!Unlock with Touch ID", | 311 | "defaultMessage": "!!!Unlock with Touch ID", |
312 | "end": { | 312 | "end": { |
313 | "column": 3, | 313 | "column": 3, |
314 | "line": 30 | 314 | "line": 31 |
315 | }, | 315 | }, |
316 | "file": "src/components/auth/Locked.js", | 316 | "file": "src/components/auth/Locked.js", |
317 | "id": "locked.touchId", | 317 | "id": "locked.touchId", |
318 | "start": { | 318 | "start": { |
319 | "column": 11, | 319 | "column": 11, |
320 | "line": 27 | 320 | "line": 28 |
321 | } | 321 | } |
322 | }, | 322 | }, |
323 | { | 323 | { |
324 | "defaultMessage": "!!!unlock via Touch ID", | 324 | "defaultMessage": "!!!unlock via Touch ID", |
325 | "end": { | 325 | "end": { |
326 | "column": 3, | 326 | "column": 3, |
327 | "line": 34 | 327 | "line": 35 |
328 | }, | 328 | }, |
329 | "file": "src/components/auth/Locked.js", | 329 | "file": "src/components/auth/Locked.js", |
330 | "id": "locked.touchIdPrompt", | 330 | "id": "locked.touchIdPrompt", |
331 | "start": { | 331 | "start": { |
332 | "column": 17, | 332 | "column": 17, |
333 | "line": 31 | 333 | "line": 32 |
334 | } | 334 | } |
335 | }, | 335 | }, |
336 | { | 336 | { |
337 | "defaultMessage": "!!!Password", | 337 | "defaultMessage": "!!!Password", |
338 | "end": { | 338 | "end": { |
339 | "column": 3, | 339 | "column": 3, |
340 | "line": 38 | 340 | "line": 39 |
341 | }, | 341 | }, |
342 | "file": "src/components/auth/Locked.js", | 342 | "file": "src/components/auth/Locked.js", |
343 | "id": "locked.password.label", | 343 | "id": "locked.password.label", |
344 | "start": { | 344 | "start": { |
345 | "column": 17, | 345 | "column": 17, |
346 | "line": 35 | 346 | "line": 36 |
347 | } | 347 | } |
348 | }, | 348 | }, |
349 | { | 349 | { |
350 | "defaultMessage": "!!!Unlock", | 350 | "defaultMessage": "!!!Unlock", |
351 | "end": { | 351 | "end": { |
352 | "column": 3, | 352 | "column": 3, |
353 | "line": 42 | 353 | "line": 43 |
354 | }, | 354 | }, |
355 | "file": "src/components/auth/Locked.js", | 355 | "file": "src/components/auth/Locked.js", |
356 | "id": "locked.submit.label", | 356 | "id": "locked.submit.label", |
357 | "start": { | 357 | "start": { |
358 | "column": 21, | 358 | "column": 21, |
359 | "line": 39 | 359 | "line": 40 |
360 | } | 360 | } |
361 | }, | 361 | }, |
362 | { | 362 | { |
363 | "defaultMessage": "!!!Unlock with Password", | 363 | "defaultMessage": "!!!Unlock with Password", |
364 | "end": { | 364 | "end": { |
365 | "column": 3, | 365 | "column": 3, |
366 | "line": 46 | 366 | "line": 47 |
367 | }, | 367 | }, |
368 | "file": "src/components/auth/Locked.js", | 368 | "file": "src/components/auth/Locked.js", |
369 | "id": "locked.unlockWithPassword", | 369 | "id": "locked.unlockWithPassword", |
370 | "start": { | 370 | "start": { |
371 | "column": 22, | 371 | "column": 22, |
372 | "line": 43 | 372 | "line": 44 |
373 | } | 373 | } |
374 | }, | 374 | }, |
375 | { | 375 | { |
376 | "defaultMessage": "!!!Password invalid", | 376 | "defaultMessage": "!!!Password invalid", |
377 | "end": { | 377 | "end": { |
378 | "column": 3, | 378 | "column": 3, |
379 | "line": 50 | 379 | "line": 51 |
380 | }, | 380 | }, |
381 | "file": "src/components/auth/Locked.js", | 381 | "file": "src/components/auth/Locked.js", |
382 | "id": "locked.invalidCredentials", | 382 | "id": "locked.invalidCredentials", |
383 | "start": { | 383 | "start": { |
384 | "column": 22, | 384 | "column": 22, |
385 | "line": 47 | 385 | "line": 48 |
386 | } | 386 | } |
387 | } | 387 | } |
388 | ], | 388 | ], |
@@ -2483,364 +2483,364 @@ | |||
2483 | "defaultMessage": "!!!Save service", | 2483 | "defaultMessage": "!!!Save service", |
2484 | "end": { | 2484 | "end": { |
2485 | "column": 3, | 2485 | "column": 3, |
2486 | "line": 28 | 2486 | "line": 30 |
2487 | }, | 2487 | }, |
2488 | "file": "src/components/settings/services/EditServiceForm.js", | 2488 | "file": "src/components/settings/services/EditServiceForm.js", |
2489 | "id": "settings.service.form.saveButton", | 2489 | "id": "settings.service.form.saveButton", |
2490 | "start": { | 2490 | "start": { |
2491 | "column": 15, | 2491 | "column": 15, |
2492 | "line": 25 | 2492 | "line": 27 |
2493 | } | 2493 | } |
2494 | }, | 2494 | }, |
2495 | { | 2495 | { |
2496 | "defaultMessage": "!!!Delete Service", | 2496 | "defaultMessage": "!!!Delete Service", |
2497 | "end": { | 2497 | "end": { |
2498 | "column": 3, | 2498 | "column": 3, |
2499 | "line": 32 | 2499 | "line": 34 |
2500 | }, | 2500 | }, |
2501 | "file": "src/components/settings/services/EditServiceForm.js", | 2501 | "file": "src/components/settings/services/EditServiceForm.js", |
2502 | "id": "settings.service.form.deleteButton", | 2502 | "id": "settings.service.form.deleteButton", |
2503 | "start": { | 2503 | "start": { |
2504 | "column": 17, | 2504 | "column": 17, |
2505 | "line": 29 | 2505 | "line": 31 |
2506 | } | 2506 | } |
2507 | }, | 2507 | }, |
2508 | { | 2508 | { |
2509 | "defaultMessage": "!!!Open darkmode.css", | 2509 | "defaultMessage": "!!!Open darkmode.css", |
2510 | "end": { | 2510 | "end": { |
2511 | "column": 3, | 2511 | "column": 3, |
2512 | "line": 36 | 2512 | "line": 38 |
2513 | }, | 2513 | }, |
2514 | "file": "src/components/settings/services/EditServiceForm.js", | 2514 | "file": "src/components/settings/services/EditServiceForm.js", |
2515 | "id": "settings.service.form.openDarkmodeCss", | 2515 | "id": "settings.service.form.openDarkmodeCss", |
2516 | "start": { | 2516 | "start": { |
2517 | "column": 19, | 2517 | "column": 19, |
2518 | "line": 33 | 2518 | "line": 35 |
2519 | } | 2519 | } |
2520 | }, | 2520 | }, |
2521 | { | 2521 | { |
2522 | "defaultMessage": "!!!Open user.css", | 2522 | "defaultMessage": "!!!Open user.css", |
2523 | "end": { | 2523 | "end": { |
2524 | "column": 3, | 2524 | "column": 3, |
2525 | "line": 40 | 2525 | "line": 42 |
2526 | }, | 2526 | }, |
2527 | "file": "src/components/settings/services/EditServiceForm.js", | 2527 | "file": "src/components/settings/services/EditServiceForm.js", |
2528 | "id": "settings.service.form.openUserCss", | 2528 | "id": "settings.service.form.openUserCss", |
2529 | "start": { | 2529 | "start": { |
2530 | "column": 15, | 2530 | "column": 15, |
2531 | "line": 37 | 2531 | "line": 39 |
2532 | } | 2532 | } |
2533 | }, | 2533 | }, |
2534 | { | 2534 | { |
2535 | "defaultMessage": "!!!Open user.js", | 2535 | "defaultMessage": "!!!Open user.js", |
2536 | "end": { | 2536 | "end": { |
2537 | "column": 3, | 2537 | "column": 3, |
2538 | "line": 44 | 2538 | "line": 46 |
2539 | }, | 2539 | }, |
2540 | "file": "src/components/settings/services/EditServiceForm.js", | 2540 | "file": "src/components/settings/services/EditServiceForm.js", |
2541 | "id": "settings.service.form.openUserJs", | 2541 | "id": "settings.service.form.openUserJs", |
2542 | "start": { | 2542 | "start": { |
2543 | "column": 14, | 2543 | "column": 14, |
2544 | "line": 41 | 2544 | "line": 43 |
2545 | } | 2545 | } |
2546 | }, | 2546 | }, |
2547 | { | 2547 | { |
2548 | "defaultMessage": "!!!Your user files will be inserted into the webpage so you can customize services in any way you like. User files are only stored locally and are not transferred to other computers using the same account.", | 2548 | "defaultMessage": "!!!Your user files will be inserted into the webpage so you can customize services in any way you like. User files are only stored locally and are not transferred to other computers using the same account.", |
2549 | "end": { | 2549 | "end": { |
2550 | "column": 3, | 2550 | "column": 3, |
2551 | "line": 48 | 2551 | "line": 50 |
2552 | }, | 2552 | }, |
2553 | "file": "src/components/settings/services/EditServiceForm.js", | 2553 | "file": "src/components/settings/services/EditServiceForm.js", |
2554 | "id": "settings.service.form.recipeFileInfo", | 2554 | "id": "settings.service.form.recipeFileInfo", |
2555 | "start": { | 2555 | "start": { |
2556 | "column": 18, | 2556 | "column": 18, |
2557 | "line": 45 | 2557 | "line": 47 |
2558 | } | 2558 | } |
2559 | }, | 2559 | }, |
2560 | { | 2560 | { |
2561 | "defaultMessage": "!!!Available services", | 2561 | "defaultMessage": "!!!Available services", |
2562 | "end": { | 2562 | "end": { |
2563 | "column": 3, | 2563 | "column": 3, |
2564 | "line": 52 | 2564 | "line": 54 |
2565 | }, | 2565 | }, |
2566 | "file": "src/components/settings/services/EditServiceForm.js", | 2566 | "file": "src/components/settings/services/EditServiceForm.js", |
2567 | "id": "settings.service.form.availableServices", | 2567 | "id": "settings.service.form.availableServices", |
2568 | "start": { | 2568 | "start": { |
2569 | "column": 21, | 2569 | "column": 21, |
2570 | "line": 49 | 2570 | "line": 51 |
2571 | } | 2571 | } |
2572 | }, | 2572 | }, |
2573 | { | 2573 | { |
2574 | "defaultMessage": "!!!Your services", | 2574 | "defaultMessage": "!!!Your services", |
2575 | "end": { | 2575 | "end": { |
2576 | "column": 3, | 2576 | "column": 3, |
2577 | "line": 56 | 2577 | "line": 58 |
2578 | }, | 2578 | }, |
2579 | "file": "src/components/settings/services/EditServiceForm.js", | 2579 | "file": "src/components/settings/services/EditServiceForm.js", |
2580 | "id": "settings.service.form.yourServices", | 2580 | "id": "settings.service.form.yourServices", |
2581 | "start": { | 2581 | "start": { |
2582 | "column": 16, | 2582 | "column": 16, |
2583 | "line": 53 | 2583 | "line": 55 |
2584 | } | 2584 | } |
2585 | }, | 2585 | }, |
2586 | { | 2586 | { |
2587 | "defaultMessage": "!!!Add {name}", | 2587 | "defaultMessage": "!!!Add {name}", |
2588 | "end": { | 2588 | "end": { |
2589 | "column": 3, | 2589 | "column": 3, |
2590 | "line": 60 | 2590 | "line": 62 |
2591 | }, | 2591 | }, |
2592 | "file": "src/components/settings/services/EditServiceForm.js", | 2592 | "file": "src/components/settings/services/EditServiceForm.js", |
2593 | "id": "settings.service.form.addServiceHeadline", | 2593 | "id": "settings.service.form.addServiceHeadline", |
2594 | "start": { | 2594 | "start": { |
2595 | "column": 22, | 2595 | "column": 22, |
2596 | "line": 57 | 2596 | "line": 59 |
2597 | } | 2597 | } |
2598 | }, | 2598 | }, |
2599 | { | 2599 | { |
2600 | "defaultMessage": "!!!Edit {name}", | 2600 | "defaultMessage": "!!!Edit {name}", |
2601 | "end": { | 2601 | "end": { |
2602 | "column": 3, | 2602 | "column": 3, |
2603 | "line": 64 | 2603 | "line": 66 |
2604 | }, | 2604 | }, |
2605 | "file": "src/components/settings/services/EditServiceForm.js", | 2605 | "file": "src/components/settings/services/EditServiceForm.js", |
2606 | "id": "settings.service.form.editServiceHeadline", | 2606 | "id": "settings.service.form.editServiceHeadline", |
2607 | "start": { | 2607 | "start": { |
2608 | "column": 23, | 2608 | "column": 23, |
2609 | "line": 61 | 2609 | "line": 63 |
2610 | } | 2610 | } |
2611 | }, | 2611 | }, |
2612 | { | 2612 | { |
2613 | "defaultMessage": "!!!Hosted", | 2613 | "defaultMessage": "!!!Hosted", |
2614 | "end": { | 2614 | "end": { |
2615 | "column": 3, | 2615 | "column": 3, |
2616 | "line": 68 | 2616 | "line": 70 |
2617 | }, | 2617 | }, |
2618 | "file": "src/components/settings/services/EditServiceForm.js", | 2618 | "file": "src/components/settings/services/EditServiceForm.js", |
2619 | "id": "settings.service.form.tabHosted", | 2619 | "id": "settings.service.form.tabHosted", |
2620 | "start": { | 2620 | "start": { |
2621 | "column": 13, | 2621 | "column": 13, |
2622 | "line": 65 | 2622 | "line": 67 |
2623 | } | 2623 | } |
2624 | }, | 2624 | }, |
2625 | { | 2625 | { |
2626 | "defaultMessage": "!!!Self hosted ⭐️", | 2626 | "defaultMessage": "!!!Self hosted ⭐️", |
2627 | "end": { | 2627 | "end": { |
2628 | "column": 3, | 2628 | "column": 3, |
2629 | "line": 72 | 2629 | "line": 74 |
2630 | }, | 2630 | }, |
2631 | "file": "src/components/settings/services/EditServiceForm.js", | 2631 | "file": "src/components/settings/services/EditServiceForm.js", |
2632 | "id": "settings.service.form.tabOnPremise", | 2632 | "id": "settings.service.form.tabOnPremise", |
2633 | "start": { | 2633 | "start": { |
2634 | "column": 16, | 2634 | "column": 16, |
2635 | "line": 69 | 2635 | "line": 71 |
2636 | } | 2636 | } |
2637 | }, | 2637 | }, |
2638 | { | 2638 | { |
2639 | "defaultMessage": "!!!Use the hosted {name} service.", | 2639 | "defaultMessage": "!!!Use the hosted {name} service.", |
2640 | "end": { | 2640 | "end": { |
2641 | "column": 3, | 2641 | "column": 3, |
2642 | "line": 76 | 2642 | "line": 78 |
2643 | }, | 2643 | }, |
2644 | "file": "src/components/settings/services/EditServiceForm.js", | 2644 | "file": "src/components/settings/services/EditServiceForm.js", |
2645 | "id": "settings.service.form.useHostedService", | 2645 | "id": "settings.service.form.useHostedService", |
2646 | "start": { | 2646 | "start": { |
2647 | "column": 20, | 2647 | "column": 20, |
2648 | "line": 73 | 2648 | "line": 75 |
2649 | } | 2649 | } |
2650 | }, | 2650 | }, |
2651 | { | 2651 | { |
2652 | "defaultMessage": "!!!Could not validate custom {name} server.", | 2652 | "defaultMessage": "!!!Could not validate custom {name} server.", |
2653 | "end": { | 2653 | "end": { |
2654 | "column": 3, | 2654 | "column": 3, |
2655 | "line": 80 | 2655 | "line": 82 |
2656 | }, | 2656 | }, |
2657 | "file": "src/components/settings/services/EditServiceForm.js", | 2657 | "file": "src/components/settings/services/EditServiceForm.js", |
2658 | "id": "settings.service.form.customUrlValidationError", | 2658 | "id": "settings.service.form.customUrlValidationError", |
2659 | "start": { | 2659 | "start": { |
2660 | "column": 28, | 2660 | "column": 28, |
2661 | "line": 77 | 2661 | "line": 79 |
2662 | } | 2662 | } |
2663 | }, | 2663 | }, |
2664 | { | 2664 | { |
2665 | "defaultMessage": "!!!To add self hosted services, you need a Ferdi Premium Supporter Account.", | 2665 | "defaultMessage": "!!!To add self hosted services, you need a Ferdi Premium Supporter Account.", |
2666 | "end": { | 2666 | "end": { |
2667 | "column": 3, | 2667 | "column": 3, |
2668 | "line": 84 | 2668 | "line": 86 |
2669 | }, | 2669 | }, |
2670 | "file": "src/components/settings/services/EditServiceForm.js", | 2670 | "file": "src/components/settings/services/EditServiceForm.js", |
2671 | "id": "settings.service.form.customUrlPremiumInfo", | 2671 | "id": "settings.service.form.customUrlPremiumInfo", |
2672 | "start": { | 2672 | "start": { |
2673 | "column": 24, | 2673 | "column": 24, |
2674 | "line": 81 | 2674 | "line": 83 |
2675 | } | 2675 | } |
2676 | }, | 2676 | }, |
2677 | { | 2677 | { |
2678 | "defaultMessage": "!!!Upgrade your account", | 2678 | "defaultMessage": "!!!Upgrade your account", |
2679 | "end": { | 2679 | "end": { |
2680 | "column": 3, | 2680 | "column": 3, |
2681 | "line": 88 | 2681 | "line": 90 |
2682 | }, | 2682 | }, |
2683 | "file": "src/components/settings/services/EditServiceForm.js", | 2683 | "file": "src/components/settings/services/EditServiceForm.js", |
2684 | "id": "settings.service.form.customUrlUpgradeAccount", | 2684 | "id": "settings.service.form.customUrlUpgradeAccount", |
2685 | "start": { | 2685 | "start": { |
2686 | "column": 27, | 2686 | "column": 27, |
2687 | "line": 85 | 2687 | "line": 87 |
2688 | } | 2688 | } |
2689 | }, | 2689 | }, |
2690 | { | 2690 | { |
2691 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", | 2691 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", |
2692 | "end": { | 2692 | "end": { |
2693 | "column": 3, | 2693 | "column": 3, |
2694 | "line": 92 | 2694 | "line": 94 |
2695 | }, | 2695 | }, |
2696 | "file": "src/components/settings/services/EditServiceForm.js", | 2696 | "file": "src/components/settings/services/EditServiceForm.js", |
2697 | "id": "settings.service.form.indirectMessageInfo", | 2697 | "id": "settings.service.form.indirectMessageInfo", |
2698 | "start": { | 2698 | "start": { |
2699 | "column": 23, | 2699 | "column": 23, |
2700 | "line": 89 | 2700 | "line": 91 |
2701 | } | 2701 | } |
2702 | }, | 2702 | }, |
2703 | { | 2703 | { |
2704 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", | 2704 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", |
2705 | "end": { | 2705 | "end": { |
2706 | "column": 3, | 2706 | "column": 3, |
2707 | "line": 96 | 2707 | "line": 98 |
2708 | }, | 2708 | }, |
2709 | "file": "src/components/settings/services/EditServiceForm.js", | 2709 | "file": "src/components/settings/services/EditServiceForm.js", |
2710 | "id": "settings.service.form.isMutedInfo", | 2710 | "id": "settings.service.form.isMutedInfo", |
2711 | "start": { | 2711 | "start": { |
2712 | "column": 15, | 2712 | "column": 15, |
2713 | "line": 93 | 2713 | "line": 95 |
2714 | } | 2714 | } |
2715 | }, | 2715 | }, |
2716 | { | 2716 | { |
2717 | "defaultMessage": "!!!You currently have hibernation enabled but you can disable hibernation for individual services using this option.", | 2717 | "defaultMessage": "!!!You currently have hibernation enabled but you can disable hibernation for individual services using this option.", |
2718 | "end": { | 2718 | "end": { |
2719 | "column": 3, | 2719 | "column": 3, |
2720 | "line": 100 | 2720 | "line": 102 |
2721 | }, | 2721 | }, |
2722 | "file": "src/components/settings/services/EditServiceForm.js", | 2722 | "file": "src/components/settings/services/EditServiceForm.js", |
2723 | "id": "settings.service.form.disableHibernationInfo", | 2723 | "id": "settings.service.form.disableHibernationInfo", |
2724 | "start": { | 2724 | "start": { |
2725 | "column": 26, | 2725 | "column": 26, |
2726 | "line": 97 | 2726 | "line": 99 |
2727 | } | 2727 | } |
2728 | }, | 2728 | }, |
2729 | { | 2729 | { |
2730 | "defaultMessage": "!!!Notifications", | 2730 | "defaultMessage": "!!!Notifications", |
2731 | "end": { | 2731 | "end": { |
2732 | "column": 3, | 2732 | "column": 3, |
2733 | "line": 104 | 2733 | "line": 106 |
2734 | }, | 2734 | }, |
2735 | "file": "src/components/settings/services/EditServiceForm.js", | 2735 | "file": "src/components/settings/services/EditServiceForm.js", |
2736 | "id": "settings.service.form.headlineNotifications", | 2736 | "id": "settings.service.form.headlineNotifications", |
2737 | "start": { | 2737 | "start": { |
2738 | "column": 25, | 2738 | "column": 25, |
2739 | "line": 101 | 2739 | "line": 103 |
2740 | } | 2740 | } |
2741 | }, | 2741 | }, |
2742 | { | 2742 | { |
2743 | "defaultMessage": "!!!Unread message badges", | 2743 | "defaultMessage": "!!!Unread message badges", |
2744 | "end": { | 2744 | "end": { |
2745 | "column": 3, | 2745 | "column": 3, |
2746 | "line": 108 | 2746 | "line": 110 |
2747 | }, | 2747 | }, |
2748 | "file": "src/components/settings/services/EditServiceForm.js", | 2748 | "file": "src/components/settings/services/EditServiceForm.js", |
2749 | "id": "settings.service.form.headlineBadges", | 2749 | "id": "settings.service.form.headlineBadges", |
2750 | "start": { | 2750 | "start": { |
2751 | "column": 18, | 2751 | "column": 18, |
2752 | "line": 105 | 2752 | "line": 107 |
2753 | } | 2753 | } |
2754 | }, | 2754 | }, |
2755 | { | 2755 | { |
2756 | "defaultMessage": "!!!General", | 2756 | "defaultMessage": "!!!General", |
2757 | "end": { | 2757 | "end": { |
2758 | "column": 3, | 2758 | "column": 3, |
2759 | "line": 112 | 2759 | "line": 114 |
2760 | }, | 2760 | }, |
2761 | "file": "src/components/settings/services/EditServiceForm.js", | 2761 | "file": "src/components/settings/services/EditServiceForm.js", |
2762 | "id": "settings.service.form.headlineGeneral", | 2762 | "id": "settings.service.form.headlineGeneral", |
2763 | "start": { | 2763 | "start": { |
2764 | "column": 19, | 2764 | "column": 19, |
2765 | "line": 109 | 2765 | "line": 111 |
2766 | } | 2766 | } |
2767 | }, | 2767 | }, |
2768 | { | 2768 | { |
2769 | "defaultMessage": "!!!Dark Reader Settings", | 2769 | "defaultMessage": "!!!Dark Reader Settings", |
2770 | "end": { | 2770 | "end": { |
2771 | "column": 3, | 2771 | "column": 3, |
2772 | "line": 116 | 2772 | "line": 118 |
2773 | }, | 2773 | }, |
2774 | "file": "src/components/settings/services/EditServiceForm.js", | 2774 | "file": "src/components/settings/services/EditServiceForm.js", |
2775 | "id": "settings.service.form.headlineDarkReaderSettings", | 2775 | "id": "settings.service.form.headlineDarkReaderSettings", |
2776 | "start": { | 2776 | "start": { |
2777 | "column": 30, | 2777 | "column": 30, |
2778 | "line": 113 | 2778 | "line": 115 |
2779 | } | 2779 | } |
2780 | }, | 2780 | }, |
2781 | { | 2781 | { |
2782 | "defaultMessage": "!!!Delete", | 2782 | "defaultMessage": "!!!Delete", |
2783 | "end": { | 2783 | "end": { |
2784 | "column": 3, | 2784 | "column": 3, |
2785 | "line": 120 | 2785 | "line": 122 |
2786 | }, | 2786 | }, |
2787 | "file": "src/components/settings/services/EditServiceForm.js", | 2787 | "file": "src/components/settings/services/EditServiceForm.js", |
2788 | "id": "settings.service.form.iconDelete", | 2788 | "id": "settings.service.form.iconDelete", |
2789 | "start": { | 2789 | "start": { |
2790 | "column": 14, | 2790 | "column": 14, |
2791 | "line": 117 | 2791 | "line": 119 |
2792 | } | 2792 | } |
2793 | }, | 2793 | }, |
2794 | { | 2794 | { |
2795 | "defaultMessage": "!!!Drop your image, or click here", | 2795 | "defaultMessage": "!!!Drop your image, or click here", |
2796 | "end": { | 2796 | "end": { |
2797 | "column": 3, | 2797 | "column": 3, |
2798 | "line": 124 | 2798 | "line": 126 |
2799 | }, | 2799 | }, |
2800 | "file": "src/components/settings/services/EditServiceForm.js", | 2800 | "file": "src/components/settings/services/EditServiceForm.js", |
2801 | "id": "settings.service.form.iconUpload", | 2801 | "id": "settings.service.form.iconUpload", |
2802 | "start": { | 2802 | "start": { |
2803 | "column": 14, | 2803 | "column": 14, |
2804 | "line": 121 | 2804 | "line": 123 |
2805 | } | 2805 | } |
2806 | }, | 2806 | }, |
2807 | { | 2807 | { |
2808 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", | 2808 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", |
2809 | "end": { | 2809 | "end": { |
2810 | "column": 3, | 2810 | "column": 3, |
2811 | "line": 128 | 2811 | "line": 130 |
2812 | }, | 2812 | }, |
2813 | "file": "src/components/settings/services/EditServiceForm.js", | 2813 | "file": "src/components/settings/services/EditServiceForm.js", |
2814 | "id": "settings.service.form.proxy.headline", | 2814 | "id": "settings.service.form.proxy.headline", |
2815 | "start": { | 2815 | "start": { |
2816 | "column": 17, | 2816 | "column": 17, |
2817 | "line": 125 | 2817 | "line": 127 |
2818 | } | 2818 | } |
2819 | }, | 2819 | }, |
2820 | { | 2820 | { |
2821 | "defaultMessage": "!!!Please restart Ferdi after changing proxy Settings.", | 2821 | "defaultMessage": "!!!Please restart Ferdi after changing proxy Settings.", |
2822 | "end": { | 2822 | "end": { |
2823 | "column": 3, | 2823 | "column": 3, |
2824 | "line": 132 | 2824 | "line": 134 |
2825 | }, | 2825 | }, |
2826 | "file": "src/components/settings/services/EditServiceForm.js", | 2826 | "file": "src/components/settings/services/EditServiceForm.js", |
2827 | "id": "settings.service.form.proxy.restartInfo", | 2827 | "id": "settings.service.form.proxy.restartInfo", |
2828 | "start": { | 2828 | "start": { |
2829 | "column": 20, | 2829 | "column": 20, |
2830 | "line": 129 | 2830 | "line": 131 |
2831 | } | 2831 | } |
2832 | }, | 2832 | }, |
2833 | { | 2833 | { |
2834 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Ferdi servers.", | 2834 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Ferdi servers.", |
2835 | "end": { | 2835 | "end": { |
2836 | "column": 3, | 2836 | "column": 3, |
2837 | "line": 136 | 2837 | "line": 138 |
2838 | }, | 2838 | }, |
2839 | "file": "src/components/settings/services/EditServiceForm.js", | 2839 | "file": "src/components/settings/services/EditServiceForm.js", |
2840 | "id": "settings.service.form.proxy.info", | 2840 | "id": "settings.service.form.proxy.info", |
2841 | "start": { | 2841 | "start": { |
2842 | "column": 13, | 2842 | "column": 13, |
2843 | "line": 133 | 2843 | "line": 135 |
2844 | } | 2844 | } |
2845 | } | 2845 | } |
2846 | ], | 2846 | ], |
@@ -3306,159 +3306,172 @@ | |||
3306 | } | 3306 | } |
3307 | }, | 3307 | }, |
3308 | { | 3308 | { |
3309 | "defaultMessage": "!!!Cache", | 3309 | "defaultMessage": "!!!Ferdi uses your Mac's build-in spellchecker to check for typos. If you want to change the languages the spellchecker checks for, you can do so in your Mac's System Preferences.", |
3310 | "end": { | 3310 | "end": { |
3311 | "column": 3, | 3311 | "column": 3, |
3312 | "line": 97 | 3312 | "line": 97 |
3313 | }, | 3313 | }, |
3314 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3314 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3315 | "id": "settings.app.spellCheckerLanguageInfo", | ||
3316 | "start": { | ||
3317 | "column": 28, | ||
3318 | "line": 94 | ||
3319 | } | ||
3320 | }, | ||
3321 | { | ||
3322 | "defaultMessage": "!!!Cache", | ||
3323 | "end": { | ||
3324 | "column": 3, | ||
3325 | "line": 101 | ||
3326 | }, | ||
3327 | "file": "src/components/settings/settings/EditSettingsForm.js", | ||
3315 | "id": "settings.app.subheadlineCache", | 3328 | "id": "settings.app.subheadlineCache", |
3316 | "start": { | 3329 | "start": { |
3317 | "column": 20, | 3330 | "column": 20, |
3318 | "line": 94 | 3331 | "line": 98 |
3319 | } | 3332 | } |
3320 | }, | 3333 | }, |
3321 | { | 3334 | { |
3322 | "defaultMessage": "!!!Ferdi cache is currently using {size} of disk space.", | 3335 | "defaultMessage": "!!!Ferdi cache is currently using {size} of disk space.", |
3323 | "end": { | 3336 | "end": { |
3324 | "column": 3, | 3337 | "column": 3, |
3325 | "line": 101 | 3338 | "line": 105 |
3326 | }, | 3339 | }, |
3327 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3340 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3328 | "id": "settings.app.cacheInfo", | 3341 | "id": "settings.app.cacheInfo", |
3329 | "start": { | 3342 | "start": { |
3330 | "column": 13, | 3343 | "column": 13, |
3331 | "line": 98 | 3344 | "line": 102 |
3332 | } | 3345 | } |
3333 | }, | 3346 | }, |
3334 | { | 3347 | { |
3335 | "defaultMessage": "!!!Couldn't clear all cache", | 3348 | "defaultMessage": "!!!Couldn't clear all cache", |
3336 | "end": { | 3349 | "end": { |
3337 | "column": 3, | 3350 | "column": 3, |
3338 | "line": 105 | 3351 | "line": 109 |
3339 | }, | 3352 | }, |
3340 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3353 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3341 | "id": "settings.app.cacheNotCleared", | 3354 | "id": "settings.app.cacheNotCleared", |
3342 | "start": { | 3355 | "start": { |
3343 | "column": 19, | 3356 | "column": 19, |
3344 | "line": 102 | 3357 | "line": 106 |
3345 | } | 3358 | } |
3346 | }, | 3359 | }, |
3347 | { | 3360 | { |
3348 | "defaultMessage": "!!!Clear cache", | 3361 | "defaultMessage": "!!!Clear cache", |
3349 | "end": { | 3362 | "end": { |
3350 | "column": 3, | 3363 | "column": 3, |
3351 | "line": 109 | 3364 | "line": 113 |
3352 | }, | 3365 | }, |
3353 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3366 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3354 | "id": "settings.app.buttonClearAllCache", | 3367 | "id": "settings.app.buttonClearAllCache", |
3355 | "start": { | 3368 | "start": { |
3356 | "column": 23, | 3369 | "column": 23, |
3357 | "line": 106 | 3370 | "line": 110 |
3358 | } | 3371 | } |
3359 | }, | 3372 | }, |
3360 | { | 3373 | { |
3361 | "defaultMessage": "!!!Check for updates", | 3374 | "defaultMessage": "!!!Check for updates", |
3362 | "end": { | 3375 | "end": { |
3363 | "column": 3, | 3376 | "column": 3, |
3364 | "line": 113 | 3377 | "line": 117 |
3365 | }, | 3378 | }, |
3366 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3379 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3367 | "id": "settings.app.buttonSearchForUpdate", | 3380 | "id": "settings.app.buttonSearchForUpdate", |
3368 | "start": { | 3381 | "start": { |
3369 | "column": 25, | 3382 | "column": 25, |
3370 | "line": 110 | 3383 | "line": 114 |
3371 | } | 3384 | } |
3372 | }, | 3385 | }, |
3373 | { | 3386 | { |
3374 | "defaultMessage": "!!!Restart & install update", | 3387 | "defaultMessage": "!!!Restart & install update", |
3375 | "end": { | 3388 | "end": { |
3376 | "column": 3, | 3389 | "column": 3, |
3377 | "line": 117 | 3390 | "line": 121 |
3378 | }, | 3391 | }, |
3379 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3392 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3380 | "id": "settings.app.buttonInstallUpdate", | 3393 | "id": "settings.app.buttonInstallUpdate", |
3381 | "start": { | 3394 | "start": { |
3382 | "column": 23, | 3395 | "column": 23, |
3383 | "line": 114 | 3396 | "line": 118 |
3384 | } | 3397 | } |
3385 | }, | 3398 | }, |
3386 | { | 3399 | { |
3387 | "defaultMessage": "!!!Is searching for update", | 3400 | "defaultMessage": "!!!Is searching for update", |
3388 | "end": { | 3401 | "end": { |
3389 | "column": 3, | 3402 | "column": 3, |
3390 | "line": 121 | 3403 | "line": 125 |
3391 | }, | 3404 | }, |
3392 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3405 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3393 | "id": "settings.app.updateStatusSearching", | 3406 | "id": "settings.app.updateStatusSearching", |
3394 | "start": { | 3407 | "start": { |
3395 | "column": 25, | 3408 | "column": 25, |
3396 | "line": 118 | 3409 | "line": 122 |
3397 | } | 3410 | } |
3398 | }, | 3411 | }, |
3399 | { | 3412 | { |
3400 | "defaultMessage": "!!!Update available, downloading...", | 3413 | "defaultMessage": "!!!Update available, downloading...", |
3401 | "end": { | 3414 | "end": { |
3402 | "column": 3, | 3415 | "column": 3, |
3403 | "line": 125 | 3416 | "line": 129 |
3404 | }, | 3417 | }, |
3405 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3418 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3406 | "id": "settings.app.updateStatusAvailable", | 3419 | "id": "settings.app.updateStatusAvailable", |
3407 | "start": { | 3420 | "start": { |
3408 | "column": 25, | 3421 | "column": 25, |
3409 | "line": 122 | 3422 | "line": 126 |
3410 | } | 3423 | } |
3411 | }, | 3424 | }, |
3412 | { | 3425 | { |
3413 | "defaultMessage": "!!!You are using the latest version of Ferdi", | 3426 | "defaultMessage": "!!!You are using the latest version of Ferdi", |
3414 | "end": { | 3427 | "end": { |
3415 | "column": 3, | 3428 | "column": 3, |
3416 | "line": 129 | 3429 | "line": 133 |
3417 | }, | 3430 | }, |
3418 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3431 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3419 | "id": "settings.app.updateStatusUpToDate", | 3432 | "id": "settings.app.updateStatusUpToDate", |
3420 | "start": { | 3433 | "start": { |
3421 | "column": 24, | 3434 | "column": 24, |
3422 | "line": 126 | 3435 | "line": 130 |
3423 | } | 3436 | } |
3424 | }, | 3437 | }, |
3425 | { | 3438 | { |
3426 | "defaultMessage": "!!!Current version:", | 3439 | "defaultMessage": "!!!Current version:", |
3427 | "end": { | 3440 | "end": { |
3428 | "column": 3, | 3441 | "column": 3, |
3429 | "line": 133 | 3442 | "line": 137 |
3430 | }, | 3443 | }, |
3431 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3444 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3432 | "id": "settings.app.currentVersion", | 3445 | "id": "settings.app.currentVersion", |
3433 | "start": { | 3446 | "start": { |
3434 | "column": 18, | 3447 | "column": 18, |
3435 | "line": 130 | 3448 | "line": 134 |
3436 | } | 3449 | } |
3437 | }, | 3450 | }, |
3438 | { | 3451 | { |
3439 | "defaultMessage": "!!!Changes require restart", | 3452 | "defaultMessage": "!!!Changes require restart", |
3440 | "end": { | 3453 | "end": { |
3441 | "column": 3, | 3454 | "column": 3, |
3442 | "line": 137 | 3455 | "line": 141 |
3443 | }, | 3456 | }, |
3444 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3457 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3445 | "id": "settings.app.restartRequired", | 3458 | "id": "settings.app.restartRequired", |
3446 | "start": { | 3459 | "start": { |
3447 | "column": 29, | 3460 | "column": 29, |
3448 | "line": 134 | 3461 | "line": 138 |
3449 | } | 3462 | } |
3450 | }, | 3463 | }, |
3451 | { | 3464 | { |
3452 | "defaultMessage": "!!!Official translations are English & German. All other languages are community based translations.", | 3465 | "defaultMessage": "!!!Official translations are English & German. All other languages are community based translations.", |
3453 | "end": { | 3466 | "end": { |
3454 | "column": 3, | 3467 | "column": 3, |
3455 | "line": 141 | 3468 | "line": 145 |
3456 | }, | 3469 | }, |
3457 | "file": "src/components/settings/settings/EditSettingsForm.js", | 3470 | "file": "src/components/settings/settings/EditSettingsForm.js", |
3458 | "id": "settings.app.languageDisclaimer", | 3471 | "id": "settings.app.languageDisclaimer", |
3459 | "start": { | 3472 | "start": { |
3460 | "column": 22, | 3473 | "column": 22, |
3461 | "line": 138 | 3474 | "line": 142 |
3462 | } | 3475 | } |
3463 | } | 3476 | } |
3464 | ], | 3477 | ], |
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index dcaa2466a..fd5c0755b 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -335,6 +335,7 @@ | |||
335 | "settings.app.scheduledDNDInfo": "Scheduled Do-not-Disturb allows you to define a period of time in which you do not want to get Notifications from Ferdi.", | 335 | "settings.app.scheduledDNDInfo": "Scheduled Do-not-Disturb allows you to define a period of time in which you do not want to get Notifications from Ferdi.", |
336 | "settings.app.scheduledDNDTimeInfo": "Times in 24-Hour-Format. End time can be before start time (e.g. start 17:00, end 09:00) to enable Do-not-Disturb overnight.", | 336 | "settings.app.scheduledDNDTimeInfo": "Times in 24-Hour-Format. End time can be before start time (e.g. start 17:00, end 09:00) to enable Do-not-Disturb overnight.", |
337 | "settings.app.sentryInfo": "Sending telemetry data allows us to find errors in Ferdi - we will not send any personal information like your message data! Changing this option requires you to restart Ferdi.", | 337 | "settings.app.sentryInfo": "Sending telemetry data allows us to find errors in Ferdi - we will not send any personal information like your message data! Changing this option requires you to restart Ferdi.", |
338 | "settings.app.spellCheckerLanguageInfo": "Ferdi uses your Mac's build-in spellchecker to check for typos. If you want to change the languages the spellchecker checks for, you can do so in your Mac's System Preferences.", | ||
338 | "settings.app.subheadlineCache": "Cache", | 339 | "settings.app.subheadlineCache": "Cache", |
339 | "settings.app.todoServerInfo": "This server will be used for the \"Ferdi Todo\" feature.", | 340 | "settings.app.todoServerInfo": "This server will be used for the \"Ferdi Todo\" feature.", |
340 | "settings.app.translationHelp": "Help us to translate Ferdi into your language.", | 341 | "settings.app.translationHelp": "Help us to translate Ferdi into your language.", |
diff --git a/src/i18n/messages/src/components/auth/Locked.json b/src/i18n/messages/src/components/auth/Locked.json index ac6091c35..ed3999114 100644 --- a/src/i18n/messages/src/components/auth/Locked.json +++ b/src/i18n/messages/src/components/auth/Locked.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Locked", | 4 | "defaultMessage": "!!!Locked", |
5 | "file": "src/components/auth/Locked.js", | 5 | "file": "src/components/auth/Locked.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 19, | 7 | "line": 20, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 22, | 11 | "line": 23, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Ferdi is currently locked. Please unlock Ferdi with your password to see your messages.", | 17 | "defaultMessage": "!!!Ferdi is currently locked. Please unlock Ferdi with your password to see your messages.", |
18 | "file": "src/components/auth/Locked.js", | 18 | "file": "src/components/auth/Locked.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 23, | 20 | "line": 24, |
21 | "column": 8 | 21 | "column": 8 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 26, | 24 | "line": 27, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Unlock with Touch ID", | 30 | "defaultMessage": "!!!Unlock with Touch ID", |
31 | "file": "src/components/auth/Locked.js", | 31 | "file": "src/components/auth/Locked.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 27, | 33 | "line": 28, |
34 | "column": 11 | 34 | "column": 11 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 30, | 37 | "line": 31, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!unlock via Touch ID", | 43 | "defaultMessage": "!!!unlock via Touch ID", |
44 | "file": "src/components/auth/Locked.js", | 44 | "file": "src/components/auth/Locked.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 31, | 46 | "line": 32, |
47 | "column": 17 | 47 | "column": 17 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 34, | 50 | "line": 35, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Password", | 56 | "defaultMessage": "!!!Password", |
57 | "file": "src/components/auth/Locked.js", | 57 | "file": "src/components/auth/Locked.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 35, | 59 | "line": 36, |
60 | "column": 17 | 60 | "column": 17 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 38, | 63 | "line": 39, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Unlock", | 69 | "defaultMessage": "!!!Unlock", |
70 | "file": "src/components/auth/Locked.js", | 70 | "file": "src/components/auth/Locked.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 39, | 72 | "line": 40, |
73 | "column": 21 | 73 | "column": 21 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 42, | 76 | "line": 43, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Unlock with Password", | 82 | "defaultMessage": "!!!Unlock with Password", |
83 | "file": "src/components/auth/Locked.js", | 83 | "file": "src/components/auth/Locked.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 43, | 85 | "line": 44, |
86 | "column": 22 | 86 | "column": 22 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 46, | 89 | "line": 47, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Password invalid", | 95 | "defaultMessage": "!!!Password invalid", |
96 | "file": "src/components/auth/Locked.js", | 96 | "file": "src/components/auth/Locked.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 47, | 98 | "line": 48, |
99 | "column": 22 | 99 | "column": 22 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 50, | 102 | "line": 51, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | } | 105 | } |
diff --git a/src/i18n/messages/src/components/settings/services/EditServiceForm.json b/src/i18n/messages/src/components/settings/services/EditServiceForm.json index 987004199..4ee427e46 100644 --- a/src/i18n/messages/src/components/settings/services/EditServiceForm.json +++ b/src/i18n/messages/src/components/settings/services/EditServiceForm.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Save service", | 4 | "defaultMessage": "!!!Save service", |
5 | "file": "src/components/settings/services/EditServiceForm.js", | 5 | "file": "src/components/settings/services/EditServiceForm.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 25, | 7 | "line": 27, |
8 | "column": 15 | 8 | "column": 15 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 28, | 11 | "line": 30, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Delete Service", | 17 | "defaultMessage": "!!!Delete Service", |
18 | "file": "src/components/settings/services/EditServiceForm.js", | 18 | "file": "src/components/settings/services/EditServiceForm.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 29, | 20 | "line": 31, |
21 | "column": 17 | 21 | "column": 17 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 32, | 24 | "line": 34, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Open darkmode.css", | 30 | "defaultMessage": "!!!Open darkmode.css", |
31 | "file": "src/components/settings/services/EditServiceForm.js", | 31 | "file": "src/components/settings/services/EditServiceForm.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 33, | 33 | "line": 35, |
34 | "column": 19 | 34 | "column": 19 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 36, | 37 | "line": 38, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Open user.css", | 43 | "defaultMessage": "!!!Open user.css", |
44 | "file": "src/components/settings/services/EditServiceForm.js", | 44 | "file": "src/components/settings/services/EditServiceForm.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 37, | 46 | "line": 39, |
47 | "column": 15 | 47 | "column": 15 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 40, | 50 | "line": 42, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Open user.js", | 56 | "defaultMessage": "!!!Open user.js", |
57 | "file": "src/components/settings/services/EditServiceForm.js", | 57 | "file": "src/components/settings/services/EditServiceForm.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 41, | 59 | "line": 43, |
60 | "column": 14 | 60 | "column": 14 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 44, | 63 | "line": 46, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Your user files will be inserted into the webpage so you can customize services in any way you like. User files are only stored locally and are not transferred to other computers using the same account.", | 69 | "defaultMessage": "!!!Your user files will be inserted into the webpage so you can customize services in any way you like. User files are only stored locally and are not transferred to other computers using the same account.", |
70 | "file": "src/components/settings/services/EditServiceForm.js", | 70 | "file": "src/components/settings/services/EditServiceForm.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 45, | 72 | "line": 47, |
73 | "column": 18 | 73 | "column": 18 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 48, | 76 | "line": 50, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Available services", | 82 | "defaultMessage": "!!!Available services", |
83 | "file": "src/components/settings/services/EditServiceForm.js", | 83 | "file": "src/components/settings/services/EditServiceForm.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 49, | 85 | "line": 51, |
86 | "column": 21 | 86 | "column": 21 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 52, | 89 | "line": 54, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Your services", | 95 | "defaultMessage": "!!!Your services", |
96 | "file": "src/components/settings/services/EditServiceForm.js", | 96 | "file": "src/components/settings/services/EditServiceForm.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 53, | 98 | "line": 55, |
99 | "column": 16 | 99 | "column": 16 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 56, | 102 | "line": 58, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | }, | 105 | }, |
@@ -108,11 +108,11 @@ | |||
108 | "defaultMessage": "!!!Add {name}", | 108 | "defaultMessage": "!!!Add {name}", |
109 | "file": "src/components/settings/services/EditServiceForm.js", | 109 | "file": "src/components/settings/services/EditServiceForm.js", |
110 | "start": { | 110 | "start": { |
111 | "line": 57, | 111 | "line": 59, |
112 | "column": 22 | 112 | "column": 22 |
113 | }, | 113 | }, |
114 | "end": { | 114 | "end": { |
115 | "line": 60, | 115 | "line": 62, |
116 | "column": 3 | 116 | "column": 3 |
117 | } | 117 | } |
118 | }, | 118 | }, |
@@ -121,11 +121,11 @@ | |||
121 | "defaultMessage": "!!!Edit {name}", | 121 | "defaultMessage": "!!!Edit {name}", |
122 | "file": "src/components/settings/services/EditServiceForm.js", | 122 | "file": "src/components/settings/services/EditServiceForm.js", |
123 | "start": { | 123 | "start": { |
124 | "line": 61, | 124 | "line": 63, |
125 | "column": 23 | 125 | "column": 23 |
126 | }, | 126 | }, |
127 | "end": { | 127 | "end": { |
128 | "line": 64, | 128 | "line": 66, |
129 | "column": 3 | 129 | "column": 3 |
130 | } | 130 | } |
131 | }, | 131 | }, |
@@ -134,11 +134,11 @@ | |||
134 | "defaultMessage": "!!!Hosted", | 134 | "defaultMessage": "!!!Hosted", |
135 | "file": "src/components/settings/services/EditServiceForm.js", | 135 | "file": "src/components/settings/services/EditServiceForm.js", |
136 | "start": { | 136 | "start": { |
137 | "line": 65, | 137 | "line": 67, |
138 | "column": 13 | 138 | "column": 13 |
139 | }, | 139 | }, |
140 | "end": { | 140 | "end": { |
141 | "line": 68, | 141 | "line": 70, |
142 | "column": 3 | 142 | "column": 3 |
143 | } | 143 | } |
144 | }, | 144 | }, |
@@ -147,11 +147,11 @@ | |||
147 | "defaultMessage": "!!!Self hosted ⭐️", | 147 | "defaultMessage": "!!!Self hosted ⭐️", |
148 | "file": "src/components/settings/services/EditServiceForm.js", | 148 | "file": "src/components/settings/services/EditServiceForm.js", |
149 | "start": { | 149 | "start": { |
150 | "line": 69, | 150 | "line": 71, |
151 | "column": 16 | 151 | "column": 16 |
152 | }, | 152 | }, |
153 | "end": { | 153 | "end": { |
154 | "line": 72, | 154 | "line": 74, |
155 | "column": 3 | 155 | "column": 3 |
156 | } | 156 | } |
157 | }, | 157 | }, |
@@ -160,11 +160,11 @@ | |||
160 | "defaultMessage": "!!!Use the hosted {name} service.", | 160 | "defaultMessage": "!!!Use the hosted {name} service.", |
161 | "file": "src/components/settings/services/EditServiceForm.js", | 161 | "file": "src/components/settings/services/EditServiceForm.js", |
162 | "start": { | 162 | "start": { |
163 | "line": 73, | 163 | "line": 75, |
164 | "column": 20 | 164 | "column": 20 |
165 | }, | 165 | }, |
166 | "end": { | 166 | "end": { |
167 | "line": 76, | 167 | "line": 78, |
168 | "column": 3 | 168 | "column": 3 |
169 | } | 169 | } |
170 | }, | 170 | }, |
@@ -173,11 +173,11 @@ | |||
173 | "defaultMessage": "!!!Could not validate custom {name} server.", | 173 | "defaultMessage": "!!!Could not validate custom {name} server.", |
174 | "file": "src/components/settings/services/EditServiceForm.js", | 174 | "file": "src/components/settings/services/EditServiceForm.js", |
175 | "start": { | 175 | "start": { |
176 | "line": 77, | 176 | "line": 79, |
177 | "column": 28 | 177 | "column": 28 |
178 | }, | 178 | }, |
179 | "end": { | 179 | "end": { |
180 | "line": 80, | 180 | "line": 82, |
181 | "column": 3 | 181 | "column": 3 |
182 | } | 182 | } |
183 | }, | 183 | }, |
@@ -186,11 +186,11 @@ | |||
186 | "defaultMessage": "!!!To add self hosted services, you need a Ferdi Premium Supporter Account.", | 186 | "defaultMessage": "!!!To add self hosted services, you need a Ferdi Premium Supporter Account.", |
187 | "file": "src/components/settings/services/EditServiceForm.js", | 187 | "file": "src/components/settings/services/EditServiceForm.js", |
188 | "start": { | 188 | "start": { |
189 | "line": 81, | 189 | "line": 83, |
190 | "column": 24 | 190 | "column": 24 |
191 | }, | 191 | }, |
192 | "end": { | 192 | "end": { |
193 | "line": 84, | 193 | "line": 86, |
194 | "column": 3 | 194 | "column": 3 |
195 | } | 195 | } |
196 | }, | 196 | }, |
@@ -199,11 +199,11 @@ | |||
199 | "defaultMessage": "!!!Upgrade your account", | 199 | "defaultMessage": "!!!Upgrade your account", |
200 | "file": "src/components/settings/services/EditServiceForm.js", | 200 | "file": "src/components/settings/services/EditServiceForm.js", |
201 | "start": { | 201 | "start": { |
202 | "line": 85, | 202 | "line": 87, |
203 | "column": 27 | 203 | "column": 27 |
204 | }, | 204 | }, |
205 | "end": { | 205 | "end": { |
206 | "line": 88, | 206 | "line": 90, |
207 | "column": 3 | 207 | "column": 3 |
208 | } | 208 | } |
209 | }, | 209 | }, |
@@ -212,11 +212,11 @@ | |||
212 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", | 212 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", |
213 | "file": "src/components/settings/services/EditServiceForm.js", | 213 | "file": "src/components/settings/services/EditServiceForm.js", |
214 | "start": { | 214 | "start": { |
215 | "line": 89, | 215 | "line": 91, |
216 | "column": 23 | 216 | "column": 23 |
217 | }, | 217 | }, |
218 | "end": { | 218 | "end": { |
219 | "line": 92, | 219 | "line": 94, |
220 | "column": 3 | 220 | "column": 3 |
221 | } | 221 | } |
222 | }, | 222 | }, |
@@ -225,11 +225,11 @@ | |||
225 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", | 225 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", |
226 | "file": "src/components/settings/services/EditServiceForm.js", | 226 | "file": "src/components/settings/services/EditServiceForm.js", |
227 | "start": { | 227 | "start": { |
228 | "line": 93, | 228 | "line": 95, |
229 | "column": 15 | 229 | "column": 15 |
230 | }, | 230 | }, |
231 | "end": { | 231 | "end": { |
232 | "line": 96, | 232 | "line": 98, |
233 | "column": 3 | 233 | "column": 3 |
234 | } | 234 | } |
235 | }, | 235 | }, |
@@ -238,11 +238,11 @@ | |||
238 | "defaultMessage": "!!!You currently have hibernation enabled but you can disable hibernation for individual services using this option.", | 238 | "defaultMessage": "!!!You currently have hibernation enabled but you can disable hibernation for individual services using this option.", |
239 | "file": "src/components/settings/services/EditServiceForm.js", | 239 | "file": "src/components/settings/services/EditServiceForm.js", |
240 | "start": { | 240 | "start": { |
241 | "line": 97, | 241 | "line": 99, |
242 | "column": 26 | 242 | "column": 26 |
243 | }, | 243 | }, |
244 | "end": { | 244 | "end": { |
245 | "line": 100, | 245 | "line": 102, |
246 | "column": 3 | 246 | "column": 3 |
247 | } | 247 | } |
248 | }, | 248 | }, |
@@ -251,11 +251,11 @@ | |||
251 | "defaultMessage": "!!!Notifications", | 251 | "defaultMessage": "!!!Notifications", |
252 | "file": "src/components/settings/services/EditServiceForm.js", | 252 | "file": "src/components/settings/services/EditServiceForm.js", |
253 | "start": { | 253 | "start": { |
254 | "line": 101, | 254 | "line": 103, |
255 | "column": 25 | 255 | "column": 25 |
256 | }, | 256 | }, |
257 | "end": { | 257 | "end": { |
258 | "line": 104, | 258 | "line": 106, |
259 | "column": 3 | 259 | "column": 3 |
260 | } | 260 | } |
261 | }, | 261 | }, |
@@ -264,11 +264,11 @@ | |||
264 | "defaultMessage": "!!!Unread message badges", | 264 | "defaultMessage": "!!!Unread message badges", |
265 | "file": "src/components/settings/services/EditServiceForm.js", | 265 | "file": "src/components/settings/services/EditServiceForm.js", |
266 | "start": { | 266 | "start": { |
267 | "line": 105, | 267 | "line": 107, |
268 | "column": 18 | 268 | "column": 18 |
269 | }, | 269 | }, |
270 | "end": { | 270 | "end": { |
271 | "line": 108, | 271 | "line": 110, |
272 | "column": 3 | 272 | "column": 3 |
273 | } | 273 | } |
274 | }, | 274 | }, |
@@ -277,11 +277,11 @@ | |||
277 | "defaultMessage": "!!!General", | 277 | "defaultMessage": "!!!General", |
278 | "file": "src/components/settings/services/EditServiceForm.js", | 278 | "file": "src/components/settings/services/EditServiceForm.js", |
279 | "start": { | 279 | "start": { |
280 | "line": 109, | 280 | "line": 111, |
281 | "column": 19 | 281 | "column": 19 |
282 | }, | 282 | }, |
283 | "end": { | 283 | "end": { |
284 | "line": 112, | 284 | "line": 114, |
285 | "column": 3 | 285 | "column": 3 |
286 | } | 286 | } |
287 | }, | 287 | }, |
@@ -290,11 +290,11 @@ | |||
290 | "defaultMessage": "!!!Dark Reader Settings", | 290 | "defaultMessage": "!!!Dark Reader Settings", |
291 | "file": "src/components/settings/services/EditServiceForm.js", | 291 | "file": "src/components/settings/services/EditServiceForm.js", |
292 | "start": { | 292 | "start": { |
293 | "line": 113, | 293 | "line": 115, |
294 | "column": 30 | 294 | "column": 30 |
295 | }, | 295 | }, |
296 | "end": { | 296 | "end": { |
297 | "line": 116, | 297 | "line": 118, |
298 | "column": 3 | 298 | "column": 3 |
299 | } | 299 | } |
300 | }, | 300 | }, |
@@ -303,11 +303,11 @@ | |||
303 | "defaultMessage": "!!!Delete", | 303 | "defaultMessage": "!!!Delete", |
304 | "file": "src/components/settings/services/EditServiceForm.js", | 304 | "file": "src/components/settings/services/EditServiceForm.js", |
305 | "start": { | 305 | "start": { |
306 | "line": 117, | 306 | "line": 119, |
307 | "column": 14 | 307 | "column": 14 |
308 | }, | 308 | }, |
309 | "end": { | 309 | "end": { |
310 | "line": 120, | 310 | "line": 122, |
311 | "column": 3 | 311 | "column": 3 |
312 | } | 312 | } |
313 | }, | 313 | }, |
@@ -316,11 +316,11 @@ | |||
316 | "defaultMessage": "!!!Drop your image, or click here", | 316 | "defaultMessage": "!!!Drop your image, or click here", |
317 | "file": "src/components/settings/services/EditServiceForm.js", | 317 | "file": "src/components/settings/services/EditServiceForm.js", |
318 | "start": { | 318 | "start": { |
319 | "line": 121, | 319 | "line": 123, |
320 | "column": 14 | 320 | "column": 14 |
321 | }, | 321 | }, |
322 | "end": { | 322 | "end": { |
323 | "line": 124, | 323 | "line": 126, |
324 | "column": 3 | 324 | "column": 3 |
325 | } | 325 | } |
326 | }, | 326 | }, |
@@ -329,11 +329,11 @@ | |||
329 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", | 329 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", |
330 | "file": "src/components/settings/services/EditServiceForm.js", | 330 | "file": "src/components/settings/services/EditServiceForm.js", |
331 | "start": { | 331 | "start": { |
332 | "line": 125, | 332 | "line": 127, |
333 | "column": 17 | 333 | "column": 17 |
334 | }, | 334 | }, |
335 | "end": { | 335 | "end": { |
336 | "line": 128, | 336 | "line": 130, |
337 | "column": 3 | 337 | "column": 3 |
338 | } | 338 | } |
339 | }, | 339 | }, |
@@ -342,11 +342,11 @@ | |||
342 | "defaultMessage": "!!!Please restart Ferdi after changing proxy Settings.", | 342 | "defaultMessage": "!!!Please restart Ferdi after changing proxy Settings.", |
343 | "file": "src/components/settings/services/EditServiceForm.js", | 343 | "file": "src/components/settings/services/EditServiceForm.js", |
344 | "start": { | 344 | "start": { |
345 | "line": 129, | 345 | "line": 131, |
346 | "column": 20 | 346 | "column": 20 |
347 | }, | 347 | }, |
348 | "end": { | 348 | "end": { |
349 | "line": 132, | 349 | "line": 134, |
350 | "column": 3 | 350 | "column": 3 |
351 | } | 351 | } |
352 | }, | 352 | }, |
@@ -355,11 +355,11 @@ | |||
355 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Ferdi servers.", | 355 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Ferdi servers.", |
356 | "file": "src/components/settings/services/EditServiceForm.js", | 356 | "file": "src/components/settings/services/EditServiceForm.js", |
357 | "start": { | 357 | "start": { |
358 | "line": 133, | 358 | "line": 135, |
359 | "column": 13 | 359 | "column": 13 |
360 | }, | 360 | }, |
361 | "end": { | 361 | "end": { |
362 | "line": 136, | 362 | "line": 138, |
363 | "column": 3 | 363 | "column": 3 |
364 | } | 364 | } |
365 | } | 365 | } |
diff --git a/src/i18n/messages/src/components/settings/services/ServicesDashboard.json b/src/i18n/messages/src/components/settings/services/ServicesDashboard.json index fa661ea2f..140d17a8b 100644 --- a/src/i18n/messages/src/components/settings/services/ServicesDashboard.json +++ b/src/i18n/messages/src/components/settings/services/ServicesDashboard.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Your services", | 4 | "defaultMessage": "!!!Your services", |
5 | "file": "src/components/settings/services/ServicesDashboard.js", | 5 | "file": "src/components/settings/services/ServicesDashboard.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 15, | 7 | "line": 16, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 18, | 11 | "line": 19, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Search service", | 17 | "defaultMessage": "!!!Search service", |
18 | "file": "src/components/settings/services/ServicesDashboard.js", | 18 | "file": "src/components/settings/services/ServicesDashboard.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 19, | 20 | "line": 20, |
21 | "column": 17 | 21 | "column": 17 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 22, | 24 | "line": 23, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!You haven't added any services yet.", | 30 | "defaultMessage": "!!!You haven't added any services yet.", |
31 | "file": "src/components/settings/services/ServicesDashboard.js", | 31 | "file": "src/components/settings/services/ServicesDashboard.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 23, | 33 | "line": 24, |
34 | "column": 19 | 34 | "column": 19 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 26, | 37 | "line": 27, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Sorry, but no service matched your search term.", | 43 | "defaultMessage": "!!!Sorry, but no service matched your search term.", |
44 | "file": "src/components/settings/services/ServicesDashboard.js", | 44 | "file": "src/components/settings/services/ServicesDashboard.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 27, | 46 | "line": 28, |
47 | "column": 18 | 47 | "column": 18 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 30, | 50 | "line": 31, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Discover services", | 56 | "defaultMessage": "!!!Discover services", |
57 | "file": "src/components/settings/services/ServicesDashboard.js", | 57 | "file": "src/components/settings/services/ServicesDashboard.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 31, | 59 | "line": 32, |
60 | "column": 20 | 60 | "column": 20 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 34, | 63 | "line": 35, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Could not load your services", | 69 | "defaultMessage": "!!!Could not load your services", |
70 | "file": "src/components/settings/services/ServicesDashboard.js", | 70 | "file": "src/components/settings/services/ServicesDashboard.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 35, | 72 | "line": 36, |
73 | "column": 25 | 73 | "column": 25 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 38, | 76 | "line": 39, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Try again", | 82 | "defaultMessage": "!!!Try again", |
83 | "file": "src/components/settings/services/ServicesDashboard.js", | 83 | "file": "src/components/settings/services/ServicesDashboard.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 39, | 85 | "line": 40, |
86 | "column": 21 | 86 | "column": 21 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 42, | 89 | "line": 43, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Your changes have been saved", | 95 | "defaultMessage": "!!!Your changes have been saved", |
96 | "file": "src/components/settings/services/ServicesDashboard.js", | 96 | "file": "src/components/settings/services/ServicesDashboard.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 43, | 98 | "line": 44, |
99 | "column": 15 | 99 | "column": 15 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 46, | 102 | "line": 47, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | }, | 105 | }, |
@@ -108,11 +108,11 @@ | |||
108 | "defaultMessage": "!!!Service has been deleted", | 108 | "defaultMessage": "!!!Service has been deleted", |
109 | "file": "src/components/settings/services/ServicesDashboard.js", | 109 | "file": "src/components/settings/services/ServicesDashboard.js", |
110 | "start": { | 110 | "start": { |
111 | "line": 47, | 111 | "line": 48, |
112 | "column": 15 | 112 | "column": 15 |
113 | }, | 113 | }, |
114 | "end": { | 114 | "end": { |
115 | "line": 50, | 115 | "line": 51, |
116 | "column": 3 | 116 | "column": 3 |
117 | } | 117 | } |
118 | } | 118 | } |
diff --git a/src/i18n/messages/src/components/settings/settings/EditSettingsForm.json b/src/i18n/messages/src/components/settings/settings/EditSettingsForm.json index 97360b78e..373cd78f9 100644 --- a/src/i18n/messages/src/components/settings/settings/EditSettingsForm.json +++ b/src/i18n/messages/src/components/settings/settings/EditSettingsForm.json | |||
@@ -234,15 +234,28 @@ | |||
234 | } | 234 | } |
235 | }, | 235 | }, |
236 | { | 236 | { |
237 | "id": "settings.app.spellCheckerLanguageInfo", | ||
238 | "defaultMessage": "!!!Ferdi uses your Mac's build-in spellchecker to check for typos. If you want to change the languages the spellchecker checks for, you can do so in your Mac's System Preferences.", | ||
239 | "file": "src/components/settings/settings/EditSettingsForm.js", | ||
240 | "start": { | ||
241 | "line": 94, | ||
242 | "column": 28 | ||
243 | }, | ||
244 | "end": { | ||
245 | "line": 97, | ||
246 | "column": 3 | ||
247 | } | ||
248 | }, | ||
249 | { | ||
237 | "id": "settings.app.subheadlineCache", | 250 | "id": "settings.app.subheadlineCache", |
238 | "defaultMessage": "!!!Cache", | 251 | "defaultMessage": "!!!Cache", |
239 | "file": "src/components/settings/settings/EditSettingsForm.js", | 252 | "file": "src/components/settings/settings/EditSettingsForm.js", |
240 | "start": { | 253 | "start": { |
241 | "line": 94, | 254 | "line": 98, |
242 | "column": 20 | 255 | "column": 20 |
243 | }, | 256 | }, |
244 | "end": { | 257 | "end": { |
245 | "line": 97, | 258 | "line": 101, |
246 | "column": 3 | 259 | "column": 3 |
247 | } | 260 | } |
248 | }, | 261 | }, |
@@ -251,11 +264,11 @@ | |||
251 | "defaultMessage": "!!!Ferdi cache is currently using {size} of disk space.", | 264 | "defaultMessage": "!!!Ferdi cache is currently using {size} of disk space.", |
252 | "file": "src/components/settings/settings/EditSettingsForm.js", | 265 | "file": "src/components/settings/settings/EditSettingsForm.js", |
253 | "start": { | 266 | "start": { |
254 | "line": 98, | 267 | "line": 102, |
255 | "column": 13 | 268 | "column": 13 |
256 | }, | 269 | }, |
257 | "end": { | 270 | "end": { |
258 | "line": 101, | 271 | "line": 105, |
259 | "column": 3 | 272 | "column": 3 |
260 | } | 273 | } |
261 | }, | 274 | }, |
@@ -264,11 +277,11 @@ | |||
264 | "defaultMessage": "!!!Couldn't clear all cache", | 277 | "defaultMessage": "!!!Couldn't clear all cache", |
265 | "file": "src/components/settings/settings/EditSettingsForm.js", | 278 | "file": "src/components/settings/settings/EditSettingsForm.js", |
266 | "start": { | 279 | "start": { |
267 | "line": 102, | 280 | "line": 106, |
268 | "column": 19 | 281 | "column": 19 |
269 | }, | 282 | }, |
270 | "end": { | 283 | "end": { |
271 | "line": 105, | 284 | "line": 109, |
272 | "column": 3 | 285 | "column": 3 |
273 | } | 286 | } |
274 | }, | 287 | }, |
@@ -277,11 +290,11 @@ | |||
277 | "defaultMessage": "!!!Clear cache", | 290 | "defaultMessage": "!!!Clear cache", |
278 | "file": "src/components/settings/settings/EditSettingsForm.js", | 291 | "file": "src/components/settings/settings/EditSettingsForm.js", |
279 | "start": { | 292 | "start": { |
280 | "line": 106, | 293 | "line": 110, |
281 | "column": 23 | 294 | "column": 23 |
282 | }, | 295 | }, |
283 | "end": { | 296 | "end": { |
284 | "line": 109, | 297 | "line": 113, |
285 | "column": 3 | 298 | "column": 3 |
286 | } | 299 | } |
287 | }, | 300 | }, |
@@ -290,11 +303,11 @@ | |||
290 | "defaultMessage": "!!!Check for updates", | 303 | "defaultMessage": "!!!Check for updates", |
291 | "file": "src/components/settings/settings/EditSettingsForm.js", | 304 | "file": "src/components/settings/settings/EditSettingsForm.js", |
292 | "start": { | 305 | "start": { |
293 | "line": 110, | 306 | "line": 114, |
294 | "column": 25 | 307 | "column": 25 |
295 | }, | 308 | }, |
296 | "end": { | 309 | "end": { |
297 | "line": 113, | 310 | "line": 117, |
298 | "column": 3 | 311 | "column": 3 |
299 | } | 312 | } |
300 | }, | 313 | }, |
@@ -303,11 +316,11 @@ | |||
303 | "defaultMessage": "!!!Restart & install update", | 316 | "defaultMessage": "!!!Restart & install update", |
304 | "file": "src/components/settings/settings/EditSettingsForm.js", | 317 | "file": "src/components/settings/settings/EditSettingsForm.js", |
305 | "start": { | 318 | "start": { |
306 | "line": 114, | 319 | "line": 118, |
307 | "column": 23 | 320 | "column": 23 |
308 | }, | 321 | }, |
309 | "end": { | 322 | "end": { |
310 | "line": 117, | 323 | "line": 121, |
311 | "column": 3 | 324 | "column": 3 |
312 | } | 325 | } |
313 | }, | 326 | }, |
@@ -316,11 +329,11 @@ | |||
316 | "defaultMessage": "!!!Is searching for update", | 329 | "defaultMessage": "!!!Is searching for update", |
317 | "file": "src/components/settings/settings/EditSettingsForm.js", | 330 | "file": "src/components/settings/settings/EditSettingsForm.js", |
318 | "start": { | 331 | "start": { |
319 | "line": 118, | 332 | "line": 122, |
320 | "column": 25 | 333 | "column": 25 |
321 | }, | 334 | }, |
322 | "end": { | 335 | "end": { |
323 | "line": 121, | 336 | "line": 125, |
324 | "column": 3 | 337 | "column": 3 |
325 | } | 338 | } |
326 | }, | 339 | }, |
@@ -329,11 +342,11 @@ | |||
329 | "defaultMessage": "!!!Update available, downloading...", | 342 | "defaultMessage": "!!!Update available, downloading...", |
330 | "file": "src/components/settings/settings/EditSettingsForm.js", | 343 | "file": "src/components/settings/settings/EditSettingsForm.js", |
331 | "start": { | 344 | "start": { |
332 | "line": 122, | 345 | "line": 126, |
333 | "column": 25 | 346 | "column": 25 |
334 | }, | 347 | }, |
335 | "end": { | 348 | "end": { |
336 | "line": 125, | 349 | "line": 129, |
337 | "column": 3 | 350 | "column": 3 |
338 | } | 351 | } |
339 | }, | 352 | }, |
@@ -342,11 +355,11 @@ | |||
342 | "defaultMessage": "!!!You are using the latest version of Ferdi", | 355 | "defaultMessage": "!!!You are using the latest version of Ferdi", |
343 | "file": "src/components/settings/settings/EditSettingsForm.js", | 356 | "file": "src/components/settings/settings/EditSettingsForm.js", |
344 | "start": { | 357 | "start": { |
345 | "line": 126, | 358 | "line": 130, |
346 | "column": 24 | 359 | "column": 24 |
347 | }, | 360 | }, |
348 | "end": { | 361 | "end": { |
349 | "line": 129, | 362 | "line": 133, |
350 | "column": 3 | 363 | "column": 3 |
351 | } | 364 | } |
352 | }, | 365 | }, |
@@ -355,11 +368,11 @@ | |||
355 | "defaultMessage": "!!!Current version:", | 368 | "defaultMessage": "!!!Current version:", |
356 | "file": "src/components/settings/settings/EditSettingsForm.js", | 369 | "file": "src/components/settings/settings/EditSettingsForm.js", |
357 | "start": { | 370 | "start": { |
358 | "line": 130, | 371 | "line": 134, |
359 | "column": 18 | 372 | "column": 18 |
360 | }, | 373 | }, |
361 | "end": { | 374 | "end": { |
362 | "line": 133, | 375 | "line": 137, |
363 | "column": 3 | 376 | "column": 3 |
364 | } | 377 | } |
365 | }, | 378 | }, |
@@ -368,11 +381,11 @@ | |||
368 | "defaultMessage": "!!!Changes require restart", | 381 | "defaultMessage": "!!!Changes require restart", |
369 | "file": "src/components/settings/settings/EditSettingsForm.js", | 382 | "file": "src/components/settings/settings/EditSettingsForm.js", |
370 | "start": { | 383 | "start": { |
371 | "line": 134, | 384 | "line": 138, |
372 | "column": 29 | 385 | "column": 29 |
373 | }, | 386 | }, |
374 | "end": { | 387 | "end": { |
375 | "line": 137, | 388 | "line": 141, |
376 | "column": 3 | 389 | "column": 3 |
377 | } | 390 | } |
378 | }, | 391 | }, |
@@ -381,11 +394,11 @@ | |||
381 | "defaultMessage": "!!!Official translations are English & German. All other languages are community based translations.", | 394 | "defaultMessage": "!!!Official translations are English & German. All other languages are community based translations.", |
382 | "file": "src/components/settings/settings/EditSettingsForm.js", | 395 | "file": "src/components/settings/settings/EditSettingsForm.js", |
383 | "start": { | 396 | "start": { |
384 | "line": 138, | 397 | "line": 142, |
385 | "column": 22 | 398 | "column": 22 |
386 | }, | 399 | }, |
387 | "end": { | 400 | "end": { |
388 | "line": 141, | 401 | "line": 145, |
389 | "column": 3 | 402 | "column": 3 |
390 | } | 403 | } |
391 | } | 404 | } |
diff --git a/src/i18n/messages/src/features/todos/components/TodosWebview.json b/src/i18n/messages/src/features/todos/components/TodosWebview.json index 173389570..ff6e037fc 100644 --- a/src/i18n/messages/src/features/todos/components/TodosWebview.json +++ b/src/i18n/messages/src/features/todos/components/TodosWebview.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Franz Todos are available to premium users now!", | 4 | "defaultMessage": "!!!Franz Todos are available to premium users now!", |
5 | "file": "src/features/todos/components/TodosWebview.js", | 5 | "file": "src/features/todos/components/TodosWebview.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 27, | 7 | "line": 31, |
8 | "column": 15 | 8 | "column": 15 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 30, | 11 | "line": 34, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Upgrade Account", | 17 | "defaultMessage": "!!!Upgrade Account", |
18 | "file": "src/features/todos/components/TodosWebview.js", | 18 | "file": "src/features/todos/components/TodosWebview.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 31, | 20 | "line": 35, |
21 | "column": 14 | 21 | "column": 14 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 34, | 24 | "line": 38, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Everyone else will have to wait a little longer.", | 30 | "defaultMessage": "!!!Everyone else will have to wait a little longer.", |
31 | "file": "src/features/todos/components/TodosWebview.js", | 31 | "file": "src/features/todos/components/TodosWebview.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 35, | 33 | "line": 39, |
34 | "column": 15 | 34 | "column": 15 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 38, | 37 | "line": 42, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | } | 40 | } |
diff --git a/src/models/Service.js b/src/models/Service.js index 45dc55fce..4b5e8592d 100644 --- a/src/models/Service.js +++ b/src/models/Service.js | |||
@@ -1,5 +1,5 @@ | |||
1 | import { autorun, computed, observable } from 'mobx'; | 1 | import { autorun, computed, observable } from 'mobx'; |
2 | import { ipcRenderer } from 'electron'; | 2 | import { ipcRenderer, remote } from 'electron'; |
3 | import normalizeUrl from 'normalize-url'; | 3 | import normalizeUrl from 'normalize-url'; |
4 | import path from 'path'; | 4 | import path from 'path'; |
5 | 5 | ||
@@ -227,7 +227,7 @@ export default class Service { | |||
227 | 227 | ||
228 | 228 | ||
229 | initializeWebViewEvents({ handleIPCMessage, openWindow, stores }) { | 229 | initializeWebViewEvents({ handleIPCMessage, openWindow, stores }) { |
230 | const webContents = this.webview.getWebContents(); | 230 | const webContents = remote.webContents.fromId(this.webview.getWebContentsId()); |
231 | 231 | ||
232 | // If the recipe has implemented modifyRequestHeaders, | 232 | // If the recipe has implemented modifyRequestHeaders, |
233 | // Send those headers to ipcMain so that it can be set in session | 233 | // Send those headers to ipcMain so that it can be set in session |
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index a8d9cc1fb..448260638 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js | |||
@@ -618,7 +618,10 @@ export default class ServicesStore extends Store { | |||
618 | const service = this.one(serviceId); | 618 | const service = this.one(serviceId); |
619 | 619 | ||
620 | if (service.webview) { | 620 | if (service.webview) { |
621 | service.webview.send(channel, args); | 621 | // Make sure the args are clean, otherwise ElectronJS can't transmit them |
622 | const cleanArgs = JSON.parse(JSON.stringify(args)); | ||
623 | |||
624 | service.webview.send(channel, cleanArgs); | ||
622 | } | 625 | } |
623 | } | 626 | } |
624 | 627 | ||
@@ -895,10 +898,14 @@ export default class ServicesStore extends Store { | |||
895 | const service = this.one(serviceId); | 898 | const service = this.one(serviceId); |
896 | 899 | ||
897 | if (service.webview) { | 900 | if (service.webview) { |
901 | // We need to completely clone the object, otherwise Electron won't be able to send the object via IPC | ||
902 | const shareWithWebview = JSON.parse(JSON.stringify(service.shareWithWebview)); | ||
903 | |||
898 | debug('Initialize recipe', service.recipe.id, service.name); | 904 | debug('Initialize recipe', service.recipe.id, service.name); |
899 | service.webview.send('initialize-recipe', Object.assign({ | 905 | service.webview.send('initialize-recipe', { |
906 | ...shareWithWebview, | ||
900 | franzVersion: app.getVersion(), | 907 | franzVersion: app.getVersion(), |
901 | }, service.shareWithWebview), service.recipe); | 908 | }, service.recipe); |
902 | } | 909 | } |
903 | } | 910 | } |
904 | 911 | ||
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js index 3a53d150d..c1ed2944a 100644 --- a/src/stores/UserStore.js +++ b/src/stores/UserStore.js | |||
@@ -99,7 +99,7 @@ export default class UserStore extends Store { | |||
99 | 99 | ||
100 | // Reactions | 100 | // Reactions |
101 | this.registerReactions([ | 101 | this.registerReactions([ |
102 | this._requireAuthenticatedUser, | 102 | this._requireAuthenticatedUser.bind(this), |
103 | this._getUserData.bind(this), | 103 | this._getUserData.bind(this), |
104 | this._resetTrialActivationState.bind(this), | 104 | this._resetTrialActivationState.bind(this), |
105 | ]); | 105 | ]); |
@@ -321,7 +321,7 @@ export default class UserStore extends Store { | |||
321 | } | 321 | } |
322 | 322 | ||
323 | const { router } = this.stores; | 323 | const { router } = this.stores; |
324 | const currentRoute = router.location.pathname; | 324 | const currentRoute = window.location.hash; |
325 | if (!this.isLoggedIn | 325 | if (!this.isLoggedIn |
326 | && currentRoute.includes('token=')) { | 326 | && currentRoute.includes('token=')) { |
327 | router.push(this.WELCOME_ROUTE); | 327 | router.push(this.WELCOME_ROUTE); |
diff --git a/src/styles/button.scss b/src/styles/button.scss index 38f8fd26d..cf2568fc4 100644 --- a/src/styles/button.scss +++ b/src/styles/button.scss | |||
@@ -110,3 +110,32 @@ | |||
110 | z-index: 9999; | 110 | z-index: 9999; |
111 | } | 111 | } |
112 | } | 112 | } |
113 | |||
114 | .ferdi__fab { | ||
115 | box-sizing: border-box; | ||
116 | |||
117 | width: 50px; | ||
118 | height: 50px; | ||
119 | |||
120 | border-radius: 25px; | ||
121 | white-space: nowrap; | ||
122 | z-index: 9998; | ||
123 | list-style: none; | ||
124 | background: $theme-brand-primary; | ||
125 | |||
126 | position: absolute; | ||
127 | bottom: 20px; | ||
128 | right: 20px; | ||
129 | |||
130 | cursor: pointer; | ||
131 | |||
132 | display: flex; | ||
133 | justify-content: center; | ||
134 | align-items: center; | ||
135 | |||
136 | a { | ||
137 | font-size: 30px; | ||
138 | color: #FFFFFF; | ||
139 | cursor: pointer; | ||
140 | } | ||
141 | } \ No newline at end of file | ||
diff --git a/src/webview/contextMenu.js b/src/webview/contextMenu.js index eeb825ece..d04f90830 100644 --- a/src/webview/contextMenu.js +++ b/src/webview/contextMenu.js | |||
@@ -1,50 +1,14 @@ | |||
1 | import { remote } from 'electron'; | 1 | import { remote } from 'electron'; |
2 | import { ContextMenuBuilder, ContextMenuListener } from 'electron-spellchecker'; | 2 | import ContextMenuBuilder from './contextMenuBuilder'; |
3 | 3 | ||
4 | const webContents = remote.getCurrentWebContents(); | 4 | const webContents = remote.getCurrentWebContents(); |
5 | 5 | ||
6 | export default async function setupContextMenu(handler) { | 6 | export default async function setupContextMenu() { |
7 | const addCustomMenuItems = (menu, menuInfo) => { | ||
8 | // Add "Paste as plain text" item when right-clicking editable content | ||
9 | if ( | ||
10 | menuInfo.editFlags.canPaste | ||
11 | && !menuInfo.linkText | ||
12 | && !menuInfo.hasImageContents | ||
13 | ) { | ||
14 | menu.insert( | ||
15 | 3, | ||
16 | new remote.MenuItem({ | ||
17 | label: 'Paste as plain text', | ||
18 | accelerator: 'CommandOrControl+Shift+V', | ||
19 | click: () => webContents.pasteAndMatchStyle(), | ||
20 | }), | ||
21 | ); | ||
22 | } | ||
23 | |||
24 | // Add "Open Link in Ferdi" item for links | ||
25 | if (menuInfo.linkURL) { | ||
26 | menu.insert( | ||
27 | 2, | ||
28 | new remote.MenuItem({ | ||
29 | label: 'Open Link in Ferdi', | ||
30 | click: () => { | ||
31 | window.location.href = menuInfo.linkURL; | ||
32 | }, | ||
33 | }), | ||
34 | ); | ||
35 | } | ||
36 | |||
37 | return menu; | ||
38 | }; | ||
39 | |||
40 | const contextMenuBuilder = new ContextMenuBuilder( | 7 | const contextMenuBuilder = new ContextMenuBuilder( |
41 | handler, | 8 | webContents, |
42 | null, | ||
43 | true, | ||
44 | addCustomMenuItems, | ||
45 | ); | 9 | ); |
46 | // eslint-disable-next-line no-new | 10 | |
47 | new ContextMenuListener((info) => { | 11 | webContents.on('context-menu', (event, params) => { |
48 | contextMenuBuilder.showPopupMenu(info); | 12 | contextMenuBuilder.showPopupMenu(params); |
49 | }); | 13 | }); |
50 | } | 14 | } |
diff --git a/src/webview/contextMenuBuilder.js b/src/webview/contextMenuBuilder.js new file mode 100644 index 000000000..ee27877b9 --- /dev/null +++ b/src/webview/contextMenuBuilder.js | |||
@@ -0,0 +1,419 @@ | |||
1 | /** | ||
2 | * Context Menu builder. | ||
3 | * | ||
4 | * Based on "electron-spellchecker"'s ContextMenuBuilder but customized for Ferdi | ||
5 | * and for usage with Electron's build-in spellchecker | ||
6 | * | ||
7 | * Source: https://github.com/electron-userland/electron-spellchecker/blob/master/src/context-menu-builder.js | ||
8 | */ | ||
9 | const { | ||
10 | clipboard, nativeImage, remote, shell, | ||
11 | } = require('electron'); | ||
12 | |||
13 | const { Menu, MenuItem } = remote; | ||
14 | |||
15 | function matchesWord(string) { | ||
16 | const regex = /[\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]+/g; | ||
17 | |||
18 | return string.match(regex); | ||
19 | } | ||
20 | |||
21 | const contextMenuStringTable = { | ||
22 | copyMail: () => 'Copy Email Address', | ||
23 | copyLinkUrl: () => 'Copy Link', | ||
24 | openLinkUrl: () => 'Open Link', | ||
25 | copyImageUrl: () => 'Copy Image URL', | ||
26 | copyImage: () => 'Copy Image', | ||
27 | addToDictionary: () => 'Add to Dictionary', | ||
28 | lookUpDefinition: ({ word }) => `Look Up "${word}"`, | ||
29 | searchGoogle: () => 'Search with Google', | ||
30 | cut: () => 'Cut', | ||
31 | copy: () => 'Copy', | ||
32 | paste: () => 'Paste', | ||
33 | inspectElement: () => 'Inspect Element', | ||
34 | }; | ||
35 | |||
36 | /** | ||
37 | * ContextMenuBuilder creates context menus based on the content clicked - this | ||
38 | * information is derived from | ||
39 | * https://github.com/electron/electron/blob/master/docs/api/web-contents.md#event-context-menu, | ||
40 | * which we use to generate the menu. We also use the spell-check information to | ||
41 | * generate suggestions. | ||
42 | */ | ||
43 | module.exports = class ContextMenuBuilder { | ||
44 | /** | ||
45 | * Creates an instance of ContextMenuBuilder | ||
46 | * | ||
47 | * @param {webContents} webContents Current webContents | ||
48 | * @param {Boolean} debugMode If true, display the "Inspect Element" menu item. | ||
49 | * @param {function} processMenu If passed, this method will be passed the menu to change | ||
50 | * it prior to display. Signature: (menu, info) => menu | ||
51 | */ | ||
52 | constructor(webContents, debugMode = false, processMenu = m => m) { | ||
53 | this.debugMode = debugMode; | ||
54 | this.processMenu = processMenu; | ||
55 | this.menu = null; | ||
56 | this.stringTable = Object.assign({}, contextMenuStringTable); | ||
57 | this.getWebContents = () => webContents; | ||
58 | } | ||
59 | |||
60 | /** | ||
61 | * Specify alternate string formatter for each context menu. | ||
62 | * String table consist of string formatter as function instead per each context menu item, | ||
63 | * allows to change string in runtime. All formatters are simply typeof () => string, except | ||
64 | * lookUpDefinition provides word, ({word}) => string. | ||
65 | * | ||
66 | * @param {Object} stringTable The object contains string foramtter function for context menu. | ||
67 | * It is allowed to specify only certain menu string as necessary, which will makes other string | ||
68 | * fall backs to default. | ||
69 | * | ||
70 | */ | ||
71 | setAlternateStringFormatter(stringTable) { | ||
72 | this.stringTable = Object.assign(this.stringTable, stringTable); | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * Shows a popup menu given the information returned from the context-menu | ||
77 | * event. This is probably the only method you need to call in this class. | ||
78 | * | ||
79 | * @param {Object} contextInfo The object returned from the 'context-menu' | ||
80 | * Electron event. | ||
81 | * | ||
82 | * @return {Promise} Completion | ||
83 | */ | ||
84 | async showPopupMenu(contextInfo) { | ||
85 | const menu = await this.buildMenuForElement(contextInfo); | ||
86 | if (!menu) return; | ||
87 | menu.popup({}); | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * Builds a context menu specific to the given info that _would_ be shown | ||
92 | * immediately by {{showPopupMenu}}. Use this to add your own menu items to | ||
93 | * the list but use most of the default behavior. | ||
94 | * | ||
95 | * @return {Promise<Menu>} The newly created `Menu` | ||
96 | */ | ||
97 | async buildMenuForElement(info) { | ||
98 | if (info.linkURL && info.linkURL.length > 0) { | ||
99 | return this.buildMenuForLink(info); | ||
100 | } | ||
101 | |||
102 | if (info.hasImageContents && info.srcURL && info.srcURL.length > 1) { | ||
103 | return this.buildMenuForImage(info); | ||
104 | } | ||
105 | |||
106 | if (info.isEditable || (info.inputFieldType && info.inputFieldType !== 'none')) { | ||
107 | return this.buildMenuForTextInput(info); | ||
108 | } | ||
109 | |||
110 | return this.buildMenuForText(info); | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * Builds a menu applicable to a text input field. | ||
115 | * | ||
116 | * @return {Menu} The `Menu` | ||
117 | */ | ||
118 | buildMenuForTextInput(menuInfo) { | ||
119 | const menu = new Menu(); | ||
120 | |||
121 | this.addSpellingItems(menu, menuInfo); | ||
122 | this.addSearchItems(menu, menuInfo); | ||
123 | |||
124 | this.addCut(menu, menuInfo); | ||
125 | this.addCopy(menu, menuInfo); | ||
126 | this.addPaste(menu, menuInfo); | ||
127 | this.addPastePlain(menu, menuInfo); | ||
128 | this.addInspectElement(menu, menuInfo); | ||
129 | this.processMenu(menu, menuInfo); | ||
130 | |||
131 | return menu; | ||
132 | } | ||
133 | |||
134 | /** | ||
135 | * Builds a menu applicable to a link element. | ||
136 | * | ||
137 | * @return {Menu} The `Menu` | ||
138 | */ | ||
139 | buildMenuForLink(menuInfo) { | ||
140 | const menu = new Menu(); | ||
141 | const isEmailAddress = menuInfo.linkURL.startsWith('mailto:'); | ||
142 | |||
143 | const copyLink = new MenuItem({ | ||
144 | label: isEmailAddress ? this.stringTable.copyMail() : this.stringTable.copyLinkUrl(), | ||
145 | click: () => { | ||
146 | // Omit the mailto: portion of the link; we just want the address | ||
147 | clipboard.writeText(isEmailAddress | ||
148 | ? menuInfo.linkText : menuInfo.linkURL); | ||
149 | }, | ||
150 | }); | ||
151 | |||
152 | const openLink = new MenuItem({ | ||
153 | label: this.stringTable.openLinkUrl(), | ||
154 | click: () => { | ||
155 | shell.openExternal(menuInfo.linkURL); | ||
156 | }, | ||
157 | }); | ||
158 | |||
159 | const openInFerdiLink = new MenuItem({ | ||
160 | label: 'Open Link in Ferdi', | ||
161 | click: () => { | ||
162 | window.location.href = menuInfo.linkURL; | ||
163 | }, | ||
164 | }); | ||
165 | |||
166 | menu.append(copyLink); | ||
167 | menu.append(openLink); | ||
168 | menu.append(openInFerdiLink); | ||
169 | |||
170 | if (this.isSrcUrlValid(menuInfo)) { | ||
171 | this.addSeparator(menu); | ||
172 | this.addImageItems(menu, menuInfo); | ||
173 | } | ||
174 | |||
175 | this.addInspectElement(menu, menuInfo); | ||
176 | this.processMenu(menu, menuInfo); | ||
177 | |||
178 | return menu; | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * Builds a menu applicable to a text field. | ||
183 | * | ||
184 | * @return {Menu} The `Menu` | ||
185 | */ | ||
186 | buildMenuForText(menuInfo) { | ||
187 | const menu = new Menu(); | ||
188 | |||
189 | this.addSearchItems(menu, menuInfo); | ||
190 | this.addCopy(menu, menuInfo); | ||
191 | this.addInspectElement(menu, menuInfo); | ||
192 | this.processMenu(menu, menuInfo); | ||
193 | |||
194 | return menu; | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * Builds a menu applicable to an image. | ||
199 | * | ||
200 | * @return {Menu} The `Menu` | ||
201 | */ | ||
202 | buildMenuForImage(menuInfo) { | ||
203 | const menu = new Menu(); | ||
204 | |||
205 | if (this.isSrcUrlValid(menuInfo)) { | ||
206 | this.addImageItems(menu, menuInfo); | ||
207 | } | ||
208 | this.addInspectElement(menu, menuInfo); | ||
209 | this.processMenu(menu, menuInfo); | ||
210 | |||
211 | return menu; | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * Checks if the current text selection contains a single misspelled word and | ||
216 | * if so, adds suggested spellings as individual menu items. | ||
217 | */ | ||
218 | addSpellingItems(menu, menuInfo) { | ||
219 | const target = this.getWebContents(); | ||
220 | // Add each spelling suggestion | ||
221 | for (const suggestion of menuInfo.dictionarySuggestions) { | ||
222 | menu.append(new MenuItem({ | ||
223 | label: suggestion, | ||
224 | // eslint-disable-next-line no-loop-func | ||
225 | click: () => target.replaceMisspelling(suggestion), | ||
226 | })); | ||
227 | } | ||
228 | |||
229 | // Allow users to add the misspelled word to the dictionary | ||
230 | if (menuInfo.misspelledWord) { | ||
231 | menu.append( | ||
232 | new MenuItem({ | ||
233 | label: 'Add to dictionary', | ||
234 | click: () => target.session.addWordToSpellCheckerDictionary(menuInfo.misspelledWord), | ||
235 | }), | ||
236 | ); | ||
237 | } | ||
238 | |||
239 | return menu; | ||
240 | } | ||
241 | |||
242 | /** | ||
243 | * Adds search-related menu items. | ||
244 | */ | ||
245 | addSearchItems(menu, menuInfo) { | ||
246 | if (!menuInfo.selectionText || menuInfo.selectionText.length < 1) { | ||
247 | return menu; | ||
248 | } | ||
249 | |||
250 | const match = matchesWord(menuInfo.selectionText); | ||
251 | if (!match || match.length === 0) { | ||
252 | return menu; | ||
253 | } | ||
254 | |||
255 | if (process.platform === 'darwin') { | ||
256 | const target = this.getWebContents(); | ||
257 | |||
258 | const lookUpDefinition = new MenuItem({ | ||
259 | label: this.stringTable.lookUpDefinition({ word: menuInfo.selectionText.trim() }), | ||
260 | click: () => target.showDefinitionForSelection(), | ||
261 | }); | ||
262 | |||
263 | menu.append(lookUpDefinition); | ||
264 | } | ||
265 | |||
266 | const search = new MenuItem({ | ||
267 | label: this.stringTable.searchGoogle(), | ||
268 | click: () => { | ||
269 | const url = `https://www.google.com/#q=${encodeURIComponent(menuInfo.selectionText)}`; | ||
270 | |||
271 | shell.openExternal(url); | ||
272 | }, | ||
273 | }); | ||
274 | |||
275 | menu.append(search); | ||
276 | this.addSeparator(menu); | ||
277 | |||
278 | return menu; | ||
279 | } | ||
280 | |||
281 | isSrcUrlValid(menuInfo) { | ||
282 | return menuInfo.srcURL && menuInfo.srcURL.length > 0; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * Adds "Copy Image" and "Copy Image URL" items when `src` is valid. | ||
287 | */ | ||
288 | addImageItems(menu, menuInfo) { | ||
289 | const copyImage = new MenuItem({ | ||
290 | label: this.stringTable.copyImage(), | ||
291 | click: () => this.convertImageToBase64(menuInfo.srcURL, | ||
292 | dataURL => clipboard.writeImage(nativeImage.createFromDataURL(dataURL))), | ||
293 | }); | ||
294 | |||
295 | menu.append(copyImage); | ||
296 | |||
297 | const copyImageUrl = new MenuItem({ | ||
298 | label: this.stringTable.copyImageUrl(), | ||
299 | click: () => clipboard.writeText(menuInfo.srcURL), | ||
300 | }); | ||
301 | |||
302 | menu.append(copyImageUrl); | ||
303 | return menu; | ||
304 | } | ||
305 | |||
306 | /** | ||
307 | * Adds the Cut menu item | ||
308 | */ | ||
309 | addCut(menu, menuInfo) { | ||
310 | const target = this.getWebContents(); | ||
311 | menu.append(new MenuItem({ | ||
312 | label: this.stringTable.cut(), | ||
313 | accelerator: 'CommandOrControl+X', | ||
314 | enabled: menuInfo.editFlags.canCut, | ||
315 | click: () => target.cut(), | ||
316 | })); | ||
317 | |||
318 | return menu; | ||
319 | } | ||
320 | |||
321 | /** | ||
322 | * Adds the Copy menu item. | ||
323 | */ | ||
324 | addCopy(menu, menuInfo) { | ||
325 | const target = this.getWebContents(); | ||
326 | menu.append(new MenuItem({ | ||
327 | label: this.stringTable.copy(), | ||
328 | accelerator: 'CommandOrControl+C', | ||
329 | enabled: menuInfo.editFlags.canCopy, | ||
330 | click: () => target.copy(), | ||
331 | })); | ||
332 | |||
333 | return menu; | ||
334 | } | ||
335 | |||
336 | /** | ||
337 | * Adds the Paste menu item. | ||
338 | */ | ||
339 | addPaste(menu, menuInfo) { | ||
340 | const target = this.getWebContents(); | ||
341 | menu.append(new MenuItem({ | ||
342 | label: this.stringTable.paste(), | ||
343 | accelerator: 'CommandOrControl+V', | ||
344 | enabled: menuInfo.editFlags.canPaste, | ||
345 | click: () => target.paste(), | ||
346 | })); | ||
347 | |||
348 | return menu; | ||
349 | } | ||
350 | |||
351 | addPastePlain(menu, menuInfo) { | ||
352 | if ( | ||
353 | menuInfo.editFlags.canPaste | ||
354 | && !menuInfo.linkText | ||
355 | && !menuInfo.hasImageContents | ||
356 | ) { | ||
357 | const target = this.getWebContents(); | ||
358 | menu.append( | ||
359 | new MenuItem({ | ||
360 | label: 'Paste as plain text', | ||
361 | accelerator: 'CommandOrControl+Shift+V', | ||
362 | click: () => target.pasteAndMatchStyle(), | ||
363 | }), | ||
364 | ); | ||
365 | } | ||
366 | } | ||
367 | |||
368 | /** | ||
369 | * Adds a separator item. | ||
370 | */ | ||
371 | addSeparator(menu) { | ||
372 | menu.append(new MenuItem({ type: 'separator' })); | ||
373 | return menu; | ||
374 | } | ||
375 | |||
376 | /** | ||
377 | * Adds the "Inspect Element" menu item. | ||
378 | */ | ||
379 | addInspectElement(menu, menuInfo, needsSeparator = true) { | ||
380 | const target = this.getWebContents(); | ||
381 | if (!this.debugMode) return menu; | ||
382 | if (needsSeparator) this.addSeparator(menu); | ||
383 | |||
384 | const inspect = new MenuItem({ | ||
385 | label: this.stringTable.inspectElement(), | ||
386 | click: () => target.inspectElement(menuInfo.x, menuInfo.y), | ||
387 | }); | ||
388 | |||
389 | menu.append(inspect); | ||
390 | return menu; | ||
391 | } | ||
392 | |||
393 | /** | ||
394 | * Converts an image to a base-64 encoded string. | ||
395 | * | ||
396 | * @param {String} url The image URL | ||
397 | * @param {Function} callback A callback that will be invoked with the result | ||
398 | * @param {String} outputFormat The image format to use, defaults to 'image/png' | ||
399 | */ | ||
400 | convertImageToBase64(url, callback, outputFormat = 'image/png') { | ||
401 | let canvas = document.createElement('CANVAS'); | ||
402 | const ctx = canvas.getContext('2d'); | ||
403 | // eslint-disable-next-line no-undef | ||
404 | const img = new Image(); | ||
405 | img.crossOrigin = 'Anonymous'; | ||
406 | |||
407 | img.onload = () => { | ||
408 | canvas.height = img.height; | ||
409 | canvas.width = img.width; | ||
410 | ctx.drawImage(img, 0, 0); | ||
411 | |||
412 | const dataURL = canvas.toDataURL(outputFormat); | ||
413 | canvas = null; | ||
414 | callback(dataURL); | ||
415 | }; | ||
416 | |||
417 | img.src = url; | ||
418 | } | ||
419 | }; | ||
diff --git a/src/webview/recipe.js b/src/webview/recipe.js index b0aefd9c1..c6724e35a 100644 --- a/src/webview/recipe.js +++ b/src/webview/recipe.js | |||
@@ -65,7 +65,18 @@ class RecipeController { | |||
65 | } | 65 | } |
66 | 66 | ||
67 | @computed get spellcheckerLanguage() { | 67 | @computed get spellcheckerLanguage() { |
68 | return this.settings.service.spellcheckerLanguage || this.settings.app.spellcheckerLanguage; | 68 | let selected; |
69 | const langs = this.settings.service.spellcheckerLanguage || this.settings.app.spellcheckerLanguage; | ||
70 | if (typeof langs === 'string' && langs.substr(0, 1) === '[') { | ||
71 | // Value is JSON encoded | ||
72 | selected = JSON.parse(langs); | ||
73 | } else if (typeof langs === 'object') { | ||
74 | selected = langs; | ||
75 | } else { | ||
76 | selected = [langs]; | ||
77 | } | ||
78 | |||
79 | return selected; | ||
69 | } | 80 | } |
70 | 81 | ||
71 | cldIdentifier = null; | 82 | cldIdentifier = null; |
@@ -165,11 +176,11 @@ class RecipeController { | |||
165 | 176 | ||
166 | if (this.settings.app.enableSpellchecking) { | 177 | if (this.settings.app.enableSpellchecking) { |
167 | debug('Setting spellchecker language to', this.spellcheckerLanguage); | 178 | debug('Setting spellchecker language to', this.spellcheckerLanguage); |
168 | let { spellcheckerLanguage } = this; | 179 | const { spellcheckerLanguage } = this; |
169 | if (spellcheckerLanguage === 'automatic') { | 180 | if (spellcheckerLanguage.includes('automatic')) { |
170 | this.automaticLanguageDetection(); | 181 | this.automaticLanguageDetection(); |
171 | debug('Found `automatic` locale, falling back to user locale until detected', this.settings.app.locale); | 182 | debug('Found `automatic` locale, falling back to user locale until detected', this.settings.app.locale); |
172 | spellcheckerLanguage = this.settings.app.locale; | 183 | spellcheckerLanguage.push(this.settings.app.locale); |
173 | } else if (this.cldIdentifier) { | 184 | } else if (this.cldIdentifier) { |
174 | this.cldIdentifier.destroy(); | 185 | this.cldIdentifier.destroy(); |
175 | } | 186 | } |
@@ -318,7 +329,10 @@ class RecipeController { | |||
318 | const spellcheckerLocale = getSpellcheckerLocaleByFuzzyIdentifier(findResult.language); | 329 | const spellcheckerLocale = getSpellcheckerLocaleByFuzzyIdentifier(findResult.language); |
319 | debug('Language detected reliably, setting spellchecker language to', spellcheckerLocale); | 330 | debug('Language detected reliably, setting spellchecker language to', spellcheckerLocale); |
320 | if (spellcheckerLocale) { | 331 | if (spellcheckerLocale) { |
321 | switchDict(spellcheckerLocale); | 332 | switchDict([ |
333 | ...this.spellcheckerLanguage, | ||
334 | spellcheckerLocale, | ||
335 | ]); | ||
322 | } | 336 | } |
323 | } | 337 | } |
324 | }, 225)); | 338 | }, 225)); |
diff --git a/src/webview/spellchecker.js b/src/webview/spellchecker.js index a33a506b2..287c9cf11 100644 --- a/src/webview/spellchecker.js +++ b/src/webview/spellchecker.js | |||
@@ -1,53 +1,42 @@ | |||
1 | import { webFrame } from 'electron'; | 1 | import { webFrame } from 'electron'; |
2 | import { SpellCheckHandler } from 'electron-spellchecker'; | ||
3 | import { SPELLCHECKER_LOCALES } from '../i18n/languages'; | 2 | import { SPELLCHECKER_LOCALES } from '../i18n/languages'; |
4 | import setupContextMenu from './contextMenu'; | 3 | import setupContextMenu from './contextMenu'; |
5 | 4 | ||
6 | const debug = require('debug')('Franz:spellchecker'); | 5 | const debug = require('debug')('Franz:spellchecker'); |
7 | 6 | ||
8 | let handler; | ||
9 | let currentDict; | ||
10 | let _isEnabled = false; | 7 | let _isEnabled = false; |
11 | 8 | ||
12 | export async function switchDict(locale) { | 9 | export async function switchDict(locales) { |
13 | try { | 10 | const { platform } = process; |
14 | debug('Trying to load dictionary', locale); | 11 | if (platform === 'darwin') { |
15 | 12 | // MacOS uses the build-in languages which cannot be changed | |
16 | if (!handler) { | 13 | return; |
17 | console.warn('SpellcheckHandler not initialized'); | 14 | } |
18 | |||
19 | return; | ||
20 | } | ||
21 | |||
22 | if (locale === currentDict) { | ||
23 | console.warn('Dictionary is already used', currentDict); | ||
24 | 15 | ||
25 | return; | 16 | try { |
26 | } | 17 | debug('Trying to load dictionary', locales); |
27 | 18 | ||
28 | handler.switchLanguage(locale); | 19 | webFrame.session.setSpellCheckerLanguages([...locales, 'en-US']); |
29 | 20 | ||
30 | debug('Switched dictionary to', locale); | 21 | debug('Switched dictionary to', locales); |
31 | 22 | ||
32 | currentDict = locale; | ||
33 | _isEnabled = true; | 23 | _isEnabled = true; |
34 | } catch (err) { | 24 | } catch (err) { |
35 | console.error(err); | 25 | console.error(err); |
36 | } | 26 | } |
37 | } | 27 | } |
38 | 28 | ||
39 | export default async function initialize(languageCode = 'en-us') { | 29 | export default async function initialize(languages = ['en-us']) { |
40 | try { | 30 | try { |
41 | handler = new SpellCheckHandler(); | ||
42 | setTimeout(() => handler.attachToInput(), 1000); | ||
43 | const locale = languageCode.toLowerCase(); | ||
44 | |||
45 | debug('Init spellchecker'); | 31 | debug('Init spellchecker'); |
46 | 32 | ||
47 | switchDict(locale); | 33 | switchDict([ |
48 | setupContextMenu(handler); | 34 | navigator.language, |
35 | ...languages, | ||
36 | ]); | ||
37 | setupContextMenu(); | ||
49 | 38 | ||
50 | return handler; | 39 | return true; |
51 | } catch (err) { | 40 | } catch (err) { |
52 | console.error(err); | 41 | console.error(err); |
53 | return false; | 42 | return false; |
@@ -60,10 +49,7 @@ export function isEnabled() { | |||
60 | 49 | ||
61 | export function disable() { | 50 | export function disable() { |
62 | if (isEnabled()) { | 51 | if (isEnabled()) { |
63 | handler.unsubscribe(); | 52 | // TODO: How to disable build-in spellchecker? |
64 | webFrame.setSpellCheckProvider(currentDict, { spellCheck: () => true }); | ||
65 | _isEnabled = false; | ||
66 | currentDict = null; | ||
67 | } | 53 | } |
68 | } | 54 | } |
69 | 55 | ||