diff options
39 files changed, 1409 insertions, 180 deletions
diff --git a/.gitignore b/.gitignore index d38c475bf..626cd7ea2 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -12,3 +12,4 @@ yarn-error.log | |||
12 | npm-debug.log* | 12 | npm-debug.log* |
13 | lerna-debug.log | 13 | lerna-debug.log |
14 | uidev/lib | 14 | uidev/lib |
15 | *.tsbuildinfo \ No newline at end of file | ||
diff --git a/.travis.yml b/.travis.yml index 29bdd5ba8..e0fd7b8ae 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -27,6 +27,7 @@ before_script: | |||
27 | - travis_retry npm install node-sass -g | 27 | - travis_retry npm install node-sass -g |
28 | script: | 28 | script: |
29 | - travis_retry travis_wait 100 npm run build | 29 | - travis_retry travis_wait 100 npm run build |
30 | |||
30 | cache: npm | 31 | cache: npm |
31 | 32 | ||
32 | branches: | 33 | branches: |
diff --git a/electron-builder.yml b/electron-builder.yml index 23625c825..330fc64e1 100644 --- a/electron-builder.yml +++ b/electron-builder.yml | |||
@@ -60,4 +60,5 @@ protocols: | |||
60 | 60 | ||
61 | asarUnpack: | 61 | asarUnpack: |
62 | - ./recipes | 62 | - ./recipes |
63 | - ./node_modules/mac-screen-capture-permissions | ||
63 | - ./assets/images/taskbar | 64 | - ./assets/images/taskbar |
diff --git a/package-lock.json b/package-lock.json index 2200d61d1..b1aa4e88d 100644 --- a/package-lock.json +++ b/package-lock.json | |||
@@ -10525,6 +10525,15 @@ | |||
10525 | } | 10525 | } |
10526 | } | 10526 | } |
10527 | }, | 10527 | }, |
10528 | "electron-util": { | ||
10529 | "version": "0.14.0", | ||
10530 | "resolved": "https://registry.npmjs.org/electron-util/-/electron-util-0.14.0.tgz", | ||
10531 | "integrity": "sha512-f8DXlOLrI7aq2S1yRlgx8Dc+Zbq5hlKKyVUnc73HyLEijo8/0KT9Cqlcduy75qwwynVw+cvbuqtqgIlrHLijyw==", | ||
10532 | "requires": { | ||
10533 | "electron-is-dev": "^1.1.0", | ||
10534 | "new-github-issue-url": "^0.2.1" | ||
10535 | } | ||
10536 | }, | ||
10528 | "electron-window-state": { | 10537 | "electron-window-state": { |
10529 | "version": "5.0.3", | 10538 | "version": "5.0.3", |
10530 | "resolved": "https://registry.npmjs.org/electron-window-state/-/electron-window-state-5.0.3.tgz", | 10539 | "resolved": "https://registry.npmjs.org/electron-window-state/-/electron-window-state-5.0.3.tgz", |
@@ -18541,6 +18550,118 @@ | |||
18541 | "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", | 18550 | "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", |
18542 | "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" | 18551 | "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" |
18543 | }, | 18552 | }, |
18553 | "mac-screen-capture-permissions": { | ||
18554 | "version": "1.1.0", | ||
18555 | "resolved": "https://registry.npmjs.org/mac-screen-capture-permissions/-/mac-screen-capture-permissions-1.1.0.tgz", | ||
18556 | "integrity": "sha512-jMRumlB3FScui/7yW+5FqqbuO7CQ0XOJVT5oTsb7W9eRQDhCIpJpIF0XxLVXwq2DIOp0fYsz1LFiBjnyDYULyQ==", | ||
18557 | "requires": { | ||
18558 | "electron-util": "^0.13.0", | ||
18559 | "execa": "^2.0.4", | ||
18560 | "macos-version": "^5.2.0" | ||
18561 | }, | ||
18562 | "dependencies": { | ||
18563 | "cross-spawn": { | ||
18564 | "version": "7.0.2", | ||
18565 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", | ||
18566 | "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==", | ||
18567 | "requires": { | ||
18568 | "path-key": "^3.1.0", | ||
18569 | "shebang-command": "^2.0.0", | ||
18570 | "which": "^2.0.1" | ||
18571 | } | ||
18572 | }, | ||
18573 | "electron-util": { | ||
18574 | "version": "0.13.1", | ||
18575 | "resolved": "https://registry.npmjs.org/electron-util/-/electron-util-0.13.1.tgz", | ||
18576 | "integrity": "sha512-CvOuAyQPaPtnDp7SspwnT1yTb1yynw6yp4LrZCfEJ7TG/kJFiZW9RqMHlCEFWMn3QNoMkNhGVeCvWJV5NsYyuQ==", | ||
18577 | "requires": { | ||
18578 | "electron-is-dev": "^1.1.0", | ||
18579 | "new-github-issue-url": "^0.2.1" | ||
18580 | } | ||
18581 | }, | ||
18582 | "execa": { | ||
18583 | "version": "2.1.0", | ||
18584 | "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", | ||
18585 | "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", | ||
18586 | "requires": { | ||
18587 | "cross-spawn": "^7.0.0", | ||
18588 | "get-stream": "^5.0.0", | ||
18589 | "is-stream": "^2.0.0", | ||
18590 | "merge-stream": "^2.0.0", | ||
18591 | "npm-run-path": "^3.0.0", | ||
18592 | "onetime": "^5.1.0", | ||
18593 | "p-finally": "^2.0.0", | ||
18594 | "signal-exit": "^3.0.2", | ||
18595 | "strip-final-newline": "^2.0.0" | ||
18596 | } | ||
18597 | }, | ||
18598 | "get-stream": { | ||
18599 | "version": "5.1.0", | ||
18600 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", | ||
18601 | "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", | ||
18602 | "requires": { | ||
18603 | "pump": "^3.0.0" | ||
18604 | } | ||
18605 | }, | ||
18606 | "is-stream": { | ||
18607 | "version": "2.0.0", | ||
18608 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", | ||
18609 | "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" | ||
18610 | }, | ||
18611 | "merge-stream": { | ||
18612 | "version": "2.0.0", | ||
18613 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", | ||
18614 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" | ||
18615 | }, | ||
18616 | "npm-run-path": { | ||
18617 | "version": "3.1.0", | ||
18618 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", | ||
18619 | "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", | ||
18620 | "requires": { | ||
18621 | "path-key": "^3.0.0" | ||
18622 | } | ||
18623 | }, | ||
18624 | "onetime": { | ||
18625 | "version": "5.1.0", | ||
18626 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", | ||
18627 | "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", | ||
18628 | "requires": { | ||
18629 | "mimic-fn": "^2.1.0" | ||
18630 | } | ||
18631 | }, | ||
18632 | "p-finally": { | ||
18633 | "version": "2.0.1", | ||
18634 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", | ||
18635 | "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" | ||
18636 | }, | ||
18637 | "path-key": { | ||
18638 | "version": "3.1.1", | ||
18639 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", | ||
18640 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" | ||
18641 | }, | ||
18642 | "shebang-command": { | ||
18643 | "version": "2.0.0", | ||
18644 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", | ||
18645 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", | ||
18646 | "requires": { | ||
18647 | "shebang-regex": "^3.0.0" | ||
18648 | } | ||
18649 | }, | ||
18650 | "shebang-regex": { | ||
18651 | "version": "3.0.0", | ||
18652 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", | ||
18653 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" | ||
18654 | }, | ||
18655 | "which": { | ||
18656 | "version": "2.0.2", | ||
18657 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", | ||
18658 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", | ||
18659 | "requires": { | ||
18660 | "isexe": "^2.0.0" | ||
18661 | } | ||
18662 | } | ||
18663 | } | ||
18664 | }, | ||
18544 | "macos-notification-state": { | 18665 | "macos-notification-state": { |
18545 | "version": "1.3.1", | 18666 | "version": "1.3.1", |
18546 | "resolved": "https://registry.npmjs.org/macos-notification-state/-/macos-notification-state-1.3.1.tgz", | 18667 | "resolved": "https://registry.npmjs.org/macos-notification-state/-/macos-notification-state-1.3.1.tgz", |
@@ -18556,6 +18677,14 @@ | |||
18556 | "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==", | 18677 | "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==", |
18557 | "dev": true | 18678 | "dev": true |
18558 | }, | 18679 | }, |
18680 | "macos-version": { | ||
18681 | "version": "5.2.0", | ||
18682 | "resolved": "https://registry.npmjs.org/macos-version/-/macos-version-5.2.0.tgz", | ||
18683 | "integrity": "sha512-egt1bqVE1evUjCup2QN2F0g42AuVcumdM31xNbABz+uXquYPzWP4OrqDm+HpCfM+6t4JzWrzABQW+MZM+FW+Jg==", | ||
18684 | "requires": { | ||
18685 | "semver": "^5.6.0" | ||
18686 | } | ||
18687 | }, | ||
18559 | "macroable": { | 18688 | "macroable": { |
18560 | "version": "1.0.0", | 18689 | "version": "1.0.0", |
18561 | "resolved": "https://registry.npmjs.org/macroable/-/macroable-1.0.0.tgz", | 18690 | "resolved": "https://registry.npmjs.org/macroable/-/macroable-1.0.0.tgz", |
@@ -18685,9 +18814,9 @@ | |||
18685 | } | 18814 | } |
18686 | }, | 18815 | }, |
18687 | "marked": { | 18816 | "marked": { |
18688 | "version": "0.7.0", | 18817 | "version": "0.6.1", |
18689 | "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", | 18818 | "resolved": "https://registry.npmjs.org/marked/-/marked-0.6.1.tgz", |
18690 | "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" | 18819 | "integrity": "sha512-+H0L3ibcWhAZE02SKMqmvYsErLo4EAVJxu5h3bHBBDvvjeWXtl92rGUSBYHL2++5Y+RSNgl8dYOAXcYe7lp1fA==" |
18691 | }, | 18820 | }, |
18692 | "matchdep": { | 18821 | "matchdep": { |
18693 | "version": "2.0.0", | 18822 | "version": "2.0.0", |
@@ -18990,8 +19119,7 @@ | |||
18990 | "mimic-fn": { | 19119 | "mimic-fn": { |
18991 | "version": "2.1.0", | 19120 | "version": "2.1.0", |
18992 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", | 19121 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", |
18993 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", | 19122 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" |
18994 | "dev": true | ||
18995 | }, | 19123 | }, |
18996 | "mimic-response": { | 19124 | "mimic-response": { |
18997 | "version": "1.0.1", | 19125 | "version": "1.0.1", |
@@ -19480,6 +19608,11 @@ | |||
19480 | "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", | 19608 | "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", |
19481 | "dev": true | 19609 | "dev": true |
19482 | }, | 19610 | }, |
19611 | "new-github-issue-url": { | ||
19612 | "version": "0.2.1", | ||
19613 | "resolved": "https://registry.npmjs.org/new-github-issue-url/-/new-github-issue-url-0.2.1.tgz", | ||
19614 | "integrity": "sha512-md4cGoxuT4T4d/HDOXbrUHkTKrp/vp+m3aOA7XXVYwNsUNMK49g3SQicTSeV5GIz/5QVGAeYRAOlyp9OvlgsYA==" | ||
19615 | }, | ||
19483 | "next-tick": { | 19616 | "next-tick": { |
19484 | "version": "1.0.0", | 19617 | "version": "1.0.0", |
19485 | "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", | 19618 | "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", |
@@ -24962,6 +25095,11 @@ | |||
24962 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", | 25095 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", |
24963 | "dev": true | 25096 | "dev": true |
24964 | }, | 25097 | }, |
25098 | "strip-final-newline": { | ||
25099 | "version": "2.0.0", | ||
25100 | "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", | ||
25101 | "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" | ||
25102 | }, | ||
24965 | "strip-indent": { | 25103 | "strip-indent": { |
24966 | "version": "2.0.0", | 25104 | "version": "2.0.0", |
24967 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", | 25105 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", |
diff --git a/package.json b/package.json index c267f6ae2..5c9be8488 100644 --- a/package.json +++ b/package.json | |||
@@ -77,6 +77,7 @@ | |||
77 | "electron-react-titlebar": "0.8.2", | 77 | "electron-react-titlebar": "0.8.2", |
78 | "electron-spellchecker": "2.2.1", | 78 | "electron-spellchecker": "2.2.1", |
79 | "electron-updater": "4.2.5", | 79 | "electron-updater": "4.2.5", |
80 | "electron-util": "0.14.0", | ||
80 | "electron-window-state": "5.0.3", | 81 | "electron-window-state": "5.0.3", |
81 | "fs-extra": "7.0.1", | 82 | "fs-extra": "7.0.1", |
82 | "gulp-csso": "3.0.1", | 83 | "gulp-csso": "3.0.1", |
@@ -85,8 +86,10 @@ | |||
85 | "gulp-uglify": "3.0.2", | 86 | "gulp-uglify": "3.0.2", |
86 | "hex-to-rgba": "1.0.2", | 87 | "hex-to-rgba": "1.0.2", |
87 | "jsonwebtoken": "8.5.1", | 88 | "jsonwebtoken": "8.5.1", |
88 | "lodash": "4.17.15", | 89 | "lodash": "^4.17.4", |
89 | "marked": "0.7.0", | 90 | "mac-screen-capture-permissions": "1.1.0", |
91 | "macos-version": "5.2.0", | ||
92 | "marked": "0.6.1", | ||
90 | "mdi": "^1.9.33", | 93 | "mdi": "^1.9.33", |
91 | "mime-types": "2.1.25", | 94 | "mime-types": "2.1.25", |
92 | "mobx": "5.15.0", | 95 | "mobx": "5.15.0", |
@@ -138,7 +141,7 @@ | |||
138 | "@babel/preset-react": "7.7.4", | 141 | "@babel/preset-react": "7.7.4", |
139 | "@babel/register": "7.7.4", | 142 | "@babel/register": "7.7.4", |
140 | "@types/classnames": "^2.2.6", | 143 | "@types/classnames": "^2.2.6", |
141 | "@types/color": "^3.0.0", | 144 | "@types/color": "3.0.0", |
142 | "@types/color-convert": "^1.9.0", | 145 | "@types/color-convert": "^1.9.0", |
143 | "@types/jss": "^9.5.7", | 146 | "@types/jss": "^9.5.7", |
144 | "@types/lodash": "4.14.149", | 147 | "@types/lodash": "4.14.149", |
diff --git a/packages/theme/package-lock.json b/packages/theme/package-lock.json index f74af2f24..85a87cf04 100644 --- a/packages/theme/package-lock.json +++ b/packages/theme/package-lock.json | |||
@@ -1,6 +1,6 @@ | |||
1 | { | 1 | { |
2 | "name": "@meetfranz/theme", | 2 | "name": "@meetfranz/theme", |
3 | "version": "1.0.4", | 3 | "version": "1.0.14", |
4 | "lockfileVersion": 1, | 4 | "lockfileVersion": 1, |
5 | "requires": true, | 5 | "requires": true, |
6 | "dependencies": { | 6 | "dependencies": { |
diff --git a/packages/theme/src/themes/dark/index.ts b/packages/theme/src/themes/dark/index.ts index 30cc19d99..b436d92f9 100644 --- a/packages/theme/src/themes/dark/index.ts +++ b/packages/theme/src/themes/dark/index.ts | |||
@@ -65,7 +65,7 @@ export const selectOptionItemHoverColor = selectColor; | |||
65 | export const selectSearchColor = inputBackground; | 65 | export const selectSearchColor = inputBackground; |
66 | 66 | ||
67 | // Modal | 67 | // Modal |
68 | export const colorModalOverlayBackground = color(legacyStyles.darkThemeBlack).alpha(0.8).rgb().string(); | 68 | export const colorModalOverlayBackground = color(legacyStyles.darkThemeBlack).alpha(0.9).rgb().string(); |
69 | export const colorModalBackground = legacyStyles.darkThemeGrayDark; | 69 | export const colorModalBackground = legacyStyles.darkThemeGrayDark; |
70 | 70 | ||
71 | // Services | 71 | // Services |
diff --git a/packages/theme/src/themes/default/index.ts b/packages/theme/src/themes/default/index.ts index edf56f21e..f8dc36574 100644 --- a/packages/theme/src/themes/default/index.ts +++ b/packages/theme/src/themes/default/index.ts | |||
@@ -1,7 +1,6 @@ | |||
1 | import color from 'color'; | 1 | import color from 'color'; |
2 | import { cloneDeep } from 'lodash'; | 2 | import { cloneDeep } from 'lodash'; |
3 | 3 | ||
4 | import { darkgreen } from 'color-name'; | ||
5 | import * as legacyStyles from '../legacy'; | 4 | import * as legacyStyles from '../legacy'; |
6 | 5 | ||
7 | export interface IStyleTypes { | 6 | export interface IStyleTypes { |
@@ -145,7 +144,7 @@ export const badgeFontSize = uiFontSize - 2; | |||
145 | export const badgeBorderRadius = 50; | 144 | export const badgeBorderRadius = 50; |
146 | 145 | ||
147 | // Modal | 146 | // Modal |
148 | export const colorModalOverlayBackground = color('#000').alpha(0.5).rgb().string(); | 147 | export const colorModalOverlayBackground = color('#000').alpha(0.8).rgb().string(); |
149 | export const colorModalBackground = colorContentBackground; | 148 | export const colorModalBackground = colorContentBackground; |
150 | 149 | ||
151 | // Services | 150 | // Services |
diff --git a/src/components/services/content/ConnectionLostBanner.js b/src/components/services/content/ConnectionLostBanner.js new file mode 100644 index 000000000..9609a65b1 --- /dev/null +++ b/src/components/services/content/ConnectionLostBanner.js | |||
@@ -0,0 +1,119 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | ||
4 | import injectSheet from 'react-jss'; | ||
5 | import { Icon } from '@meetfranz/ui'; | ||
6 | import { intlShape, defineMessages } from 'react-intl'; | ||
7 | |||
8 | import { | ||
9 | mdiAlert, | ||
10 | } from '@mdi/js'; | ||
11 | import { LIVE_API_WEBSITE } from '../../../config'; | ||
12 | // import { Button } from '@meetfranz/forms'; | ||
13 | |||
14 | const messages = defineMessages({ | ||
15 | text: { | ||
16 | id: 'connectionLostBanner.message', | ||
17 | defaultMessage: '!!!Oh no! Franz lost the connection to {name}.', | ||
18 | }, | ||
19 | moreInformation: { | ||
20 | id: 'connectionLostBanner.informationLink', | ||
21 | defaultMessage: '!!!What happened?', | ||
22 | }, | ||
23 | cta: { | ||
24 | id: 'connectionLostBanner.cta', | ||
25 | defaultMessage: '!!!Reload Service', | ||
26 | }, | ||
27 | }); | ||
28 | |||
29 | const styles = theme => ({ | ||
30 | root: { | ||
31 | background: theme.colorBackground, | ||
32 | borderRadius: theme.borderRadius, | ||
33 | position: 'absolute', | ||
34 | zIndex: 300, | ||
35 | height: 50, | ||
36 | display: 'flex', | ||
37 | flexDirection: 'row', | ||
38 | alignItems: 'center', | ||
39 | bottom: 10, | ||
40 | right: 10, | ||
41 | justifyContent: 'center', | ||
42 | padding: 10, | ||
43 | fontSize: 12, | ||
44 | }, | ||
45 | link: { | ||
46 | display: 'inline-flex', | ||
47 | opacity: 0.7, | ||
48 | }, | ||
49 | button: { | ||
50 | transition: 'opacity 0.25s', | ||
51 | color: theme.colorText, | ||
52 | border: [1, 'solid', theme.colorText], | ||
53 | borderRadius: theme.borderRadiusSmall, | ||
54 | padding: 4, | ||
55 | fontSize: 12, | ||
56 | marginLeft: 15, | ||
57 | |||
58 | '&:hover': { | ||
59 | opacity: 0.8, | ||
60 | }, | ||
61 | }, | ||
62 | icon: { | ||
63 | marginRight: 10, | ||
64 | fill: theme.styleTypes.danger.accent, | ||
65 | }, | ||
66 | }); | ||
67 | |||
68 | @injectSheet(styles) @observer | ||
69 | class ConnectionLostBanner extends Component { | ||
70 | static propTypes = { | ||
71 | classes: PropTypes.object.isRequired, | ||
72 | name: PropTypes.string.isRequired, | ||
73 | reload: PropTypes.func.isRequired, | ||
74 | } | ||
75 | |||
76 | static contextTypes = { | ||
77 | intl: intlShape, | ||
78 | }; | ||
79 | |||
80 | inputRef = React.createRef(); | ||
81 | |||
82 | render() { | ||
83 | const { | ||
84 | classes, | ||
85 | name, | ||
86 | reload, | ||
87 | } = this.props; | ||
88 | |||
89 | const { intl } = this.context; | ||
90 | |||
91 | return ( | ||
92 | <div className={classes.root}> | ||
93 | <Icon | ||
94 | icon={mdiAlert} | ||
95 | className={classes.icon} | ||
96 | /> | ||
97 | <p> | ||
98 | {intl.formatMessage(messages.text, { name })} | ||
99 | <br /> | ||
100 | <a | ||
101 | href={`${LIVE_API_WEBSITE}/support#what-does-franz-lost-the-connection-to-service-mean`} | ||
102 | className={classes.link} | ||
103 | > | ||
104 | {intl.formatMessage(messages.moreInformation)} | ||
105 | </a> | ||
106 | </p> | ||
107 | <button | ||
108 | type="button" | ||
109 | className={classes.button} | ||
110 | onClick={reload} | ||
111 | > | ||
112 | {intl.formatMessage(messages.cta)} | ||
113 | </button> | ||
114 | </div> | ||
115 | ); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | export default ConnectionLostBanner; | ||
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js index f6832038a..d91016c71 100644 --- a/src/components/services/content/ServiceView.js +++ b/src/components/services/content/ServiceView.js | |||
@@ -193,7 +193,7 @@ export default @inject('stores', 'actions') @observer class ServiceView extends | |||
193 | </Fragment> | 193 | </Fragment> |
194 | ) : ( | 194 | ) : ( |
195 | <> | 195 | <> |
196 | {!service.isHibernating ? ( | 196 | {(!service.isHibernating || service.disableHibernation) ? ( |
197 | <> | 197 | <> |
198 | {showNavBar && ( | 198 | {showNavBar && ( |
199 | <WebControlsScreen service={service} /> | 199 | <WebControlsScreen service={service} /> |
@@ -203,6 +203,12 @@ export default @inject('stores', 'actions') @observer class ServiceView extends | |||
203 | setWebviewReference={setWebviewReference} | 203 | setWebviewReference={setWebviewReference} |
204 | detachService={detachService} | 204 | detachService={detachService} |
205 | /> | 205 | /> |
206 | {/* {service.lostRecipeConnection && ( | ||
207 | <ConnectionLostBanner | ||
208 | name={service.name} | ||
209 | reload={reload} | ||
210 | /> | ||
211 | )} */} | ||
206 | </> | 212 | </> |
207 | ) : ( | 213 | ) : ( |
208 | <div> | 214 | <div> |
diff --git a/src/components/services/tabs/TabItem.js b/src/components/services/tabs/TabItem.js index 36338a910..ea7a66a62 100644 --- a/src/components/services/tabs/TabItem.js +++ b/src/components/services/tabs/TabItem.js | |||
@@ -145,7 +145,7 @@ class TabItem extends Component { | |||
145 | • | 145 | • |
146 | </span> | 146 | </span> |
147 | )} | 147 | )} |
148 | {service.isHibernating && ( | 148 | {service.isHibernating && !service.disableHibernation && ( |
149 | <span className="tab-item__message-count hibernating"> | 149 | <span className="tab-item__message-count hibernating"> |
150 | • | 150 | • |
151 | </span> | 151 | </span> |
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index bb4f4a76f..4fd1f99ef 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js | |||
@@ -94,6 +94,10 @@ const messages = defineMessages({ | |||
94 | id: 'settings.service.form.isMutedInfo', | 94 | id: 'settings.service.form.isMutedInfo', |
95 | defaultMessage: '!!!When disabled, all notification sounds and audio playback are muted', | 95 | defaultMessage: '!!!When disabled, all notification sounds and audio playback are muted', |
96 | }, | 96 | }, |
97 | disableHibernationInfo: { | ||
98 | id: 'settings.service.form.disableHibernationInfo', | ||
99 | defaultMessage: '!!!You currently have hibernation enabled but you can disable hibernation for individual services using this option.', | ||
100 | }, | ||
97 | headlineNotifications: { | 101 | headlineNotifications: { |
98 | id: 'settings.service.form.headlineNotifications', | 102 | id: 'settings.service.form.headlineNotifications', |
99 | defaultMessage: '!!!Notifications', | 103 | defaultMessage: '!!!Notifications', |
@@ -154,6 +158,7 @@ export default @observer class EditServiceForm extends Component { | |||
154 | isProxyFeatureEnabled: PropTypes.bool.isRequired, | 158 | isProxyFeatureEnabled: PropTypes.bool.isRequired, |
155 | isServiceProxyIncludedInCurrentPlan: PropTypes.bool.isRequired, | 159 | isServiceProxyIncludedInCurrentPlan: PropTypes.bool.isRequired, |
156 | isSpellcheckerIncludedInCurrentPlan: PropTypes.bool.isRequired, | 160 | isSpellcheckerIncludedInCurrentPlan: PropTypes.bool.isRequired, |
161 | isHibernationFeatureActive: PropTypes.bool.isRequired, | ||
157 | }; | 162 | }; |
158 | 163 | ||
159 | static defaultProps = { | 164 | static defaultProps = { |
@@ -219,6 +224,7 @@ export default @observer class EditServiceForm extends Component { | |||
219 | isProxyFeatureEnabled, | 224 | isProxyFeatureEnabled, |
220 | isServiceProxyIncludedInCurrentPlan, | 225 | isServiceProxyIncludedInCurrentPlan, |
221 | isSpellcheckerIncludedInCurrentPlan, | 226 | isSpellcheckerIncludedInCurrentPlan, |
227 | isHibernationFeatureActive, | ||
222 | } = this.props; | 228 | } = this.props; |
223 | const { intl } = this.context; | 229 | const { intl } = this.context; |
224 | 230 | ||
@@ -365,6 +371,14 @@ export default @observer class EditServiceForm extends Component { | |||
365 | <div className="settings__settings-group"> | 371 | <div className="settings__settings-group"> |
366 | <h3>{intl.formatMessage(messages.headlineGeneral)}</h3> | 372 | <h3>{intl.formatMessage(messages.headlineGeneral)}</h3> |
367 | <Toggle field={form.$('isEnabled')} /> | 373 | <Toggle field={form.$('isEnabled')} /> |
374 | {isHibernationFeatureActive && ( | ||
375 | <> | ||
376 | <Toggle field={form.$('disableHibernation')} /> | ||
377 | <p className="settings__help"> | ||
378 | {intl.formatMessage(messages.disableHibernationInfo)} | ||
379 | </p> | ||
380 | </> | ||
381 | )} | ||
368 | <Toggle field={form.$('isDarkModeEnabled')} /> | 382 | <Toggle field={form.$('isDarkModeEnabled')} /> |
369 | {form.$('isDarkModeEnabled').value | 383 | {form.$('isDarkModeEnabled').value |
370 | && ( | 384 | && ( |
diff --git a/src/components/ui/FeatureList.js b/src/components/ui/FeatureList.js index f1039709c..dbc2a9078 100644 --- a/src/components/ui/FeatureList.js +++ b/src/components/ui/FeatureList.js | |||
@@ -66,6 +66,10 @@ const messages = defineMessages({ | |||
66 | id: 'pricing.features.adFree', | 66 | id: 'pricing.features.adFree', |
67 | defaultMessage: '!!!Forever ad-free', | 67 | defaultMessage: '!!!Forever ad-free', |
68 | }, | 68 | }, |
69 | appDelayEnabled: { | ||
70 | id: 'pricing.features.appDelaysEnabled', | ||
71 | defaultMessage: '!!!Occasional Waiting Screens', | ||
72 | }, | ||
69 | }); | 73 | }); |
70 | 74 | ||
71 | export class FeatureList extends Component { | 75 | export class FeatureList extends Component { |
@@ -96,6 +100,7 @@ export class FeatureList extends Component { | |||
96 | const features = []; | 100 | const features = []; |
97 | if (plan === PLANS.FREE) { | 101 | if (plan === PLANS.FREE) { |
98 | features.push( | 102 | features.push( |
103 | messages.appDelayEnabled, | ||
99 | messages.upToThreeServices, | 104 | messages.upToThreeServices, |
100 | messages.availableRecipes, | 105 | messages.availableRecipes, |
101 | messages.accountSync, | 106 | messages.accountSync, |
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js index 560068efc..14c1ef41e 100644 --- a/src/containers/settings/EditServiceScreen.js +++ b/src/containers/settings/EditServiceScreen.js | |||
@@ -33,6 +33,10 @@ const messages = defineMessages({ | |||
33 | id: 'settings.service.form.enableService', | 33 | id: 'settings.service.form.enableService', |
34 | defaultMessage: '!!!Enable service', | 34 | defaultMessage: '!!!Enable service', |
35 | }, | 35 | }, |
36 | disableHibernation: { | ||
37 | id: 'settings.service.form.disableHibernation', | ||
38 | defaultMessage: '!!!Disable hibernation', | ||
39 | }, | ||
36 | enableNotification: { | 40 | enableNotification: { |
37 | id: 'settings.service.form.enableNotification', | 41 | id: 'settings.service.form.enableNotification', |
38 | defaultMessage: '!!!Enable Notifications', | 42 | defaultMessage: '!!!Enable Notifications', |
@@ -134,8 +138,11 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
134 | 138 | ||
135 | const { | 139 | const { |
136 | stores, | 140 | stores, |
141 | router, | ||
137 | } = this.props; | 142 | } = this.props; |
138 | 143 | ||
144 | const { action } = router.params; | ||
145 | |||
139 | let defaultSpellcheckerLanguage = SPELLCHECKER_LOCALES[stores.settings.app.spellcheckerLanguage]; | 146 | let defaultSpellcheckerLanguage = SPELLCHECKER_LOCALES[stores.settings.app.spellcheckerLanguage]; |
140 | 147 | ||
141 | if (stores.settings.app.spellcheckerLanguage === 'automatic') { | 148 | if (stores.settings.app.spellcheckerLanguage === 'automatic') { |
@@ -160,6 +167,11 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
160 | value: service.isEnabled, | 167 | value: service.isEnabled, |
161 | default: true, | 168 | default: true, |
162 | }, | 169 | }, |
170 | disableHibernation: { | ||
171 | label: intl.formatMessage(messages.disableHibernation), | ||
172 | value: action !== 'edit' ? false : service.disableHibernation, | ||
173 | default: false, | ||
174 | }, | ||
163 | isNotificationEnabled: { | 175 | isNotificationEnabled: { |
164 | label: intl.formatMessage(messages.enableNotification), | 176 | label: intl.formatMessage(messages.enableNotification), |
165 | value: service.isNotificationEnabled, | 177 | value: service.isNotificationEnabled, |
@@ -327,7 +339,9 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
327 | } | 339 | } |
328 | 340 | ||
329 | render() { | 341 | render() { |
330 | const { recipes, services, user } = this.props.stores; | 342 | const { |
343 | recipes, services, user, settings, | ||
344 | } = this.props.stores; | ||
331 | const { action } = this.props.router.params; | 345 | const { action } = this.props.router.params; |
332 | 346 | ||
333 | let recipe; | 347 | let recipe; |
@@ -381,6 +395,7 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
381 | isProxyFeatureEnabled={proxyFeature.isEnabled} | 395 | isProxyFeatureEnabled={proxyFeature.isEnabled} |
382 | isServiceProxyIncludedInCurrentPlan={proxyFeature.isIncludedInCurrentPlan} | 396 | isServiceProxyIncludedInCurrentPlan={proxyFeature.isIncludedInCurrentPlan} |
383 | isSpellcheckerIncludedInCurrentPlan={spellcheckerFeature.isIncludedInCurrentPlan} | 397 | isSpellcheckerIncludedInCurrentPlan={spellcheckerFeature.isIncludedInCurrentPlan} |
398 | isHibernationFeatureActive={settings.app.hibernate} | ||
384 | /> | 399 | /> |
385 | </ErrorBoundary> | 400 | </ErrorBoundary> |
386 | ); | 401 | ); |
diff --git a/src/electron/macOSPermissions.js b/src/electron/macOSPermissions.js new file mode 100644 index 000000000..4ba6a7619 --- /dev/null +++ b/src/electron/macOSPermissions.js | |||
@@ -0,0 +1,14 @@ | |||
1 | import { systemPreferences } from 'electron'; | ||
2 | import { | ||
3 | hasScreenCapturePermission, | ||
4 | hasPromptedForPermission, | ||
5 | } from 'mac-screen-capture-permissions'; | ||
6 | |||
7 | export default function () { | ||
8 | systemPreferences.askForMediaAccess('camera'); | ||
9 | systemPreferences.askForMediaAccess('microphone'); | ||
10 | |||
11 | if (!hasPromptedForPermission()) { | ||
12 | hasScreenCapturePermission(); | ||
13 | } | ||
14 | } | ||
diff --git a/src/features/announcements/components/AnnouncementScreen.js b/src/features/announcements/components/AnnouncementScreen.js index 38de2dbc8..2f25e7139 100644 --- a/src/features/announcements/components/AnnouncementScreen.js +++ b/src/features/announcements/components/AnnouncementScreen.js | |||
@@ -192,6 +192,11 @@ class AnnouncementScreen extends Component { | |||
192 | stores: PropTypes.shape({ | 192 | stores: PropTypes.shape({ |
193 | ui: PropTypes.instanceOf(UIStore).isRequired, | 193 | ui: PropTypes.instanceOf(UIStore).isRequired, |
194 | }).isRequired, | 194 | }).isRequired, |
195 | actions: PropTypes.shape({ | ||
196 | app: PropTypes.shape({ | ||
197 | openExternalUrl: PropTypes.func.isRequired, | ||
198 | }).isRequired, | ||
199 | }).isRequired, | ||
195 | }; | 200 | }; |
196 | 201 | ||
197 | static contextTypes = { | 202 | static contextTypes = { |
@@ -199,7 +204,7 @@ class AnnouncementScreen extends Component { | |||
199 | }; | 204 | }; |
200 | 205 | ||
201 | render() { | 206 | render() { |
202 | const { classes, stores } = this.props; | 207 | const { classes, stores, actions } = this.props; |
203 | const { intl } = this.context; | 208 | const { intl } = this.context; |
204 | const { changelog, announcement } = announcementsStore; | 209 | const { changelog, announcement } = announcementsStore; |
205 | const themeImage = stores.ui.isDarkThemeActive ? 'dark' : 'light'; | 210 | const themeImage = stores.ui.isDarkThemeActive ? 'dark' : 'light'; |
@@ -223,14 +228,23 @@ class AnnouncementScreen extends Component { | |||
223 | __html: marked(announcement.main.text, markedOptions), | 228 | __html: marked(announcement.main.text, markedOptions), |
224 | }} | 229 | }} |
225 | /> | 230 | /> |
226 | <div className={classes.mainCtaButton}> | 231 | {(announcement.main.cta.label || announcement.main.cta.href) && ( |
227 | <Button | 232 | <div className={classes.mainCtaButton}> |
228 | label={announcement.main.cta.label} | 233 | <Button |
229 | onClick={() => { | 234 | label={announcement.main.cta.label} |
230 | window.location.href = `#${announcement.main.cta.href}`; | 235 | onClick={() => { |
231 | }} | 236 | const { |
232 | /> | 237 | href, |
233 | </div> | 238 | } = announcement.main.cta; |
239 | if (announcement.main.cta.href.startsWith('http')) { | ||
240 | actions.app.openExternalUrl({ url: href }); | ||
241 | } else { | ||
242 | window.location.href = `#${href}`; | ||
243 | } | ||
244 | }} | ||
245 | /> | ||
246 | </div> | ||
247 | )} | ||
234 | </div> | 248 | </div> |
235 | </div> | 249 | </div> |
236 | </div> | 250 | </div> |
@@ -250,7 +264,14 @@ class AnnouncementScreen extends Component { | |||
250 | <Button | 264 | <Button |
251 | label={announcement.spotlight.cta.label} | 265 | label={announcement.spotlight.cta.label} |
252 | onClick={() => { | 266 | onClick={() => { |
253 | window.location.href = `#${announcement.spotlight.cta.href}`; | 267 | const { |
268 | href, | ||
269 | } = announcement.spotlight.cta; | ||
270 | if (announcement.spotlight.cta.href.startsWith('http')) { | ||
271 | actions.app.openExternalUrl({ url: href }); | ||
272 | } else { | ||
273 | window.location.href = `#${href}`; | ||
274 | } | ||
254 | }} | 275 | }} |
255 | /> | 276 | /> |
256 | </div> | 277 | </div> |
diff --git a/src/features/planSelection/components/PlanItem.js b/src/features/planSelection/components/PlanItem.js index ec061377b..3855fedf1 100644 --- a/src/features/planSelection/components/PlanItem.js +++ b/src/features/planSelection/components/PlanItem.js | |||
@@ -49,6 +49,7 @@ const styles = theme => ({ | |||
49 | priceWrapper: { | 49 | priceWrapper: { |
50 | height: 50, | 50 | height: 50, |
51 | marginBottom: 0, | 51 | marginBottom: 0, |
52 | marginTop: ({ text }) => (!text ? 15 : 0), | ||
52 | }, | 53 | }, |
53 | price: { | 54 | price: { |
54 | fontSize: 50, | 55 | fontSize: 50, |
@@ -64,7 +65,7 @@ const styles = theme => ({ | |||
64 | cta: { | 65 | cta: { |
65 | background: theme.styleTypes.primary.accent, | 66 | background: theme.styleTypes.primary.accent, |
66 | color: theme.styleTypes.primary.contrast, | 67 | color: theme.styleTypes.primary.contrast, |
67 | margin: [40, 'auto', 0, 'auto'], | 68 | margin: [30, 'auto', 0, 'auto'], |
68 | }, | 69 | }, |
69 | divider: { | 70 | divider: { |
70 | width: 40, | 71 | width: 40, |
@@ -77,10 +78,14 @@ const styles = theme => ({ | |||
77 | background: color(theme.styleTypes.primary.accent).darken(0.25).hex(), | 78 | background: color(theme.styleTypes.primary.accent).darken(0.25).hex(), |
78 | color: theme.styleTypes.primary.contrast, | 79 | color: theme.styleTypes.primary.contrast, |
79 | position: 'relative', | 80 | position: 'relative', |
81 | height: 'auto', | ||
80 | }, | 82 | }, |
81 | content: { | 83 | content: { |
82 | padding: [10, 20, 20], | 84 | padding: [10, 20, 20], |
83 | background: '#EFEFEF', | 85 | background: '#EFEFEF', |
86 | display: 'flex', | ||
87 | flexDirection: 'column', | ||
88 | justifyContent: 'space-between', | ||
84 | }, | 89 | }, |
85 | simpleCTA: { | 90 | simpleCTA: { |
86 | background: 'none', | 91 | background: 'none', |
@@ -167,10 +172,14 @@ export default @observer @injectSheet(styles) class PlanItem extends Component { | |||
167 | </div> | 172 | </div> |
168 | )} | 173 | )} |
169 | <H2 className={classes.planName}>{name}</H2> | 174 | <H2 className={classes.planName}>{name}</H2> |
170 | <p className={classes.text}> | 175 | {text && ( |
171 | {text} | 176 | <> |
172 | </p> | 177 | <p className={classes.text}> |
173 | <hr className={classes.divider} /> | 178 | {text} |
179 | </p> | ||
180 | <hr className={classes.divider} /> | ||
181 | </> | ||
182 | )} | ||
174 | <p className={classes.priceWrapper}> | 183 | <p className={classes.priceWrapper}> |
175 | <span className={classes.currency}>{currency}</span> | 184 | <span className={classes.currency}>{currency}</span> |
176 | <span className={classes.price}> | 185 | <span className={classes.price}> |
diff --git a/src/features/planSelection/components/PlanSelection.js b/src/features/planSelection/components/PlanSelection.js index 4bf5238dd..6f0dd30ad 100644 --- a/src/features/planSelection/components/PlanSelection.js +++ b/src/features/planSelection/components/PlanSelection.js | |||
@@ -6,7 +6,7 @@ import { defineMessages, intlShape } from 'react-intl'; | |||
6 | import { H1, H2, Icon } from '@meetfranz/ui'; | 6 | import { H1, H2, Icon } from '@meetfranz/ui'; |
7 | import color from 'color'; | 7 | import color from 'color'; |
8 | 8 | ||
9 | import { mdiRocket, mdiArrowRight } from '@mdi/js'; | 9 | import { mdiArrowRight } from '@mdi/js'; |
10 | import PlanItem from './PlanItem'; | 10 | import PlanItem from './PlanItem'; |
11 | import { i18nPlanName } from '../../../helpers/plan-helpers'; | 11 | import { i18nPlanName } from '../../../helpers/plan-helpers'; |
12 | import { PLANS } from '../../../config'; | 12 | import { PLANS } from '../../../config'; |
@@ -79,10 +79,10 @@ const styles = theme => ({ | |||
79 | overflowY: 'scroll', | 79 | overflowY: 'scroll', |
80 | }, | 80 | }, |
81 | container: { | 81 | container: { |
82 | width: '80%', | 82 | // width: '80%', |
83 | height: 'auto', | 83 | height: 'auto', |
84 | background: theme.styleTypes.primary.accent, | 84 | // background: theme.styleTypes.primary.accent, |
85 | padding: 40, | 85 | // padding: 40, |
86 | borderRadius: theme.borderRadius, | 86 | borderRadius: theme.borderRadius, |
87 | maxWidth: 1000, | 87 | maxWidth: 1000, |
88 | 88 | ||
@@ -104,23 +104,6 @@ const styles = theme => ({ | |||
104 | boxShadow: [0, 2, 30, color('#000').alpha(0.1).rgb().string()], | 104 | boxShadow: [0, 2, 30, color('#000').alpha(0.1).rgb().string()], |
105 | }, | 105 | }, |
106 | }, | 106 | }, |
107 | bigIcon: { | ||
108 | background: theme.styleTypes.danger.accent, | ||
109 | width: 120, | ||
110 | height: 120, | ||
111 | display: 'flex', | ||
112 | alignItems: 'center', | ||
113 | borderRadius: '100%', | ||
114 | justifyContent: 'center', | ||
115 | margin: [-100, 'auto', 20], | ||
116 | |||
117 | '& svg': { | ||
118 | width: '80px !important', | ||
119 | height: '80px !important', | ||
120 | filter: 'drop-shadow( 0px 2px 3px rgba(0, 0, 0, 0.3))', | ||
121 | fill: theme.styleTypes.danger.contrast, | ||
122 | }, | ||
123 | }, | ||
124 | headline: { | 107 | headline: { |
125 | fontSize: 40, | 108 | fontSize: 40, |
126 | }, | 109 | }, |
@@ -158,7 +141,7 @@ const styles = theme => ({ | |||
158 | overflow: 'scroll-x', | 141 | overflow: 'scroll-x', |
159 | }, | 142 | }, |
160 | featuredPlan: { | 143 | featuredPlan: { |
161 | transform: 'scale(1.05)', | 144 | transform: ({ isPersonalPlanAvailable }) => (isPersonalPlanAvailable ? 'scale(1.05)' : null), |
162 | }, | 145 | }, |
163 | disclaimer: { | 146 | disclaimer: { |
164 | textAlign: 'right', | 147 | textAlign: 'right', |
@@ -177,8 +160,13 @@ class PlanSelection extends Component { | |||
177 | upgradeAccount: PropTypes.func.isRequired, | 160 | upgradeAccount: PropTypes.func.isRequired, |
178 | stayOnFree: PropTypes.func.isRequired, | 161 | stayOnFree: PropTypes.func.isRequired, |
179 | hadSubscription: PropTypes.bool.isRequired, | 162 | hadSubscription: PropTypes.bool.isRequired, |
163 | isPersonalPlanAvailable: PropTypes.bool, | ||
180 | }; | 164 | }; |
181 | 165 | ||
166 | static defaultProps = { | ||
167 | isPersonalPlanAvailable: true, | ||
168 | } | ||
169 | |||
182 | static contextTypes = { | 170 | static contextTypes = { |
183 | intl: intlShape, | 171 | intl: intlShape, |
184 | }; | 172 | }; |
@@ -196,6 +184,7 @@ class PlanSelection extends Component { | |||
196 | upgradeAccount, | 184 | upgradeAccount, |
197 | stayOnFree, | 185 | stayOnFree, |
198 | hadSubscription, | 186 | hadSubscription, |
187 | isPersonalPlanAvailable, | ||
199 | } = this.props; | 188 | } = this.props; |
200 | 189 | ||
201 | const { intl } = this.context; | 190 | const { intl } = this.context; |
@@ -206,15 +195,14 @@ class PlanSelection extends Component { | |||
206 | className={classes.root} | 195 | className={classes.root} |
207 | > | 196 | > |
208 | <div className={classes.container}> | 197 | <div className={classes.container}> |
209 | <div className={classes.bigIcon}> | ||
210 | <Icon icon={mdiRocket} /> | ||
211 | </div> | ||
212 | <H1 className={classes.headline}>{intl.formatMessage(messages.welcome, { name: firstname })}</H1> | 198 | <H1 className={classes.headline}>{intl.formatMessage(messages.welcome, { name: firstname })}</H1> |
213 | <H2 className={classes.subheadline}>{intl.formatMessage(messages.subheadline)}</H2> | 199 | {isPersonalPlanAvailable && ( |
200 | <H2 className={classes.subheadline}>{intl.formatMessage(messages.subheadline)}</H2> | ||
201 | )} | ||
214 | <div className={classes.plans}> | 202 | <div className={classes.plans}> |
215 | <PlanItem | 203 | <PlanItem |
216 | name={i18nPlanName(PLANS.FREE, intl)} | 204 | name={i18nPlanName(PLANS.FREE, intl)} |
217 | text={intl.formatMessage(messages.textFree)} | 205 | text={isPersonalPlanAvailable ? intl.formatMessage(messages.textFree) : null} |
218 | price={0} | 206 | price={0} |
219 | currency={currency} | 207 | currency={currency} |
220 | ctaLabel={intl.formatMessage(subscriptionExpired ? messages.ctaDowngradeFree : messages.ctaStayOnFree)} | 208 | ctaLabel={intl.formatMessage(subscriptionExpired ? messages.ctaDowngradeFree : messages.ctaStayOnFree)} |
@@ -228,33 +216,35 @@ class PlanSelection extends Component { | |||
228 | </PlanItem> | 216 | </PlanItem> |
229 | <PlanItem | 217 | <PlanItem |
230 | name={i18nPlanName(plans.pro.yearly.id, intl)} | 218 | name={i18nPlanName(plans.pro.yearly.id, intl)} |
231 | text={intl.formatMessage(messages.textProfessional)} | 219 | text={isPersonalPlanAvailable ? intl.formatMessage(messages.textProfessional) : null} |
232 | price={plans.pro.yearly.price} | 220 | price={plans.pro.yearly.price} |
233 | currency={currency} | 221 | currency={currency} |
234 | ctaLabel={intl.formatMessage(hadSubscription ? messages.shortActionPro : messages.actionTrial)} | 222 | ctaLabel={intl.formatMessage(hadSubscription ? messages.shortActionPro : messages.actionTrial)} |
235 | upgrade={() => upgradeAccount(plans.pro.yearly.id)} | 223 | upgrade={() => upgradeAccount(plans.pro.yearly.id)} |
236 | className={classes.featuredPlan} | 224 | className={classes.featuredPlan} |
237 | perUser | 225 | perUser |
238 | bestValue | 226 | bestValue={isPersonalPlanAvailable} |
239 | > | ||
240 | <FeatureList | ||
241 | plan={PLANS.PRO} | ||
242 | className={classes.featureList} | ||
243 | /> | ||
244 | </PlanItem> | ||
245 | <PlanItem | ||
246 | name={i18nPlanName(plans.personal.yearly.id, intl)} | ||
247 | text={intl.formatMessage(messages.textPersonal)} | ||
248 | price={plans.personal.yearly.price} | ||
249 | currency={currency} | ||
250 | ctaLabel={intl.formatMessage(hadSubscription ? messages.shortActionPersonal : messages.actionTrial)} | ||
251 | upgrade={() => upgradeAccount(plans.personal.yearly.id)} | ||
252 | > | 227 | > |
253 | <FeatureList | 228 | <FeatureList |
254 | plan={PLANS.PERSONAL} | 229 | plan={isPersonalPlanAvailable ? PLANS.PRO : null} |
255 | className={classes.featureList} | 230 | className={classes.featureList} |
256 | /> | 231 | /> |
257 | </PlanItem> | 232 | </PlanItem> |
233 | {isPersonalPlanAvailable && ( | ||
234 | <PlanItem | ||
235 | name={i18nPlanName(plans.personal.yearly.id, intl)} | ||
236 | text={intl.formatMessage(messages.textPersonal)} | ||
237 | price={plans.personal.yearly.price} | ||
238 | currency={currency} | ||
239 | ctaLabel={intl.formatMessage(hadSubscription ? messages.shortActionPersonal : messages.actionTrial)} | ||
240 | upgrade={() => upgradeAccount(plans.personal.yearly.id)} | ||
241 | > | ||
242 | <FeatureList | ||
243 | plan={PLANS.PERSONAL} | ||
244 | className={classes.featureList} | ||
245 | /> | ||
246 | </PlanItem> | ||
247 | )} | ||
258 | </div> | 248 | </div> |
259 | <div className={classes.footer}> | 249 | <div className={classes.footer}> |
260 | <a | 250 | <a |
diff --git a/src/features/planSelection/containers/PlanSelectionScreen.js b/src/features/planSelection/containers/PlanSelectionScreen.js index d202c924e..e4d85cda5 100644 --- a/src/features/planSelection/containers/PlanSelectionScreen.js +++ b/src/features/planSelection/containers/PlanSelectionScreen.js | |||
@@ -53,7 +53,8 @@ class PlanSelectionScreen extends Component { | |||
53 | const { intl } = this.context; | 53 | const { intl } = this.context; |
54 | 54 | ||
55 | const { user, features } = this.props.stores; | 55 | const { user, features } = this.props.stores; |
56 | const { plans, currency } = features.features.pricingConfig; | 56 | const { isPersonalPlanAvailable, pricingConfig } = features.features; |
57 | const { plans, currency } = pricingConfig; | ||
57 | const { activateTrial } = this.props.actions.user; | 58 | const { activateTrial } = this.props.actions.user; |
58 | const { downgradeAccount, hideOverlay } = this.props.actions.planSelection; | 59 | const { downgradeAccount, hideOverlay } = this.props.actions.planSelection; |
59 | 60 | ||
@@ -95,6 +96,7 @@ class PlanSelectionScreen extends Component { | |||
95 | }} | 96 | }} |
96 | subscriptionExpired={user.team && user.team.state === 'expired' && !user.team.userHasDowngraded} | 97 | subscriptionExpired={user.team && user.team.state === 'expired' && !user.team.userHasDowngraded} |
97 | hadSubscription={user.data.hadSubscription} | 98 | hadSubscription={user.data.hadSubscription} |
99 | isPersonalPlanAvailable={isPersonalPlanAvailable} | ||
98 | /> | 100 | /> |
99 | </ErrorBoundary> | 101 | </ErrorBoundary> |
100 | ); | 102 | ); |
diff --git a/src/helpers/plan-helpers.js b/src/helpers/plan-helpers.js index ee22e4471..b474f8bbd 100644 --- a/src/helpers/plan-helpers.js +++ b/src/helpers/plan-helpers.js | |||
@@ -20,6 +20,10 @@ const messages = defineMessages({ | |||
20 | }, | 20 | }, |
21 | }); | 21 | }); |
22 | 22 | ||
23 | export function cleanupPlanId(id) { | ||
24 | return id.replace(/(.*)-x[0-9]/, '$1'); | ||
25 | } | ||
26 | |||
23 | export function i18nPlanName(planId, intl) { | 27 | export function i18nPlanName(planId, intl) { |
24 | if (!planId) { | 28 | if (!planId) { |
25 | throw new Error('planId is required'); | 29 | throw new Error('planId is required'); |
@@ -29,7 +33,9 @@ export function i18nPlanName(planId, intl) { | |||
29 | throw new Error('intl context is required'); | 33 | throw new Error('intl context is required'); |
30 | } | 34 | } |
31 | 35 | ||
32 | const plan = PLANS_MAPPING[planId]; | 36 | const id = cleanupPlanId(planId); |
37 | |||
38 | const plan = PLANS_MAPPING[id]; | ||
33 | 39 | ||
34 | return intl.formatMessage(messages[plan]); | 40 | return intl.formatMessage(messages[plan]); |
35 | } | 41 | } |
@@ -39,7 +45,9 @@ export function getPlan(planId) { | |||
39 | throw new Error('planId is required'); | 45 | throw new Error('planId is required'); |
40 | } | 46 | } |
41 | 47 | ||
42 | const plan = PLANS_MAPPING[planId]; | 48 | const id = cleanupPlanId(planId); |
49 | |||
50 | const plan = PLANS_MAPPING[id]; | ||
43 | 51 | ||
44 | return plan; | 52 | return plan; |
45 | } | 53 | } |
diff --git a/src/helpers/userAgent-helpers.js b/src/helpers/userAgent-helpers.js new file mode 100644 index 000000000..15edc1054 --- /dev/null +++ b/src/helpers/userAgent-helpers.js | |||
@@ -0,0 +1,45 @@ | |||
1 | import { remote, app } from 'electron'; | ||
2 | import os from 'os'; | ||
3 | import macosVersion from 'macos-version'; | ||
4 | import { isMac, isWindows } from '../environment'; | ||
5 | |||
6 | // This helper gets included from the backend and frontend but we only need to use "remote" | ||
7 | // if we are in the frontend | ||
8 | const ferdiVersion = remote && remote.app ? remote.app.getVersion() : app.getVersion(); | ||
9 | |||
10 | function macOS() { | ||
11 | const version = macosVersion(); | ||
12 | |||
13 | return `Macintosh; Intel Mac OS X ${version.replace(/\./g, '_')}`; | ||
14 | } | ||
15 | |||
16 | function windows() { | ||
17 | const version = os.release(); | ||
18 | const [majorVersion, minorVersion] = version.split('.'); | ||
19 | return `Windows NT ${majorVersion}.${minorVersion}; Win64; x64`; | ||
20 | } | ||
21 | |||
22 | function linux() { | ||
23 | return 'X11; Ubuntu; Linux x86_64'; | ||
24 | } | ||
25 | |||
26 | export default function userAgent(removeChromeVersion = false) { | ||
27 | let platformString = ''; | ||
28 | |||
29 | if (isMac) { | ||
30 | platformString = macOS(); | ||
31 | } else if (isWindows) { | ||
32 | platformString = windows(); | ||
33 | } else { | ||
34 | platformString = linux(); | ||
35 | } | ||
36 | |||
37 | let applicationString = ''; | ||
38 | if (!removeChromeVersion) { | ||
39 | applicationString = ` Ferdi/${ferdiVersion} (Electron ${process.versions.electron})`; | ||
40 | } | ||
41 | |||
42 | // TODO: Update AppleWebKit and Safari version after electron update | ||
43 | return `Mozilla/5.0 (${platformString}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome${!removeChromeVersion ? `/${process.versions.chrome}` : ''} Safari/537.36${applicationString}`; | ||
44 | // Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) old-airport-include/1.0.0 Chrome Electron/7.1.7 Safari/537.36 | ||
45 | } | ||
diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index 56d0b1971..f3ff7caf3 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json | |||
@@ -1193,6 +1193,190 @@ | |||
1193 | { | 1193 | { |
1194 | "descriptors": [ | 1194 | "descriptors": [ |
1195 | { | 1195 | { |
1196 | "defaultMessage": "!!!Home", | ||
1197 | "end": { | ||
1198 | "column": 3, | ||
1199 | "line": 16 | ||
1200 | }, | ||
1201 | "file": "src/components/services/content/ConnectionBanner.js", | ||
1202 | "id": "webControls.goHome", | ||
1203 | "start": { | ||
1204 | "column": 10, | ||
1205 | "line": 13 | ||
1206 | } | ||
1207 | }, | ||
1208 | { | ||
1209 | "defaultMessage": "!!!Open in Browser", | ||
1210 | "end": { | ||
1211 | "column": 3, | ||
1212 | "line": 20 | ||
1213 | }, | ||
1214 | "file": "src/components/services/content/ConnectionBanner.js", | ||
1215 | "id": "webControls.openInBrowser", | ||
1216 | "start": { | ||
1217 | "column": 17, | ||
1218 | "line": 17 | ||
1219 | } | ||
1220 | }, | ||
1221 | { | ||
1222 | "defaultMessage": "!!!Back", | ||
1223 | "end": { | ||
1224 | "column": 3, | ||
1225 | "line": 24 | ||
1226 | }, | ||
1227 | "file": "src/components/services/content/ConnectionBanner.js", | ||
1228 | "id": "webControls.back", | ||
1229 | "start": { | ||
1230 | "column": 8, | ||
1231 | "line": 21 | ||
1232 | } | ||
1233 | }, | ||
1234 | { | ||
1235 | "defaultMessage": "!!!Forward", | ||
1236 | "end": { | ||
1237 | "column": 3, | ||
1238 | "line": 28 | ||
1239 | }, | ||
1240 | "file": "src/components/services/content/ConnectionBanner.js", | ||
1241 | "id": "webControls.forward", | ||
1242 | "start": { | ||
1243 | "column": 11, | ||
1244 | "line": 25 | ||
1245 | } | ||
1246 | }, | ||
1247 | { | ||
1248 | "defaultMessage": "!!!Reload", | ||
1249 | "end": { | ||
1250 | "column": 3, | ||
1251 | "line": 32 | ||
1252 | }, | ||
1253 | "file": "src/components/services/content/ConnectionBanner.js", | ||
1254 | "id": "webControls.reload", | ||
1255 | "start": { | ||
1256 | "column": 10, | ||
1257 | "line": 29 | ||
1258 | } | ||
1259 | } | ||
1260 | ], | ||
1261 | "path": "src/components/services/content/ConnectionBanner.json" | ||
1262 | }, | ||
1263 | { | ||
1264 | "descriptors": [ | ||
1265 | { | ||
1266 | "defaultMessage": "!!!Home", | ||
1267 | "end": { | ||
1268 | "column": 3, | ||
1269 | "line": 16 | ||
1270 | }, | ||
1271 | "file": "src/components/services/content/ConnectionLost.js", | ||
1272 | "id": "webControls.goHome", | ||
1273 | "start": { | ||
1274 | "column": 10, | ||
1275 | "line": 13 | ||
1276 | } | ||
1277 | }, | ||
1278 | { | ||
1279 | "defaultMessage": "!!!Open in Browser", | ||
1280 | "end": { | ||
1281 | "column": 3, | ||
1282 | "line": 20 | ||
1283 | }, | ||
1284 | "file": "src/components/services/content/ConnectionLost.js", | ||
1285 | "id": "webControls.openInBrowser", | ||
1286 | "start": { | ||
1287 | "column": 17, | ||
1288 | "line": 17 | ||
1289 | } | ||
1290 | }, | ||
1291 | { | ||
1292 | "defaultMessage": "!!!Back", | ||
1293 | "end": { | ||
1294 | "column": 3, | ||
1295 | "line": 24 | ||
1296 | }, | ||
1297 | "file": "src/components/services/content/ConnectionLost.js", | ||
1298 | "id": "webControls.back", | ||
1299 | "start": { | ||
1300 | "column": 8, | ||
1301 | "line": 21 | ||
1302 | } | ||
1303 | }, | ||
1304 | { | ||
1305 | "defaultMessage": "!!!Forward", | ||
1306 | "end": { | ||
1307 | "column": 3, | ||
1308 | "line": 28 | ||
1309 | }, | ||
1310 | "file": "src/components/services/content/ConnectionLost.js", | ||
1311 | "id": "webControls.forward", | ||
1312 | "start": { | ||
1313 | "column": 11, | ||
1314 | "line": 25 | ||
1315 | } | ||
1316 | }, | ||
1317 | { | ||
1318 | "defaultMessage": "!!!Reload", | ||
1319 | "end": { | ||
1320 | "column": 3, | ||
1321 | "line": 32 | ||
1322 | }, | ||
1323 | "file": "src/components/services/content/ConnectionLost.js", | ||
1324 | "id": "webControls.reload", | ||
1325 | "start": { | ||
1326 | "column": 10, | ||
1327 | "line": 29 | ||
1328 | } | ||
1329 | } | ||
1330 | ], | ||
1331 | "path": "src/components/services/content/ConnectionLost.json" | ||
1332 | }, | ||
1333 | { | ||
1334 | "descriptors": [ | ||
1335 | { | ||
1336 | "defaultMessage": "!!!Oh no! Franz lost the connection to {name}.", | ||
1337 | "end": { | ||
1338 | "column": 3, | ||
1339 | "line": 18 | ||
1340 | }, | ||
1341 | "file": "src/components/services/content/ConnectionLostBanner.js", | ||
1342 | "id": "connectionLostBanner.message", | ||
1343 | "start": { | ||
1344 | "column": 8, | ||
1345 | "line": 15 | ||
1346 | } | ||
1347 | }, | ||
1348 | { | ||
1349 | "defaultMessage": "!!!What happened?", | ||
1350 | "end": { | ||
1351 | "column": 3, | ||
1352 | "line": 22 | ||
1353 | }, | ||
1354 | "file": "src/components/services/content/ConnectionLostBanner.js", | ||
1355 | "id": "connectionLostBanner.informationLink", | ||
1356 | "start": { | ||
1357 | "column": 19, | ||
1358 | "line": 19 | ||
1359 | } | ||
1360 | }, | ||
1361 | { | ||
1362 | "defaultMessage": "!!!Reload Service", | ||
1363 | "end": { | ||
1364 | "column": 3, | ||
1365 | "line": 26 | ||
1366 | }, | ||
1367 | "file": "src/components/services/content/ConnectionLostBanner.js", | ||
1368 | "id": "connectionLostBanner.cta", | ||
1369 | "start": { | ||
1370 | "column": 7, | ||
1371 | "line": 23 | ||
1372 | } | ||
1373 | } | ||
1374 | ], | ||
1375 | "path": "src/components/services/content/ConnectionLostBanner.json" | ||
1376 | }, | ||
1377 | { | ||
1378 | "descriptors": [ | ||
1379 | { | ||
1196 | "defaultMessage": "!!!Oh no!", | 1380 | "defaultMessage": "!!!Oh no!", |
1197 | "end": { | 1381 | "end": { |
1198 | "column": 3, | 1382 | "column": 3, |
@@ -1434,6 +1618,76 @@ | |||
1434 | { | 1618 | { |
1435 | "descriptors": [ | 1619 | "descriptors": [ |
1436 | { | 1620 | { |
1621 | "defaultMessage": "!!!Home", | ||
1622 | "end": { | ||
1623 | "column": 3, | ||
1624 | "line": 16 | ||
1625 | }, | ||
1626 | "file": "src/components/services/content/WebControls.js", | ||
1627 | "id": "webControls.goHome", | ||
1628 | "start": { | ||
1629 | "column": 10, | ||
1630 | "line": 13 | ||
1631 | } | ||
1632 | }, | ||
1633 | { | ||
1634 | "defaultMessage": "!!!Open in Browser", | ||
1635 | "end": { | ||
1636 | "column": 3, | ||
1637 | "line": 20 | ||
1638 | }, | ||
1639 | "file": "src/components/services/content/WebControls.js", | ||
1640 | "id": "webControls.openInBrowser", | ||
1641 | "start": { | ||
1642 | "column": 17, | ||
1643 | "line": 17 | ||
1644 | } | ||
1645 | }, | ||
1646 | { | ||
1647 | "defaultMessage": "!!!Back", | ||
1648 | "end": { | ||
1649 | "column": 3, | ||
1650 | "line": 24 | ||
1651 | }, | ||
1652 | "file": "src/components/services/content/WebControls.js", | ||
1653 | "id": "webControls.back", | ||
1654 | "start": { | ||
1655 | "column": 8, | ||
1656 | "line": 21 | ||
1657 | } | ||
1658 | }, | ||
1659 | { | ||
1660 | "defaultMessage": "!!!Forward", | ||
1661 | "end": { | ||
1662 | "column": 3, | ||
1663 | "line": 28 | ||
1664 | }, | ||
1665 | "file": "src/components/services/content/WebControls.js", | ||
1666 | "id": "webControls.forward", | ||
1667 | "start": { | ||
1668 | "column": 11, | ||
1669 | "line": 25 | ||
1670 | } | ||
1671 | }, | ||
1672 | { | ||
1673 | "defaultMessage": "!!!Reload", | ||
1674 | "end": { | ||
1675 | "column": 3, | ||
1676 | "line": 32 | ||
1677 | }, | ||
1678 | "file": "src/components/services/content/WebControls.js", | ||
1679 | "id": "webControls.reload", | ||
1680 | "start": { | ||
1681 | "column": 10, | ||
1682 | "line": 29 | ||
1683 | } | ||
1684 | } | ||
1685 | ], | ||
1686 | "path": "src/components/services/content/WebControls.json" | ||
1687 | }, | ||
1688 | { | ||
1689 | "descriptors": [ | ||
1690 | { | ||
1437 | "defaultMessage": "!!!Oh no!", | 1691 | "defaultMessage": "!!!Oh no!", |
1438 | "end": { | 1692 | "end": { |
1439 | "column": 3, | 1693 | "column": 3, |
@@ -2421,107 +2675,120 @@ | |||
2421 | } | 2675 | } |
2422 | }, | 2676 | }, |
2423 | { | 2677 | { |
2424 | "defaultMessage": "!!!Notifications", | 2678 | "defaultMessage": "!!!You currently have hibernation enabled but you can disable hibernation for individual services using this option.", |
2425 | "end": { | 2679 | "end": { |
2426 | "column": 3, | 2680 | "column": 3, |
2427 | "line": 99 | 2681 | "line": 99 |
2428 | }, | 2682 | }, |
2429 | "file": "src/components/settings/services/EditServiceForm.js", | 2683 | "file": "src/components/settings/services/EditServiceForm.js", |
2684 | "id": "settings.service.form.disableHibernationInfo", | ||
2685 | "start": { | ||
2686 | "column": 26, | ||
2687 | "line": 96 | ||
2688 | } | ||
2689 | }, | ||
2690 | { | ||
2691 | "defaultMessage": "!!!Notifications", | ||
2692 | "end": { | ||
2693 | "column": 3, | ||
2694 | "line": 103 | ||
2695 | }, | ||
2696 | "file": "src/components/settings/services/EditServiceForm.js", | ||
2430 | "id": "settings.service.form.headlineNotifications", | 2697 | "id": "settings.service.form.headlineNotifications", |
2431 | "start": { | 2698 | "start": { |
2432 | "column": 25, | 2699 | "column": 25, |
2433 | "line": 96 | 2700 | "line": 100 |
2434 | } | 2701 | } |
2435 | }, | 2702 | }, |
2436 | { | 2703 | { |
2437 | "defaultMessage": "!!!Unread message badges", | 2704 | "defaultMessage": "!!!Unread message badges", |
2438 | "end": { | 2705 | "end": { |
2439 | "column": 3, | 2706 | "column": 3, |
2440 | "line": 103 | 2707 | "line": 107 |
2441 | }, | 2708 | }, |
2442 | "file": "src/components/settings/services/EditServiceForm.js", | 2709 | "file": "src/components/settings/services/EditServiceForm.js", |
2443 | "id": "settings.service.form.headlineBadges", | 2710 | "id": "settings.service.form.headlineBadges", |
2444 | "start": { | 2711 | "start": { |
2445 | "column": 18, | 2712 | "column": 18, |
2446 | "line": 100 | 2713 | "line": 104 |
2447 | } | 2714 | } |
2448 | }, | 2715 | }, |
2449 | { | 2716 | { |
2450 | "defaultMessage": "!!!General", | 2717 | "defaultMessage": "!!!General", |
2451 | "end": { | 2718 | "end": { |
2452 | "column": 3, | 2719 | "column": 3, |
2453 | "line": 107 | 2720 | "line": 111 |
2454 | }, | 2721 | }, |
2455 | "file": "src/components/settings/services/EditServiceForm.js", | 2722 | "file": "src/components/settings/services/EditServiceForm.js", |
2456 | "id": "settings.service.form.headlineGeneral", | 2723 | "id": "settings.service.form.headlineGeneral", |
2457 | "start": { | 2724 | "start": { |
2458 | "column": 19, | 2725 | "column": 19, |
2459 | "line": 104 | 2726 | "line": 108 |
2460 | } | 2727 | } |
2461 | }, | 2728 | }, |
2462 | { | 2729 | { |
2463 | "defaultMessage": "!!!Delete", | 2730 | "defaultMessage": "!!!Delete", |
2464 | "end": { | 2731 | "end": { |
2465 | "column": 3, | 2732 | "column": 3, |
2466 | "line": 111 | 2733 | "line": 115 |
2467 | }, | 2734 | }, |
2468 | "file": "src/components/settings/services/EditServiceForm.js", | 2735 | "file": "src/components/settings/services/EditServiceForm.js", |
2469 | "id": "settings.service.form.iconDelete", | 2736 | "id": "settings.service.form.iconDelete", |
2470 | "start": { | 2737 | "start": { |
2471 | "column": 14, | 2738 | "column": 14, |
2472 | "line": 108 | 2739 | "line": 112 |
2473 | } | 2740 | } |
2474 | }, | 2741 | }, |
2475 | { | 2742 | { |
2476 | "defaultMessage": "!!!Drop your image, or click here", | 2743 | "defaultMessage": "!!!Drop your image, or click here", |
2477 | "end": { | 2744 | "end": { |
2478 | "column": 3, | 2745 | "column": 3, |
2479 | "line": 115 | 2746 | "line": 119 |
2480 | }, | 2747 | }, |
2481 | "file": "src/components/settings/services/EditServiceForm.js", | 2748 | "file": "src/components/settings/services/EditServiceForm.js", |
2482 | "id": "settings.service.form.iconUpload", | 2749 | "id": "settings.service.form.iconUpload", |
2483 | "start": { | 2750 | "start": { |
2484 | "column": 14, | 2751 | "column": 14, |
2485 | "line": 112 | 2752 | "line": 116 |
2486 | } | 2753 | } |
2487 | }, | 2754 | }, |
2488 | { | 2755 | { |
2489 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", | 2756 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", |
2490 | "end": { | 2757 | "end": { |
2491 | "column": 3, | 2758 | "column": 3, |
2492 | "line": 119 | 2759 | "line": 123 |
2493 | }, | 2760 | }, |
2494 | "file": "src/components/settings/services/EditServiceForm.js", | 2761 | "file": "src/components/settings/services/EditServiceForm.js", |
2495 | "id": "settings.service.form.proxy.headline", | 2762 | "id": "settings.service.form.proxy.headline", |
2496 | "start": { | 2763 | "start": { |
2497 | "column": 17, | 2764 | "column": 17, |
2498 | "line": 116 | 2765 | "line": 120 |
2499 | } | 2766 | } |
2500 | }, | 2767 | }, |
2501 | { | 2768 | { |
2502 | "defaultMessage": "!!!Please restart Ferdi after changing proxy Settings.", | 2769 | "defaultMessage": "!!!Please restart Ferdi after changing proxy Settings.", |
2503 | "end": { | 2770 | "end": { |
2504 | "column": 3, | 2771 | "column": 3, |
2505 | "line": 123 | 2772 | "line": 127 |
2506 | }, | 2773 | }, |
2507 | "file": "src/components/settings/services/EditServiceForm.js", | 2774 | "file": "src/components/settings/services/EditServiceForm.js", |
2508 | "id": "settings.service.form.proxy.restartInfo", | 2775 | "id": "settings.service.form.proxy.restartInfo", |
2509 | "start": { | 2776 | "start": { |
2510 | "column": 20, | 2777 | "column": 20, |
2511 | "line": 120 | 2778 | "line": 124 |
2512 | } | 2779 | } |
2513 | }, | 2780 | }, |
2514 | { | 2781 | { |
2515 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Ferdi servers.", | 2782 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Ferdi servers.", |
2516 | "end": { | 2783 | "end": { |
2517 | "column": 3, | 2784 | "column": 3, |
2518 | "line": 127 | 2785 | "line": 131 |
2519 | }, | 2786 | }, |
2520 | "file": "src/components/settings/services/EditServiceForm.js", | 2787 | "file": "src/components/settings/services/EditServiceForm.js", |
2521 | "id": "settings.service.form.proxy.info", | 2788 | "id": "settings.service.form.proxy.info", |
2522 | "start": { | 2789 | "start": { |
2523 | "column": 13, | 2790 | "column": 13, |
2524 | "line": 124 | 2791 | "line": 128 |
2525 | } | 2792 | } |
2526 | } | 2793 | } |
2527 | ], | 2794 | ], |
@@ -3888,6 +4155,19 @@ | |||
3888 | "column": 10, | 4155 | "column": 10, |
3889 | "line": 65 | 4156 | "line": 65 |
3890 | } | 4157 | } |
4158 | }, | ||
4159 | { | ||
4160 | "defaultMessage": "!!!Occasional Waiting Screens", | ||
4161 | "end": { | ||
4162 | "column": 3, | ||
4163 | "line": 72 | ||
4164 | }, | ||
4165 | "file": "src/components/ui/FeatureList.js", | ||
4166 | "id": "pricing.features.appDelaysEnabled", | ||
4167 | "start": { | ||
4168 | "column": 19, | ||
4169 | "line": 69 | ||
4170 | } | ||
3891 | } | 4171 | } |
3892 | ], | 4172 | ], |
3893 | "path": "src/components/ui/FeatureList.json" | 4173 | "path": "src/components/ui/FeatureList.json" |
@@ -4006,172 +4286,185 @@ | |||
4006 | } | 4286 | } |
4007 | }, | 4287 | }, |
4008 | { | 4288 | { |
4009 | "defaultMessage": "!!!Enable Notifications", | 4289 | "defaultMessage": "!!!Disable hibernation", |
4010 | "end": { | 4290 | "end": { |
4011 | "column": 3, | 4291 | "column": 3, |
4012 | "line": 39 | 4292 | "line": 39 |
4013 | }, | 4293 | }, |
4014 | "file": "src/containers/settings/EditServiceScreen.js", | 4294 | "file": "src/containers/settings/EditServiceScreen.js", |
4015 | "id": "settings.service.form.enableNotification", | 4295 | "id": "settings.service.form.disableHibernation", |
4016 | "start": { | 4296 | "start": { |
4017 | "column": 22, | 4297 | "column": 22, |
4018 | "line": 36 | 4298 | "line": 36 |
4019 | } | 4299 | } |
4020 | }, | 4300 | }, |
4021 | { | 4301 | { |
4022 | "defaultMessage": "!!!Show unread message badges", | 4302 | "defaultMessage": "!!!Enable Notifications", |
4023 | "end": { | 4303 | "end": { |
4024 | "column": 3, | 4304 | "column": 3, |
4025 | "line": 43 | 4305 | "line": 43 |
4026 | }, | 4306 | }, |
4027 | "file": "src/containers/settings/EditServiceScreen.js", | 4307 | "file": "src/containers/settings/EditServiceScreen.js", |
4308 | "id": "settings.service.form.enableNotification", | ||
4309 | "start": { | ||
4310 | "column": 22, | ||
4311 | "line": 40 | ||
4312 | } | ||
4313 | }, | ||
4314 | { | ||
4315 | "defaultMessage": "!!!Show unread message badges", | ||
4316 | "end": { | ||
4317 | "column": 3, | ||
4318 | "line": 47 | ||
4319 | }, | ||
4320 | "file": "src/containers/settings/EditServiceScreen.js", | ||
4028 | "id": "settings.service.form.enableBadge", | 4321 | "id": "settings.service.form.enableBadge", |
4029 | "start": { | 4322 | "start": { |
4030 | "column": 15, | 4323 | "column": 15, |
4031 | "line": 40 | 4324 | "line": 44 |
4032 | } | 4325 | } |
4033 | }, | 4326 | }, |
4034 | { | 4327 | { |
4035 | "defaultMessage": "!!!Enable audio", | 4328 | "defaultMessage": "!!!Enable audio", |
4036 | "end": { | 4329 | "end": { |
4037 | "column": 3, | 4330 | "column": 3, |
4038 | "line": 47 | 4331 | "line": 51 |
4039 | }, | 4332 | }, |
4040 | "file": "src/containers/settings/EditServiceScreen.js", | 4333 | "file": "src/containers/settings/EditServiceScreen.js", |
4041 | "id": "settings.service.form.enableAudio", | 4334 | "id": "settings.service.form.enableAudio", |
4042 | "start": { | 4335 | "start": { |
4043 | "column": 15, | 4336 | "column": 15, |
4044 | "line": 44 | 4337 | "line": 48 |
4045 | } | 4338 | } |
4046 | }, | 4339 | }, |
4047 | { | 4340 | { |
4048 | "defaultMessage": "!!!Team", | 4341 | "defaultMessage": "!!!Team", |
4049 | "end": { | 4342 | "end": { |
4050 | "column": 3, | 4343 | "column": 3, |
4051 | "line": 51 | 4344 | "line": 55 |
4052 | }, | 4345 | }, |
4053 | "file": "src/containers/settings/EditServiceScreen.js", | 4346 | "file": "src/containers/settings/EditServiceScreen.js", |
4054 | "id": "settings.service.form.team", | 4347 | "id": "settings.service.form.team", |
4055 | "start": { | 4348 | "start": { |
4056 | "column": 8, | 4349 | "column": 8, |
4057 | "line": 48 | 4350 | "line": 52 |
4058 | } | 4351 | } |
4059 | }, | 4352 | }, |
4060 | { | 4353 | { |
4061 | "defaultMessage": "!!!Service URL", | 4354 | "defaultMessage": "!!!Service URL", |
4062 | "end": { | 4355 | "end": { |
4063 | "column": 3, | 4356 | "column": 3, |
4064 | "line": 55 | 4357 | "line": 59 |
4065 | }, | 4358 | }, |
4066 | "file": "src/containers/settings/EditServiceScreen.js", | 4359 | "file": "src/containers/settings/EditServiceScreen.js", |
4067 | "id": "settings.service.form.customUrl", | 4360 | "id": "settings.service.form.customUrl", |
4068 | "start": { | 4361 | "start": { |
4069 | "column": 13, | 4362 | "column": 13, |
4070 | "line": 52 | 4363 | "line": 56 |
4071 | } | 4364 | } |
4072 | }, | 4365 | }, |
4073 | { | 4366 | { |
4074 | "defaultMessage": "!!!Show message badge for all new messages", | 4367 | "defaultMessage": "!!!Show message badge for all new messages", |
4075 | "end": { | 4368 | "end": { |
4076 | "column": 3, | 4369 | "column": 3, |
4077 | "line": 59 | 4370 | "line": 63 |
4078 | }, | 4371 | }, |
4079 | "file": "src/containers/settings/EditServiceScreen.js", | 4372 | "file": "src/containers/settings/EditServiceScreen.js", |
4080 | "id": "settings.service.form.indirectMessages", | 4373 | "id": "settings.service.form.indirectMessages", |
4081 | "start": { | 4374 | "start": { |
4082 | "column": 20, | 4375 | "column": 20, |
4083 | "line": 56 | 4376 | "line": 60 |
4084 | } | 4377 | } |
4085 | }, | 4378 | }, |
4086 | { | 4379 | { |
4087 | "defaultMessage": "!!!Custom icon", | 4380 | "defaultMessage": "!!!Custom icon", |
4088 | "end": { | 4381 | "end": { |
4089 | "column": 3, | 4382 | "column": 3, |
4090 | "line": 63 | 4383 | "line": 67 |
4091 | }, | 4384 | }, |
4092 | "file": "src/containers/settings/EditServiceScreen.js", | 4385 | "file": "src/containers/settings/EditServiceScreen.js", |
4093 | "id": "settings.service.form.icon", | 4386 | "id": "settings.service.form.icon", |
4094 | "start": { | 4387 | "start": { |
4095 | "column": 8, | 4388 | "column": 8, |
4096 | "line": 60 | 4389 | "line": 64 |
4097 | } | 4390 | } |
4098 | }, | 4391 | }, |
4099 | { | 4392 | { |
4100 | "defaultMessage": "!!!Enable Dark Mode", | 4393 | "defaultMessage": "!!!Enable Dark Mode", |
4101 | "end": { | 4394 | "end": { |
4102 | "column": 3, | 4395 | "column": 3, |
4103 | "line": 67 | 4396 | "line": 71 |
4104 | }, | 4397 | }, |
4105 | "file": "src/containers/settings/EditServiceScreen.js", | 4398 | "file": "src/containers/settings/EditServiceScreen.js", |
4106 | "id": "settings.service.form.enableDarkMode", | 4399 | "id": "settings.service.form.enableDarkMode", |
4107 | "start": { | 4400 | "start": { |
4108 | "column": 18, | 4401 | "column": 18, |
4109 | "line": 64 | 4402 | "line": 68 |
4110 | } | 4403 | } |
4111 | }, | 4404 | }, |
4112 | { | 4405 | { |
4113 | "defaultMessage": "!!!Use Proxy", | 4406 | "defaultMessage": "!!!Use Proxy", |
4114 | "end": { | 4407 | "end": { |
4115 | "column": 3, | 4408 | "column": 3, |
4116 | "line": 71 | 4409 | "line": 75 |
4117 | }, | 4410 | }, |
4118 | "file": "src/containers/settings/EditServiceScreen.js", | 4411 | "file": "src/containers/settings/EditServiceScreen.js", |
4119 | "id": "settings.service.form.proxy.isEnabled", | 4412 | "id": "settings.service.form.proxy.isEnabled", |
4120 | "start": { | 4413 | "start": { |
4121 | "column": 15, | 4414 | "column": 15, |
4122 | "line": 68 | 4415 | "line": 72 |
4123 | } | 4416 | } |
4124 | }, | 4417 | }, |
4125 | { | 4418 | { |
4126 | "defaultMessage": "!!!Proxy Host/IP", | 4419 | "defaultMessage": "!!!Proxy Host/IP", |
4127 | "end": { | 4420 | "end": { |
4128 | "column": 3, | 4421 | "column": 3, |
4129 | "line": 75 | 4422 | "line": 79 |
4130 | }, | 4423 | }, |
4131 | "file": "src/containers/settings/EditServiceScreen.js", | 4424 | "file": "src/containers/settings/EditServiceScreen.js", |
4132 | "id": "settings.service.form.proxy.host", | 4425 | "id": "settings.service.form.proxy.host", |
4133 | "start": { | 4426 | "start": { |
4134 | "column": 13, | 4427 | "column": 13, |
4135 | "line": 72 | 4428 | "line": 76 |
4136 | } | 4429 | } |
4137 | }, | 4430 | }, |
4138 | { | 4431 | { |
4139 | "defaultMessage": "!!!Port", | 4432 | "defaultMessage": "!!!Port", |
4140 | "end": { | 4433 | "end": { |
4141 | "column": 3, | 4434 | "column": 3, |
4142 | "line": 79 | 4435 | "line": 83 |
4143 | }, | 4436 | }, |
4144 | "file": "src/containers/settings/EditServiceScreen.js", | 4437 | "file": "src/containers/settings/EditServiceScreen.js", |
4145 | "id": "settings.service.form.proxy.port", | 4438 | "id": "settings.service.form.proxy.port", |
4146 | "start": { | 4439 | "start": { |
4147 | "column": 13, | 4440 | "column": 13, |
4148 | "line": 76 | 4441 | "line": 80 |
4149 | } | 4442 | } |
4150 | }, | 4443 | }, |
4151 | { | 4444 | { |
4152 | "defaultMessage": "!!!User", | 4445 | "defaultMessage": "!!!User", |
4153 | "end": { | 4446 | "end": { |
4154 | "column": 3, | 4447 | "column": 3, |
4155 | "line": 83 | 4448 | "line": 87 |
4156 | }, | 4449 | }, |
4157 | "file": "src/containers/settings/EditServiceScreen.js", | 4450 | "file": "src/containers/settings/EditServiceScreen.js", |
4158 | "id": "settings.service.form.proxy.user", | 4451 | "id": "settings.service.form.proxy.user", |
4159 | "start": { | 4452 | "start": { |
4160 | "column": 13, | 4453 | "column": 13, |
4161 | "line": 80 | 4454 | "line": 84 |
4162 | } | 4455 | } |
4163 | }, | 4456 | }, |
4164 | { | 4457 | { |
4165 | "defaultMessage": "!!!Password", | 4458 | "defaultMessage": "!!!Password", |
4166 | "end": { | 4459 | "end": { |
4167 | "column": 3, | 4460 | "column": 3, |
4168 | "line": 87 | 4461 | "line": 91 |
4169 | }, | 4462 | }, |
4170 | "file": "src/containers/settings/EditServiceScreen.js", | 4463 | "file": "src/containers/settings/EditServiceScreen.js", |
4171 | "id": "settings.service.form.proxy.password", | 4464 | "id": "settings.service.form.proxy.password", |
4172 | "start": { | 4465 | "start": { |
4173 | "column": 17, | 4466 | "column": 17, |
4174 | "line": 84 | 4467 | "line": 88 |
4175 | } | 4468 | } |
4176 | } | 4469 | } |
4177 | ], | 4470 | ], |
@@ -5327,6 +5620,76 @@ | |||
5327 | { | 5620 | { |
5328 | "descriptors": [ | 5621 | "descriptors": [ |
5329 | { | 5622 | { |
5623 | "defaultMessage": "!!!Home", | ||
5624 | "end": { | ||
5625 | "column": 3, | ||
5626 | "line": 16 | ||
5627 | }, | ||
5628 | "file": "src/features/recipeConnectionLost/components/WebControls.js", | ||
5629 | "id": "webControls.goHome", | ||
5630 | "start": { | ||
5631 | "column": 10, | ||
5632 | "line": 13 | ||
5633 | } | ||
5634 | }, | ||
5635 | { | ||
5636 | "defaultMessage": "!!!Open in Browser", | ||
5637 | "end": { | ||
5638 | "column": 3, | ||
5639 | "line": 20 | ||
5640 | }, | ||
5641 | "file": "src/features/recipeConnectionLost/components/WebControls.js", | ||
5642 | "id": "webControls.openInBrowser", | ||
5643 | "start": { | ||
5644 | "column": 17, | ||
5645 | "line": 17 | ||
5646 | } | ||
5647 | }, | ||
5648 | { | ||
5649 | "defaultMessage": "!!!Back", | ||
5650 | "end": { | ||
5651 | "column": 3, | ||
5652 | "line": 24 | ||
5653 | }, | ||
5654 | "file": "src/features/recipeConnectionLost/components/WebControls.js", | ||
5655 | "id": "webControls.back", | ||
5656 | "start": { | ||
5657 | "column": 8, | ||
5658 | "line": 21 | ||
5659 | } | ||
5660 | }, | ||
5661 | { | ||
5662 | "defaultMessage": "!!!Forward", | ||
5663 | "end": { | ||
5664 | "column": 3, | ||
5665 | "line": 28 | ||
5666 | }, | ||
5667 | "file": "src/features/recipeConnectionLost/components/WebControls.js", | ||
5668 | "id": "webControls.forward", | ||
5669 | "start": { | ||
5670 | "column": 11, | ||
5671 | "line": 25 | ||
5672 | } | ||
5673 | }, | ||
5674 | { | ||
5675 | "defaultMessage": "!!!Reload", | ||
5676 | "end": { | ||
5677 | "column": 3, | ||
5678 | "line": 32 | ||
5679 | }, | ||
5680 | "file": "src/features/recipeConnectionLost/components/WebControls.js", | ||
5681 | "id": "webControls.reload", | ||
5682 | "start": { | ||
5683 | "column": 10, | ||
5684 | "line": 29 | ||
5685 | } | ||
5686 | } | ||
5687 | ], | ||
5688 | "path": "src/features/recipeConnectionLost/components/WebControls.json" | ||
5689 | }, | ||
5690 | { | ||
5691 | "descriptors": [ | ||
5692 | { | ||
5330 | "defaultMessage": "!!!Changes in Franz {version}", | 5693 | "defaultMessage": "!!!Changes in Franz {version}", |
5331 | "end": { | 5694 | "end": { |
5332 | "column": 3, | 5695 | "column": 3, |
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 947f927e7..8a95970a2 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -4,6 +4,9 @@ | |||
4 | "changeserver.headline": "Change server", | 4 | "changeserver.headline": "Change server", |
5 | "changeserver.label": "Server", | 5 | "changeserver.label": "Server", |
6 | "changeserver.submit": "Submit", | 6 | "changeserver.submit": "Submit", |
7 | "connectionLostBanner.cta": "Reload Service", | ||
8 | "connectionLostBanner.informationLink": "What happened?", | ||
9 | "connectionLostBanner.message": "Oh no! Ferdi lost the connection to {name}.", | ||
7 | "feature.announcements.changelog.headline": "Changes in Ferdi {version}", | 10 | "feature.announcements.changelog.headline": "Changes in Ferdi {version}", |
8 | "feature.debugger.title": "Publish debugging information", | 11 | "feature.debugger.title": "Publish debugging information", |
9 | "feature.delayApp.headline": "Please purchase a Ferdi Supporter License to skip waiting", | 12 | "feature.delayApp.headline": "Please purchase a Ferdi Supporter License to skip waiting", |
@@ -183,6 +186,7 @@ | |||
183 | "pricing.features.accountSync": "Account Synchronisation", | 186 | "pricing.features.accountSync": "Account Synchronisation", |
184 | "pricing.features.adFree": "Forever ad-free", | 187 | "pricing.features.adFree": "Forever ad-free", |
185 | "pricing.features.appDelays": "No Waiting Screens", | 188 | "pricing.features.appDelays": "No Waiting Screens", |
189 | "pricing.features.appDelaysEnabled": "Occasional Waiting Screens", | ||
186 | "pricing.features.customWebsites": "Add Custom Websites", | 190 | "pricing.features.customWebsites": "Add Custom Websites", |
187 | "pricing.features.desktopNotifications": "Desktop Notifications", | 191 | "pricing.features.desktopNotifications": "Desktop Notifications", |
188 | "pricing.features.onPremise": "On-premise & other Hosted Services", | 192 | "pricing.features.onPremise": "On-premise & other Hosted Services", |
@@ -305,8 +309,8 @@ | |||
305 | "settings.app.form.sentry": "Send telemetry data", | 309 | "settings.app.form.sentry": "Send telemetry data", |
306 | "settings.app.form.serviceRibbonWidth": "Sidebar width", | 310 | "settings.app.form.serviceRibbonWidth": "Sidebar width", |
307 | "settings.app.form.showDisabledServices": "Display disabled services tabs", | 311 | "settings.app.form.showDisabledServices": "Display disabled services tabs", |
308 | "settings.app.form.showMessagesBadgesWhenMuted": "Show unread message badge when notifications are disabled", | ||
309 | "settings.app.form.showDragArea": "Show draggable area on window", | 312 | "settings.app.form.showDragArea": "Show draggable area on window", |
313 | "settings.app.form.showMessagesBadgesWhenMuted": "Show unread message badge when notifications are disabled", | ||
310 | "settings.app.form.startMinimized": "Start minimized", | 314 | "settings.app.form.startMinimized": "Start minimized", |
311 | "settings.app.form.universalDarkMode": "Enable universal Dark Mode", | 315 | "settings.app.form.universalDarkMode": "Enable universal Dark Mode", |
312 | "settings.app.form.useTouchIdToUnlock": "Allow using TouchID to unlock Ferdi", | 316 | "settings.app.form.useTouchIdToUnlock": "Allow using TouchID to unlock Ferdi", |
@@ -366,6 +370,8 @@ | |||
366 | "settings.service.form.customUrlUpgradeAccount": "Upgrade your account", | 370 | "settings.service.form.customUrlUpgradeAccount": "Upgrade your account", |
367 | "settings.service.form.customUrlValidationError": "Could not validate custom {name} server.", | 371 | "settings.service.form.customUrlValidationError": "Could not validate custom {name} server.", |
368 | "settings.service.form.deleteButton": "Delete service", | 372 | "settings.service.form.deleteButton": "Delete service", |
373 | "settings.service.form.disableHibernation": "Disable hibernation", | ||
374 | "settings.service.form.disableHibernationInfo": "You currently have hibernation enabled but you can disable hibernation for individual services using this option.", | ||
369 | "settings.service.form.editServiceHeadline": "Edit {name}", | 375 | "settings.service.form.editServiceHeadline": "Edit {name}", |
370 | "settings.service.form.enableAudio": "Enable audio", | 376 | "settings.service.form.enableAudio": "Enable audio", |
371 | "settings.service.form.enableBadge": "Show unread message badges", | 377 | "settings.service.form.enableBadge": "Show unread message badges", |
diff --git a/src/i18n/messages/src/components/services/content/ConnectionBanner.json b/src/i18n/messages/src/components/services/content/ConnectionBanner.json new file mode 100644 index 000000000..1047c28b5 --- /dev/null +++ b/src/i18n/messages/src/components/services/content/ConnectionBanner.json | |||
@@ -0,0 +1,67 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "webControls.goHome", | ||
4 | "defaultMessage": "!!!Home", | ||
5 | "file": "src/components/services/content/ConnectionBanner.js", | ||
6 | "start": { | ||
7 | "line": 13, | ||
8 | "column": 10 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 16, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "webControls.openInBrowser", | ||
17 | "defaultMessage": "!!!Open in Browser", | ||
18 | "file": "src/components/services/content/ConnectionBanner.js", | ||
19 | "start": { | ||
20 | "line": 17, | ||
21 | "column": 17 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 20, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "webControls.back", | ||
30 | "defaultMessage": "!!!Back", | ||
31 | "file": "src/components/services/content/ConnectionBanner.js", | ||
32 | "start": { | ||
33 | "line": 21, | ||
34 | "column": 8 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 24, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "webControls.forward", | ||
43 | "defaultMessage": "!!!Forward", | ||
44 | "file": "src/components/services/content/ConnectionBanner.js", | ||
45 | "start": { | ||
46 | "line": 25, | ||
47 | "column": 11 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 28, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "webControls.reload", | ||
56 | "defaultMessage": "!!!Reload", | ||
57 | "file": "src/components/services/content/ConnectionBanner.js", | ||
58 | "start": { | ||
59 | "line": 29, | ||
60 | "column": 10 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 32, | ||
64 | "column": 3 | ||
65 | } | ||
66 | } | ||
67 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/services/content/ConnectionLost.json b/src/i18n/messages/src/components/services/content/ConnectionLost.json new file mode 100644 index 000000000..ee3f7a4ba --- /dev/null +++ b/src/i18n/messages/src/components/services/content/ConnectionLost.json | |||
@@ -0,0 +1,67 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "webControls.goHome", | ||
4 | "defaultMessage": "!!!Home", | ||
5 | "file": "src/components/services/content/ConnectionLost.js", | ||
6 | "start": { | ||
7 | "line": 13, | ||
8 | "column": 10 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 16, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "webControls.openInBrowser", | ||
17 | "defaultMessage": "!!!Open in Browser", | ||
18 | "file": "src/components/services/content/ConnectionLost.js", | ||
19 | "start": { | ||
20 | "line": 17, | ||
21 | "column": 17 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 20, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "webControls.back", | ||
30 | "defaultMessage": "!!!Back", | ||
31 | "file": "src/components/services/content/ConnectionLost.js", | ||
32 | "start": { | ||
33 | "line": 21, | ||
34 | "column": 8 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 24, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "webControls.forward", | ||
43 | "defaultMessage": "!!!Forward", | ||
44 | "file": "src/components/services/content/ConnectionLost.js", | ||
45 | "start": { | ||
46 | "line": 25, | ||
47 | "column": 11 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 28, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "webControls.reload", | ||
56 | "defaultMessage": "!!!Reload", | ||
57 | "file": "src/components/services/content/ConnectionLost.js", | ||
58 | "start": { | ||
59 | "line": 29, | ||
60 | "column": 10 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 32, | ||
64 | "column": 3 | ||
65 | } | ||
66 | } | ||
67 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/services/content/ConnectionLostBanner.json b/src/i18n/messages/src/components/services/content/ConnectionLostBanner.json new file mode 100644 index 000000000..fd7019f41 --- /dev/null +++ b/src/i18n/messages/src/components/services/content/ConnectionLostBanner.json | |||
@@ -0,0 +1,41 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "connectionLostBanner.message", | ||
4 | "defaultMessage": "!!!Oh no! Franz lost the connection to {name}.", | ||
5 | "file": "src/components/services/content/ConnectionLostBanner.js", | ||
6 | "start": { | ||
7 | "line": 15, | ||
8 | "column": 8 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 18, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "connectionLostBanner.informationLink", | ||
17 | "defaultMessage": "!!!What happened?", | ||
18 | "file": "src/components/services/content/ConnectionLostBanner.js", | ||
19 | "start": { | ||
20 | "line": 19, | ||
21 | "column": 19 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 22, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "connectionLostBanner.cta", | ||
30 | "defaultMessage": "!!!Reload Service", | ||
31 | "file": "src/components/services/content/ConnectionLostBanner.js", | ||
32 | "start": { | ||
33 | "line": 23, | ||
34 | "column": 7 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 26, | ||
38 | "column": 3 | ||
39 | } | ||
40 | } | ||
41 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/services/content/WebControls.json b/src/i18n/messages/src/components/services/content/WebControls.json new file mode 100644 index 000000000..5af5143d0 --- /dev/null +++ b/src/i18n/messages/src/components/services/content/WebControls.json | |||
@@ -0,0 +1,67 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "webControls.goHome", | ||
4 | "defaultMessage": "!!!Home", | ||
5 | "file": "src/components/services/content/WebControls.js", | ||
6 | "start": { | ||
7 | "line": 13, | ||
8 | "column": 10 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 16, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "webControls.openInBrowser", | ||
17 | "defaultMessage": "!!!Open in Browser", | ||
18 | "file": "src/components/services/content/WebControls.js", | ||
19 | "start": { | ||
20 | "line": 17, | ||
21 | "column": 17 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 20, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "webControls.back", | ||
30 | "defaultMessage": "!!!Back", | ||
31 | "file": "src/components/services/content/WebControls.js", | ||
32 | "start": { | ||
33 | "line": 21, | ||
34 | "column": 8 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 24, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "webControls.forward", | ||
43 | "defaultMessage": "!!!Forward", | ||
44 | "file": "src/components/services/content/WebControls.js", | ||
45 | "start": { | ||
46 | "line": 25, | ||
47 | "column": 11 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 28, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "webControls.reload", | ||
56 | "defaultMessage": "!!!Reload", | ||
57 | "file": "src/components/services/content/WebControls.js", | ||
58 | "start": { | ||
59 | "line": 29, | ||
60 | "column": 10 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 32, | ||
64 | "column": 3 | ||
65 | } | ||
66 | } | ||
67 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/settings/services/EditServiceForm.json b/src/i18n/messages/src/components/settings/services/EditServiceForm.json index df64c8a5f..811c49498 100644 --- a/src/i18n/messages/src/components/settings/services/EditServiceForm.json +++ b/src/i18n/messages/src/components/settings/services/EditServiceForm.json | |||
@@ -234,15 +234,28 @@ | |||
234 | } | 234 | } |
235 | }, | 235 | }, |
236 | { | 236 | { |
237 | "id": "settings.service.form.disableHibernationInfo", | ||
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", | ||
240 | "start": { | ||
241 | "line": 96, | ||
242 | "column": 26 | ||
243 | }, | ||
244 | "end": { | ||
245 | "line": 99, | ||
246 | "column": 3 | ||
247 | } | ||
248 | }, | ||
249 | { | ||
237 | "id": "settings.service.form.headlineNotifications", | 250 | "id": "settings.service.form.headlineNotifications", |
238 | "defaultMessage": "!!!Notifications", | 251 | "defaultMessage": "!!!Notifications", |
239 | "file": "src/components/settings/services/EditServiceForm.js", | 252 | "file": "src/components/settings/services/EditServiceForm.js", |
240 | "start": { | 253 | "start": { |
241 | "line": 96, | 254 | "line": 100, |
242 | "column": 25 | 255 | "column": 25 |
243 | }, | 256 | }, |
244 | "end": { | 257 | "end": { |
245 | "line": 99, | 258 | "line": 103, |
246 | "column": 3 | 259 | "column": 3 |
247 | } | 260 | } |
248 | }, | 261 | }, |
@@ -251,11 +264,11 @@ | |||
251 | "defaultMessage": "!!!Unread message badges", | 264 | "defaultMessage": "!!!Unread message badges", |
252 | "file": "src/components/settings/services/EditServiceForm.js", | 265 | "file": "src/components/settings/services/EditServiceForm.js", |
253 | "start": { | 266 | "start": { |
254 | "line": 100, | 267 | "line": 104, |
255 | "column": 18 | 268 | "column": 18 |
256 | }, | 269 | }, |
257 | "end": { | 270 | "end": { |
258 | "line": 103, | 271 | "line": 107, |
259 | "column": 3 | 272 | "column": 3 |
260 | } | 273 | } |
261 | }, | 274 | }, |
@@ -264,11 +277,11 @@ | |||
264 | "defaultMessage": "!!!General", | 277 | "defaultMessage": "!!!General", |
265 | "file": "src/components/settings/services/EditServiceForm.js", | 278 | "file": "src/components/settings/services/EditServiceForm.js", |
266 | "start": { | 279 | "start": { |
267 | "line": 104, | 280 | "line": 108, |
268 | "column": 19 | 281 | "column": 19 |
269 | }, | 282 | }, |
270 | "end": { | 283 | "end": { |
271 | "line": 107, | 284 | "line": 111, |
272 | "column": 3 | 285 | "column": 3 |
273 | } | 286 | } |
274 | }, | 287 | }, |
@@ -277,11 +290,11 @@ | |||
277 | "defaultMessage": "!!!Delete", | 290 | "defaultMessage": "!!!Delete", |
278 | "file": "src/components/settings/services/EditServiceForm.js", | 291 | "file": "src/components/settings/services/EditServiceForm.js", |
279 | "start": { | 292 | "start": { |
280 | "line": 108, | 293 | "line": 112, |
281 | "column": 14 | 294 | "column": 14 |
282 | }, | 295 | }, |
283 | "end": { | 296 | "end": { |
284 | "line": 111, | 297 | "line": 115, |
285 | "column": 3 | 298 | "column": 3 |
286 | } | 299 | } |
287 | }, | 300 | }, |
@@ -290,11 +303,11 @@ | |||
290 | "defaultMessage": "!!!Drop your image, or click here", | 303 | "defaultMessage": "!!!Drop your image, or click here", |
291 | "file": "src/components/settings/services/EditServiceForm.js", | 304 | "file": "src/components/settings/services/EditServiceForm.js", |
292 | "start": { | 305 | "start": { |
293 | "line": 112, | 306 | "line": 116, |
294 | "column": 14 | 307 | "column": 14 |
295 | }, | 308 | }, |
296 | "end": { | 309 | "end": { |
297 | "line": 115, | 310 | "line": 119, |
298 | "column": 3 | 311 | "column": 3 |
299 | } | 312 | } |
300 | }, | 313 | }, |
@@ -303,11 +316,11 @@ | |||
303 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", | 316 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", |
304 | "file": "src/components/settings/services/EditServiceForm.js", | 317 | "file": "src/components/settings/services/EditServiceForm.js", |
305 | "start": { | 318 | "start": { |
306 | "line": 116, | 319 | "line": 120, |
307 | "column": 17 | 320 | "column": 17 |
308 | }, | 321 | }, |
309 | "end": { | 322 | "end": { |
310 | "line": 119, | 323 | "line": 123, |
311 | "column": 3 | 324 | "column": 3 |
312 | } | 325 | } |
313 | }, | 326 | }, |
@@ -316,11 +329,11 @@ | |||
316 | "defaultMessage": "!!!Please restart Ferdi after changing proxy Settings.", | 329 | "defaultMessage": "!!!Please restart Ferdi after changing proxy Settings.", |
317 | "file": "src/components/settings/services/EditServiceForm.js", | 330 | "file": "src/components/settings/services/EditServiceForm.js", |
318 | "start": { | 331 | "start": { |
319 | "line": 120, | 332 | "line": 124, |
320 | "column": 20 | 333 | "column": 20 |
321 | }, | 334 | }, |
322 | "end": { | 335 | "end": { |
323 | "line": 123, | 336 | "line": 127, |
324 | "column": 3 | 337 | "column": 3 |
325 | } | 338 | } |
326 | }, | 339 | }, |
@@ -329,11 +342,11 @@ | |||
329 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Ferdi servers.", | 342 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Ferdi servers.", |
330 | "file": "src/components/settings/services/EditServiceForm.js", | 343 | "file": "src/components/settings/services/EditServiceForm.js", |
331 | "start": { | 344 | "start": { |
332 | "line": 124, | 345 | "line": 128, |
333 | "column": 13 | 346 | "column": 13 |
334 | }, | 347 | }, |
335 | "end": { | 348 | "end": { |
336 | "line": 127, | 349 | "line": 131, |
337 | "column": 3 | 350 | "column": 3 |
338 | } | 351 | } |
339 | } | 352 | } |
diff --git a/src/i18n/messages/src/components/ui/FeatureList.json b/src/i18n/messages/src/components/ui/FeatureList.json index 3201115b3..8d1dc4360 100644 --- a/src/i18n/messages/src/components/ui/FeatureList.json +++ b/src/i18n/messages/src/components/ui/FeatureList.json | |||
@@ -193,5 +193,18 @@ | |||
193 | "line": 68, | 193 | "line": 68, |
194 | "column": 3 | 194 | "column": 3 |
195 | } | 195 | } |
196 | }, | ||
197 | { | ||
198 | "id": "pricing.features.appDelaysEnabled", | ||
199 | "defaultMessage": "!!!Occasional Waiting Screens", | ||
200 | "file": "src/components/ui/FeatureList.js", | ||
201 | "start": { | ||
202 | "line": 69, | ||
203 | "column": 19 | ||
204 | }, | ||
205 | "end": { | ||
206 | "line": 72, | ||
207 | "column": 3 | ||
208 | } | ||
196 | } | 209 | } |
197 | ] \ No newline at end of file | 210 | ] \ No newline at end of file |
diff --git a/src/i18n/messages/src/containers/settings/EditServiceScreen.json b/src/i18n/messages/src/containers/settings/EditServiceScreen.json index 9b46a1e6f..36937ebf8 100644 --- a/src/i18n/messages/src/containers/settings/EditServiceScreen.json +++ b/src/i18n/messages/src/containers/settings/EditServiceScreen.json | |||
@@ -26,8 +26,8 @@ | |||
26 | } | 26 | } |
27 | }, | 27 | }, |
28 | { | 28 | { |
29 | "id": "settings.service.form.enableNotification", | 29 | "id": "settings.service.form.disableHibernation", |
30 | "defaultMessage": "!!!Enable Notifications", | 30 | "defaultMessage": "!!!Disable hibernation", |
31 | "file": "src/containers/settings/EditServiceScreen.js", | 31 | "file": "src/containers/settings/EditServiceScreen.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 36, | 33 | "line": 36, |
@@ -39,15 +39,28 @@ | |||
39 | } | 39 | } |
40 | }, | 40 | }, |
41 | { | 41 | { |
42 | "id": "settings.service.form.enableNotification", | ||
43 | "defaultMessage": "!!!Enable Notifications", | ||
44 | "file": "src/containers/settings/EditServiceScreen.js", | ||
45 | "start": { | ||
46 | "line": 40, | ||
47 | "column": 22 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 43, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
42 | "id": "settings.service.form.enableBadge", | 55 | "id": "settings.service.form.enableBadge", |
43 | "defaultMessage": "!!!Show unread message badges", | 56 | "defaultMessage": "!!!Show unread message badges", |
44 | "file": "src/containers/settings/EditServiceScreen.js", | 57 | "file": "src/containers/settings/EditServiceScreen.js", |
45 | "start": { | 58 | "start": { |
46 | "line": 40, | 59 | "line": 44, |
47 | "column": 15 | 60 | "column": 15 |
48 | }, | 61 | }, |
49 | "end": { | 62 | "end": { |
50 | "line": 43, | 63 | "line": 47, |
51 | "column": 3 | 64 | "column": 3 |
52 | } | 65 | } |
53 | }, | 66 | }, |
@@ -56,11 +69,11 @@ | |||
56 | "defaultMessage": "!!!Enable audio", | 69 | "defaultMessage": "!!!Enable audio", |
57 | "file": "src/containers/settings/EditServiceScreen.js", | 70 | "file": "src/containers/settings/EditServiceScreen.js", |
58 | "start": { | 71 | "start": { |
59 | "line": 44, | 72 | "line": 48, |
60 | "column": 15 | 73 | "column": 15 |
61 | }, | 74 | }, |
62 | "end": { | 75 | "end": { |
63 | "line": 47, | 76 | "line": 51, |
64 | "column": 3 | 77 | "column": 3 |
65 | } | 78 | } |
66 | }, | 79 | }, |
@@ -69,11 +82,11 @@ | |||
69 | "defaultMessage": "!!!Team", | 82 | "defaultMessage": "!!!Team", |
70 | "file": "src/containers/settings/EditServiceScreen.js", | 83 | "file": "src/containers/settings/EditServiceScreen.js", |
71 | "start": { | 84 | "start": { |
72 | "line": 48, | 85 | "line": 52, |
73 | "column": 8 | 86 | "column": 8 |
74 | }, | 87 | }, |
75 | "end": { | 88 | "end": { |
76 | "line": 51, | 89 | "line": 55, |
77 | "column": 3 | 90 | "column": 3 |
78 | } | 91 | } |
79 | }, | 92 | }, |
@@ -82,11 +95,11 @@ | |||
82 | "defaultMessage": "!!!Service URL", | 95 | "defaultMessage": "!!!Service URL", |
83 | "file": "src/containers/settings/EditServiceScreen.js", | 96 | "file": "src/containers/settings/EditServiceScreen.js", |
84 | "start": { | 97 | "start": { |
85 | "line": 52, | 98 | "line": 56, |
86 | "column": 13 | 99 | "column": 13 |
87 | }, | 100 | }, |
88 | "end": { | 101 | "end": { |
89 | "line": 55, | 102 | "line": 59, |
90 | "column": 3 | 103 | "column": 3 |
91 | } | 104 | } |
92 | }, | 105 | }, |
@@ -95,11 +108,11 @@ | |||
95 | "defaultMessage": "!!!Show message badge for all new messages", | 108 | "defaultMessage": "!!!Show message badge for all new messages", |
96 | "file": "src/containers/settings/EditServiceScreen.js", | 109 | "file": "src/containers/settings/EditServiceScreen.js", |
97 | "start": { | 110 | "start": { |
98 | "line": 56, | 111 | "line": 60, |
99 | "column": 20 | 112 | "column": 20 |
100 | }, | 113 | }, |
101 | "end": { | 114 | "end": { |
102 | "line": 59, | 115 | "line": 63, |
103 | "column": 3 | 116 | "column": 3 |
104 | } | 117 | } |
105 | }, | 118 | }, |
@@ -108,11 +121,11 @@ | |||
108 | "defaultMessage": "!!!Custom icon", | 121 | "defaultMessage": "!!!Custom icon", |
109 | "file": "src/containers/settings/EditServiceScreen.js", | 122 | "file": "src/containers/settings/EditServiceScreen.js", |
110 | "start": { | 123 | "start": { |
111 | "line": 60, | 124 | "line": 64, |
112 | "column": 8 | 125 | "column": 8 |
113 | }, | 126 | }, |
114 | "end": { | 127 | "end": { |
115 | "line": 63, | 128 | "line": 67, |
116 | "column": 3 | 129 | "column": 3 |
117 | } | 130 | } |
118 | }, | 131 | }, |
@@ -121,11 +134,11 @@ | |||
121 | "defaultMessage": "!!!Enable Dark Mode", | 134 | "defaultMessage": "!!!Enable Dark Mode", |
122 | "file": "src/containers/settings/EditServiceScreen.js", | 135 | "file": "src/containers/settings/EditServiceScreen.js", |
123 | "start": { | 136 | "start": { |
124 | "line": 64, | 137 | "line": 68, |
125 | "column": 18 | 138 | "column": 18 |
126 | }, | 139 | }, |
127 | "end": { | 140 | "end": { |
128 | "line": 67, | 141 | "line": 71, |
129 | "column": 3 | 142 | "column": 3 |
130 | } | 143 | } |
131 | }, | 144 | }, |
@@ -134,11 +147,11 @@ | |||
134 | "defaultMessage": "!!!Use Proxy", | 147 | "defaultMessage": "!!!Use Proxy", |
135 | "file": "src/containers/settings/EditServiceScreen.js", | 148 | "file": "src/containers/settings/EditServiceScreen.js", |
136 | "start": { | 149 | "start": { |
137 | "line": 68, | 150 | "line": 72, |
138 | "column": 15 | 151 | "column": 15 |
139 | }, | 152 | }, |
140 | "end": { | 153 | "end": { |
141 | "line": 71, | 154 | "line": 75, |
142 | "column": 3 | 155 | "column": 3 |
143 | } | 156 | } |
144 | }, | 157 | }, |
@@ -147,11 +160,11 @@ | |||
147 | "defaultMessage": "!!!Proxy Host/IP", | 160 | "defaultMessage": "!!!Proxy Host/IP", |
148 | "file": "src/containers/settings/EditServiceScreen.js", | 161 | "file": "src/containers/settings/EditServiceScreen.js", |
149 | "start": { | 162 | "start": { |
150 | "line": 72, | 163 | "line": 76, |
151 | "column": 13 | 164 | "column": 13 |
152 | }, | 165 | }, |
153 | "end": { | 166 | "end": { |
154 | "line": 75, | 167 | "line": 79, |
155 | "column": 3 | 168 | "column": 3 |
156 | } | 169 | } |
157 | }, | 170 | }, |
@@ -160,11 +173,11 @@ | |||
160 | "defaultMessage": "!!!Port", | 173 | "defaultMessage": "!!!Port", |
161 | "file": "src/containers/settings/EditServiceScreen.js", | 174 | "file": "src/containers/settings/EditServiceScreen.js", |
162 | "start": { | 175 | "start": { |
163 | "line": 76, | 176 | "line": 80, |
164 | "column": 13 | 177 | "column": 13 |
165 | }, | 178 | }, |
166 | "end": { | 179 | "end": { |
167 | "line": 79, | 180 | "line": 83, |
168 | "column": 3 | 181 | "column": 3 |
169 | } | 182 | } |
170 | }, | 183 | }, |
@@ -173,11 +186,11 @@ | |||
173 | "defaultMessage": "!!!User", | 186 | "defaultMessage": "!!!User", |
174 | "file": "src/containers/settings/EditServiceScreen.js", | 187 | "file": "src/containers/settings/EditServiceScreen.js", |
175 | "start": { | 188 | "start": { |
176 | "line": 80, | 189 | "line": 84, |
177 | "column": 13 | 190 | "column": 13 |
178 | }, | 191 | }, |
179 | "end": { | 192 | "end": { |
180 | "line": 83, | 193 | "line": 87, |
181 | "column": 3 | 194 | "column": 3 |
182 | } | 195 | } |
183 | }, | 196 | }, |
@@ -186,11 +199,11 @@ | |||
186 | "defaultMessage": "!!!Password", | 199 | "defaultMessage": "!!!Password", |
187 | "file": "src/containers/settings/EditServiceScreen.js", | 200 | "file": "src/containers/settings/EditServiceScreen.js", |
188 | "start": { | 201 | "start": { |
189 | "line": 84, | 202 | "line": 88, |
190 | "column": 17 | 203 | "column": 17 |
191 | }, | 204 | }, |
192 | "end": { | 205 | "end": { |
193 | "line": 87, | 206 | "line": 91, |
194 | "column": 3 | 207 | "column": 3 |
195 | } | 208 | } |
196 | } | 209 | } |
diff --git a/src/i18n/messages/src/containers/settings/EditSettingsScreen.json b/src/i18n/messages/src/containers/settings/EditSettingsScreen.json index 5e084c1e1..42199503b 100644 --- a/src/i18n/messages/src/containers/settings/EditSettingsScreen.json +++ b/src/i18n/messages/src/containers/settings/EditSettingsScreen.json | |||
@@ -300,7 +300,7 @@ | |||
300 | }, | 300 | }, |
301 | { | 301 | { |
302 | "id": "settings.app.form.adaptableDarkMode", | 302 | "id": "settings.app.form.adaptableDarkMode", |
303 | "defaultMessage": "!!!Synchronize dark mode with my Mac's dark mode setting", | 303 | "defaultMessage": "!!!Synchronize dark mode with my OS's dark mode setting", |
304 | "file": "src/containers/settings/EditSettingsScreen.js", | 304 | "file": "src/containers/settings/EditSettingsScreen.js", |
305 | "start": { | 305 | "start": { |
306 | "line": 121, | 306 | "line": 121, |
diff --git a/src/i18n/messages/src/features/recipeConnectionLost/components/WebControls.json b/src/i18n/messages/src/features/recipeConnectionLost/components/WebControls.json new file mode 100644 index 000000000..f3bcaf345 --- /dev/null +++ b/src/i18n/messages/src/features/recipeConnectionLost/components/WebControls.json | |||
@@ -0,0 +1,67 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "webControls.goHome", | ||
4 | "defaultMessage": "!!!Home", | ||
5 | "file": "src/features/recipeConnectionLost/components/WebControls.js", | ||
6 | "start": { | ||
7 | "line": 13, | ||
8 | "column": 10 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 16, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "webControls.openInBrowser", | ||
17 | "defaultMessage": "!!!Open in Browser", | ||
18 | "file": "src/features/recipeConnectionLost/components/WebControls.js", | ||
19 | "start": { | ||
20 | "line": 17, | ||
21 | "column": 17 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 20, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "webControls.back", | ||
30 | "defaultMessage": "!!!Back", | ||
31 | "file": "src/features/recipeConnectionLost/components/WebControls.js", | ||
32 | "start": { | ||
33 | "line": 21, | ||
34 | "column": 8 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 24, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "webControls.forward", | ||
43 | "defaultMessage": "!!!Forward", | ||
44 | "file": "src/features/recipeConnectionLost/components/WebControls.js", | ||
45 | "start": { | ||
46 | "line": 25, | ||
47 | "column": 11 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 28, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "webControls.reload", | ||
56 | "defaultMessage": "!!!Reload", | ||
57 | "file": "src/features/recipeConnectionLost/components/WebControls.js", | ||
58 | "start": { | ||
59 | "line": 29, | ||
60 | "column": 10 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 32, | ||
64 | "column": 3 | ||
65 | } | ||
66 | } | ||
67 | ] \ No newline at end of file | ||
diff --git a/src/index.js b/src/index.js index 594097288..e5f678759 100644 --- a/src/index.js +++ b/src/index.js | |||
@@ -37,6 +37,7 @@ import Tray from './lib/Tray'; | |||
37 | import Settings from './electron/Settings'; | 37 | import Settings from './electron/Settings'; |
38 | import handleDeepLink from './electron/deepLinking'; | 38 | import handleDeepLink from './electron/deepLinking'; |
39 | import { isPositionValid } from './electron/windowUtils'; | 39 | import { isPositionValid } from './electron/windowUtils'; |
40 | // import askFormacOSPermissions from './electron/macOSPermissions'; | ||
40 | import { appId } from './package.json'; // eslint-disable-line import/no-unresolved | 41 | import { appId } from './package.json'; // eslint-disable-line import/no-unresolved |
41 | import './electron/exception'; | 42 | import './electron/exception'; |
42 | 43 | ||
@@ -46,10 +47,14 @@ import { | |||
46 | } from './config'; | 47 | } from './config'; |
47 | import { asarPath } from './helpers/asar-helpers'; | 48 | import { asarPath } from './helpers/asar-helpers'; |
48 | import { isValidExternalURL } from './helpers/url-helpers'; | 49 | import { isValidExternalURL } from './helpers/url-helpers'; |
49 | /* eslint-enable import/first */ | 50 | import userAgent from './helpers/userAgent-helpers'; |
50 | 51 | ||
51 | const debug = require('debug')('Ferdi:App'); | 52 | const debug = require('debug')('Ferdi:App'); |
52 | 53 | ||
54 | // Globally set useragent to fix user agent override in service workers | ||
55 | debug('Set userAgent to ', userAgent()); | ||
56 | app.userAgentFallback = userAgent(); | ||
57 | |||
53 | // Keep a global reference of the window object, if you don't, the window will | 58 | // Keep a global reference of the window object, if you don't, the window will |
54 | // be closed automatically when the JavaScript object is garbage collected. | 59 | // be closed automatically when the JavaScript object is garbage collected. |
55 | let mainWindow; | 60 | let mainWindow; |
@@ -182,6 +187,7 @@ const createWindow = () => { | |||
182 | nodeIntegration: true, | 187 | nodeIntegration: true, |
183 | webviewTag: true, | 188 | webviewTag: true, |
184 | preload: path.join(__dirname, 'sentry.js'), | 189 | preload: path.join(__dirname, 'sentry.js'), |
190 | enableRemoteModule: true, | ||
185 | }, | 191 | }, |
186 | }); | 192 | }); |
187 | 193 | ||
@@ -291,6 +297,11 @@ const createWindow = () => { | |||
291 | } | 297 | } |
292 | }); | 298 | }); |
293 | 299 | ||
300 | // Asking for permissions like this currently crashes Ferdi | ||
301 | // if (isMac) { | ||
302 | // askFormacOSPermissions(); | ||
303 | // } | ||
304 | |||
294 | mainWindow.on('show', () => { | 305 | mainWindow.on('show', () => { |
295 | debug('Skip taskbar: true'); | 306 | debug('Skip taskbar: true'); |
296 | mainWindow.setSkipTaskbar(false); | 307 | mainWindow.setSkipTaskbar(false); |
diff --git a/src/internal-server b/src/internal-server | |||
Subproject 38fc9925d88971cee26cc08343da2f0e153c053 | Subproject 95ae59926dbd88d55a5377be997558a9e112ab4 | ||
diff --git a/src/models/Recipe.js b/src/models/Recipe.js index 6655f8310..dcb998a19 100644 --- a/src/models/Recipe.js +++ b/src/models/Recipe.js | |||
@@ -38,6 +38,8 @@ export default class Recipe { | |||
38 | 38 | ||
39 | disablewebsecurity = false; | 39 | disablewebsecurity = false; |
40 | 40 | ||
41 | autoHibernate = false; | ||
42 | |||
41 | constructor(data) { | 43 | constructor(data) { |
42 | if (!data) { | 44 | if (!data) { |
43 | throw Error('Recipe config not valid'); | 45 | throw Error('Recipe config not valid'); |
@@ -78,6 +80,8 @@ export default class Recipe { | |||
78 | 80 | ||
79 | this.disablewebsecurity = data.config.disablewebsecurity || this.disablewebsecurity; | 81 | this.disablewebsecurity = data.config.disablewebsecurity || this.disablewebsecurity; |
80 | 82 | ||
83 | this.autoHibernate = data.config.autoHibernate || this.autoHibernate; | ||
84 | |||
81 | this.message = data.config.message || this.message; | 85 | this.message = data.config.message || this.message; |
82 | } | 86 | } |
83 | 87 | ||
diff --git a/src/models/Service.js b/src/models/Service.js index f073ac9fc..dc8febe0b 100644 --- a/src/models/Service.js +++ b/src/models/Service.js | |||
@@ -2,6 +2,8 @@ import { autorun, computed, observable } from 'mobx'; | |||
2 | import normalizeUrl from 'normalize-url'; | 2 | import normalizeUrl from 'normalize-url'; |
3 | import path from 'path'; | 3 | import path from 'path'; |
4 | 4 | ||
5 | import userAgent from '../helpers/userAgent-helpers'; | ||
6 | |||
5 | const debug = require('debug')('Ferdi:Service'); | 7 | const debug = require('debug')('Ferdi:Service'); |
6 | 8 | ||
7 | export const RESTRICTION_TYPES = { | 9 | export const RESTRICTION_TYPES = { |
@@ -74,6 +76,20 @@ export default class Service { | |||
74 | 76 | ||
75 | @observable restrictionType = null; | 77 | @observable restrictionType = null; |
76 | 78 | ||
79 | @observable isHibernationEnabled = false; | ||
80 | |||
81 | @observable lastUsed = Date.now(); // timestamp | ||
82 | |||
83 | @observable lastPoll = null; | ||
84 | |||
85 | @observable lastPollAnswer = null; | ||
86 | |||
87 | @observable lostRecipeConnection = false; | ||
88 | |||
89 | @observable lostRecipeReloadAttempt = 0; | ||
90 | |||
91 | @observable chromelessUserAgent = false; | ||
92 | |||
77 | constructor(data, recipe) { | 93 | constructor(data, recipe) { |
78 | if (!data) { | 94 | if (!data) { |
79 | console.error('Service config not valid'); | 95 | console.error('Service config not valid'); |
@@ -119,6 +135,8 @@ export default class Service { | |||
119 | 135 | ||
120 | this.spellcheckerLanguage = data.spellcheckerLanguage !== undefined ? data.spellcheckerLanguage : this.spellcheckerLanguage; | 136 | this.spellcheckerLanguage = data.spellcheckerLanguage !== undefined ? data.spellcheckerLanguage : this.spellcheckerLanguage; |
121 | 137 | ||
138 | this.isHibernationEnabled = data.isHibernationEnabled !== undefined ? data.isHibernationEnabled : this.isHibernationEnabled; | ||
139 | |||
122 | this.recipe = recipe; | 140 | this.recipe = recipe; |
123 | 141 | ||
124 | autorun(() => { | 142 | autorun(() => { |
@@ -187,21 +205,34 @@ export default class Service { | |||
187 | } | 205 | } |
188 | 206 | ||
189 | @computed get userAgent() { | 207 | @computed get userAgent() { |
190 | let { userAgent } = window.navigator; | 208 | let ua = userAgent(this.chromelessUserAgent); |
191 | if (typeof this.recipe.overrideUserAgent === 'function') { | 209 | if (typeof this.recipe.overrideUserAgent === 'function') { |
192 | userAgent = this.recipe.overrideUserAgent(); | 210 | ua = this.recipe.overrideUserAgent(); |
193 | } | 211 | } |
194 | 212 | ||
195 | // Remove Ferdi as it can cause incompatabilities with services. | 213 | return ua; |
196 | // This way, Ferdi will look like a normal Chrome instance | ||
197 | userAgent = userAgent.replace(/(Ferdi|Electron)([^\s]+\s)/g, ''); | ||
198 | |||
199 | return userAgent; | ||
200 | } | 214 | } |
201 | 215 | ||
202 | initializeWebViewEvents({ handleIPCMessage, openWindow, stores }) { | 216 | initializeWebViewEvents({ handleIPCMessage, openWindow, stores }) { |
203 | const webContents = this.webview.getWebContents(); | 217 | const webContents = this.webview.getWebContents(); |
204 | 218 | ||
219 | const handleUserAgent = (url, forwardingHack = false) => { | ||
220 | if (url.startsWith('https://accounts.google.com')) { | ||
221 | if (!this.chromelessUserAgent) { | ||
222 | debug('Setting user agent to chromeless for url', url); | ||
223 | this.webview.setUserAgent(userAgent(true)); | ||
224 | if (forwardingHack) { | ||
225 | this.webview.loadURL(url); | ||
226 | } | ||
227 | this.chromelessUserAgent = true; | ||
228 | } | ||
229 | } else if (this.chromelessUserAgent) { | ||
230 | debug('Setting user agent to contain chrome'); | ||
231 | this.webview.setUserAgent(this.userAgent); | ||
232 | this.chromelessUserAgent = false; | ||
233 | } | ||
234 | }; | ||
235 | |||
205 | this.webview.addEventListener('ipc-message', e => handleIPCMessage({ | 236 | this.webview.addEventListener('ipc-message', e => handleIPCMessage({ |
206 | serviceId: this.id, | 237 | serviceId: this.id, |
207 | channel: e.channel, | 238 | channel: e.channel, |
@@ -209,7 +240,6 @@ export default class Service { | |||
209 | })); | 240 | })); |
210 | 241 | ||
211 | this.webview.addEventListener('new-window', (event, url, frameName, options) => { | 242 | this.webview.addEventListener('new-window', (event, url, frameName, options) => { |
212 | console.log('open window', event, url, frameName, options); | ||
213 | openWindow({ | 243 | openWindow({ |
214 | event, | 244 | event, |
215 | url, | 245 | url, |
@@ -218,6 +248,9 @@ export default class Service { | |||
218 | }); | 248 | }); |
219 | }); | 249 | }); |
220 | 250 | ||
251 | |||
252 | this.webview.addEventListener('will-navigate', event => handleUserAgent(event.url, true)); | ||
253 | |||
221 | this.webview.addEventListener('did-start-loading', (event) => { | 254 | this.webview.addEventListener('did-start-loading', (event) => { |
222 | debug('Did start load', this.name, event); | 255 | debug('Did start load', this.name, event); |
223 | 256 | ||
@@ -235,7 +268,10 @@ export default class Service { | |||
235 | }; | 268 | }; |
236 | 269 | ||
237 | this.webview.addEventListener('did-frame-finish-load', didLoad.bind(this)); | 270 | this.webview.addEventListener('did-frame-finish-load', didLoad.bind(this)); |
238 | this.webview.addEventListener('did-navigate', didLoad.bind(this)); | 271 | this.webview.addEventListener('did-navigate', (event) => { |
272 | handleUserAgent(event.url); | ||
273 | didLoad(); | ||
274 | }); | ||
239 | 275 | ||
240 | this.webview.addEventListener('did-fail-load', (event) => { | 276 | this.webview.addEventListener('did-fail-load', (event) => { |
241 | debug('Service failed to load', this.name, event); | 277 | debug('Service failed to load', this.name, event); |
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js index e2e3760a8..da6055e5f 100644 --- a/src/stores/AppStore.js +++ b/src/stores/AppStore.js | |||
@@ -218,13 +218,16 @@ export default class AppStore extends Store { | |||
218 | // macOS catalina notifications hack | 218 | // macOS catalina notifications hack |
219 | // notifications got stuck after upgrade but forcing a notification | 219 | // notifications got stuck after upgrade but forcing a notification |
220 | // via `new Notification` triggered the permission request | 220 | // via `new Notification` triggered the permission request |
221 | if (isMac && !localStorage.getItem(CATALINA_NOTIFICATION_HACK_KEY)) { | 221 | if (isMac) { |
222 | // eslint-disable-next-line no-new | 222 | if (!localStorage.getItem(CATALINA_NOTIFICATION_HACK_KEY)) { |
223 | new window.Notification('Welcome to Franz 5', { | 223 | debug('Triggering macOS Catalina notification permission trigger'); |
224 | body: 'Have a wonderful day & happy messaging.', | 224 | // eslint-disable-next-line no-new |
225 | }); | 225 | new window.Notification('Welcome to Franz 5', { |
226 | body: 'Have a wonderful day & happy messaging.', | ||
227 | }); | ||
226 | 228 | ||
227 | localStorage.setItem(CATALINA_NOTIFICATION_HACK_KEY, true); | 229 | localStorage.setItem(CATALINA_NOTIFICATION_HACK_KEY, true); |
230 | } | ||
228 | } | 231 | } |
229 | } | 232 | } |
230 | 233 | ||
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index 19e6f8299..80c7d7e81 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js | |||
@@ -5,7 +5,7 @@ import { | |||
5 | computed, | 5 | computed, |
6 | observable, | 6 | observable, |
7 | } from 'mobx'; | 7 | } from 'mobx'; |
8 | import { remove } from 'lodash'; | 8 | import { debounce, remove } from 'lodash'; |
9 | import ms from 'ms'; | 9 | import ms from 'ms'; |
10 | import fs from 'fs-extra'; | 10 | import fs from 'fs-extra'; |
11 | import path from 'path'; | 11 | import path from 'path'; |
@@ -127,6 +127,60 @@ export default class ServicesStore extends Store { | |||
127 | ); | 127 | ); |
128 | } | 128 | } |
129 | 129 | ||
130 | initialize() { | ||
131 | super.initialize(); | ||
132 | |||
133 | // Check services to become hibernated | ||
134 | this.serviceMaintenanceTick(); | ||
135 | } | ||
136 | |||
137 | teardown() { | ||
138 | super.teardown(); | ||
139 | |||
140 | // Stop checking services for hibernation | ||
141 | this.serviceMaintenanceTick.cancel(); | ||
142 | } | ||
143 | |||
144 | /** | ||
145 | * Сheck for services to become hibernated. | ||
146 | */ | ||
147 | serviceMaintenanceTick = debounce(() => { | ||
148 | this._serviceMaintenance(); | ||
149 | this.serviceMaintenanceTick(); | ||
150 | debug('Service maintenance tick'); | ||
151 | }, ms('10s')); | ||
152 | |||
153 | /** | ||
154 | * Run various maintenance tasks on services | ||
155 | */ | ||
156 | _serviceMaintenance() { | ||
157 | this.all.forEach((service) => { | ||
158 | // Defines which services should be hibernated. | ||
159 | if (!service.isActive && (Date.now() - service.lastUsed > ms('5m'))) { | ||
160 | // If service is stale for 5 min, hibernate it. | ||
161 | this._hibernate({ serviceId: service.id }); | ||
162 | } | ||
163 | |||
164 | if (service.lastPoll && (service.lastPoll) - service.lastPollAnswer > ms('30s')) { | ||
165 | // If service did not reply for more than 30s try to reload. | ||
166 | if (!service.isActive) { | ||
167 | if (this.stores.app.isOnline && service.lostRecipeReloadAttempt < 3) { | ||
168 | service.webview.reload(); | ||
169 | service.lostRecipeReloadAttempt += 1; | ||
170 | |||
171 | service.lostRecipeConnection = false; | ||
172 | } | ||
173 | } else { | ||
174 | service.lostRecipeConnection = true; | ||
175 | } | ||
176 | } else { | ||
177 | service.lostRecipeConnection = false; | ||
178 | service.lostRecipeReloadAttempt = 0; | ||
179 | } | ||
180 | }); | ||
181 | } | ||
182 | |||
183 | // Computed props | ||
130 | @computed get all() { | 184 | @computed get all() { |
131 | if (this.stores.user.isLoggedIn) { | 185 | if (this.stores.user.isLoggedIn) { |
132 | const services = this.allServicesRequest.execute().result; | 186 | const services = this.allServicesRequest.execute().result; |
@@ -379,6 +433,7 @@ export default class ServicesStore extends Store { | |||
379 | this.all[index].isActive = false; | 433 | this.all[index].isActive = false; |
380 | }); | 434 | }); |
381 | service.isActive = true; | 435 | service.isActive = true; |
436 | service.lastUsed = Date.now(); | ||
382 | 437 | ||
383 | // Update list of last used services | 438 | // Update list of last used services |
384 | this.lastUsedServices = this.lastUsedServices.filter(id => id !== serviceId); | 439 | this.lastUsedServices = this.lastUsedServices.filter(id => id !== serviceId); |
@@ -475,10 +530,16 @@ export default class ServicesStore extends Store { | |||
475 | const service = this.one(serviceId); | 530 | const service = this.one(serviceId); |
476 | 531 | ||
477 | if (channel === 'hello') { | 532 | if (channel === 'hello') { |
533 | debug('Received hello event from', serviceId); | ||
534 | |||
478 | this._initRecipePolling(service.id); | 535 | this._initRecipePolling(service.id); |
479 | this._initializeServiceRecipeInWebview(serviceId); | 536 | this._initializeServiceRecipeInWebview(serviceId); |
480 | this._shareSettingsWithServiceProcess(); | 537 | this._shareSettingsWithServiceProcess(); |
538 | } else if (channel === 'alive') { | ||
539 | service.lastPollAnswer = Date.now(); | ||
481 | } else if (channel === 'messages') { | 540 | } else if (channel === 'messages') { |
541 | debug(`Received unread message info from '${serviceId}'`, args[0]); | ||
542 | |||
482 | this.actions.service.setUnreadMessageCount({ | 543 | this.actions.service.setUnreadMessageCount({ |
483 | serviceId, | 544 | serviceId, |
484 | count: { | 545 | count: { |
@@ -600,6 +661,7 @@ export default class ServicesStore extends Store { | |||
600 | if (!service.isEnabled) return; | 661 | if (!service.isEnabled) return; |
601 | 662 | ||
602 | service.resetMessageCount(); | 663 | service.resetMessageCount(); |
664 | service.lostRecipeConnection = false; | ||
603 | 665 | ||
604 | // service.webview.loadURL(service.url); | 666 | // service.webview.loadURL(service.url); |
605 | service.webview.reload(); | 667 | service.webview.reload(); |
@@ -777,7 +839,7 @@ export default class ServicesStore extends Store { | |||
777 | const isMuted = isAppMuted || service.isMuted; | 839 | const isMuted = isAppMuted || service.isMuted; |
778 | 840 | ||
779 | if (isAttached) { | 841 | if (isAttached) { |
780 | service.webview.setAudioMuted(isMuted); | 842 | service.webview.audioMuted = isMuted; |
781 | } | 843 | } |
782 | }); | 844 | }); |
783 | } | 845 | } |
@@ -863,6 +925,7 @@ export default class ServicesStore extends Store { | |||
863 | service.webview.send('poll'); | 925 | service.webview.send('poll'); |
864 | 926 | ||
865 | service.timer = setTimeout(loop, delay); | 927 | service.timer = setTimeout(loop, delay); |
928 | service.lastPoll = Date.now(); | ||
866 | }; | 929 | }; |
867 | 930 | ||
868 | loop(); | 931 | loop(); |
diff --git a/src/webview/lib/RecipeWebview.js b/src/webview/lib/RecipeWebview.js index 4fac21c55..add5fffa6 100644 --- a/src/webview/lib/RecipeWebview.js +++ b/src/webview/lib/RecipeWebview.js | |||
@@ -14,6 +14,10 @@ class RecipeWebview { | |||
14 | this.loopFunc(); | 14 | this.loopFunc(); |
15 | 15 | ||
16 | debug('Poll event'); | 16 | debug('Poll event'); |
17 | |||
18 | // This event is for checking if the service recipe is still actively | ||
19 | // communicating with the client | ||
20 | ipcRenderer.sendToHost('alive'); | ||
17 | }); | 21 | }); |
18 | } | 22 | } |
19 | 23 | ||