diff options
author | 2019-09-03 20:33:00 +0200 | |
---|---|---|
committer | 2019-09-03 20:33:00 +0200 | |
commit | 3ca3e36cf7fce6b241e242a07cb4731760ee4265 (patch) | |
tree | 0796a3712aebbf695545892be19fc677e7acec8e | |
parent | Automatic i18n update (i18n.meetfranz.com) (diff) | |
parent | Update en-US.json (diff) | |
download | ferdium-app-3ca3e36cf7fce6b241e242a07cb4731760ee4265.tar.gz ferdium-app-3ca3e36cf7fce6b241e242a07cb4731760ee4265.tar.zst ferdium-app-3ca3e36cf7fce6b241e242a07cb4731760ee4265.zip |
Merge branch 'develop' into i18n
119 files changed, 4924 insertions, 1782 deletions
@@ -55,7 +55,8 @@ | |||
55 | "atob": true, | 55 | "atob": true, |
56 | "btoa": true, | 56 | "btoa": true, |
57 | "ga": true, | 57 | "ga": true, |
58 | "mocha": true | 58 | "mocha": true, |
59 | "Element": true | ||
59 | }, | 60 | }, |
60 | "env": { | 61 | "env": { |
61 | "jest/globals": true | 62 | "jest/globals": true |
diff --git a/CHANGELOG.md b/CHANGELOG.md index 45743b931..da7a6c608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
@@ -1,9 +1,70 @@ | |||
1 | # [5.2.0-beta.1](https://github.com/meetfranz/franz/compare/v5.1.0...v5.2.0-beta.1) (2019-06-11) | 1 | ## [5.2.1-beta.1](https://github.com/meetfranz/franz/compare/v5.2.0...v5.2.1-beta.1) (2019-07-30) |
2 | |||
3 | |||
4 | ### Bug Fixes | ||
5 | |||
6 | * **Notifications:** Fix issue that blocked notifications from e.g. Slack ([44c413b](https://github.com/meetfranz/franz/commit/44c413b)) | ||
2 | 7 | ||
3 | 8 | ||
4 | ### Features | 9 | ### Features |
5 | 10 | ||
6 | * **App:** Update electron to 5.0.2 ([5828062](https://github.com/meetfranz/franz/commit/5828062)) | 11 | * **App:** Add option to copy debug information via the help menu ([4666e85](https://github.com/meetfranz/franz/commit/4666e85)) |
12 | |||
13 | |||
14 | |||
15 | # [5.2.0](https://github.com/meetfranz/franz/compare/v5.2.0-beta.4...v5.2.0) (2019-07-19) | ||
16 | |||
17 | ### Features | ||
18 | * **Service:** You can now add any custom website 🥳 | ||
19 | |||
20 | ### Bug Fixes | ||
21 | |||
22 | * **Notifications:** Don't show notification badges when app is muted ([e844a64](https://github.com/meetfranz/franz/commit/e844a64)) | ||
23 | * **Settings:** Fix position of settings window | ||
24 | * **Recipes:** Fix recipe install when directly accessing recipe e.g. via url ([eba50bc](https://github.com/meetfranz/franz/commit/eba50bc)) | ||
25 | * **Proxy:** Fix issue with service proxy authentication ([b9e5b23](https://github.com/meetfranz/franz/commit/b9e5b23)) | ||
26 | * **Announcements:** Fix issue with rendering announcements in workspaces ([1e38ec5](https://github.com/meetfranz/franz/commit/1e38ec5)) | ||
27 | * **Windows:** Add Workspaces menu & fix Window menu ([92a61d4](https://github.com/meetfranz/franz/commit/92a61d4)) | ||
28 | * **Windows:** Replace tray icon with high-res version ([a5eb399](https://github.com/meetfranz/franz/commit/a5eb399)) | ||
29 | * **Workspaces:** Fix service reordering within workspaces ([17f3a22](https://github.com/meetfranz/franz/commit/17f3a22)) | ||
30 | * **Workspaces:** Fix issue with service visibility after downgrade ([05294](https://github.com/meetfranz/franz/commit/05294)) | ||
31 | |||
32 | ### General | ||
33 | * **App:** Improved email validation ([dd8ddcc](https://github.com/meetfranz/franz/commit/dd8ddcc)) ([@Snuggle](https://github.com/Snuggle)) | ||
34 | * **App:** Update electron to 4.2.4 ([404c87a](https://github.com/meetfranz/franz/commit/404c87a)) | ||
35 | * **Translations:** Improved translations. **[A million thanks to the amazing community. 🎉](http://i18n.meetfranz.com/)** | ||
36 | |||
37 | |||
38 | # [5.2.0-beta.4](https://github.com/meetfranz/franz/compare/v5.2.0-beta.3...v5.2.0-beta.4) (2019-07-01) | ||
39 | |||
40 | |||
41 | ### Bug Fixes | ||
42 | |||
43 | * **Notifications:** Don't show notification badges when app is muted ([e844a64](https://github.com/meetfranz/franz/commit/e844a64)) | ||
44 | * **Settings:** Fix position of settings window | ||
45 | |||
46 | ### General | ||
47 | |||
48 | * **Translations:** Improved translations. **[A million thanks to the amazing community. 🎉](http://i18n.meetfranz.com/)** | ||
49 | |||
50 | |||
51 | # [5.2.0-beta.3](https://github.com/meetfranz/franz/compare/v5.2.0-beta.2...v5.2.0-beta.3) (2019-06-24) | ||
52 | |||
53 | ### General | ||
54 | |||
55 | * **App:** Downgraded electron to 4.2.4 ([404c87a](https://github.com/meetfranz/franz/commit/404c87a)) | ||
56 | |||
57 | |||
58 | # [5.2.0-beta.2](https://github.com/meetfranz/franz/compare/v5.2.0-beta.1...v5.2.0-beta.2) (2019-06-12) | ||
59 | |||
60 | |||
61 | ### Bug Fixes | ||
62 | |||
63 | * **Recipes:** Fix recipe install when directly accessing recipe ([eba50bc](https://github.com/meetfranz/franz/commit/eba50bc)) | ||
64 | |||
65 | |||
66 | |||
67 | # [5.2.0-beta.1](https://github.com/meetfranz/franz/compare/v5.1.0...v5.2.0-beta.1) (2019-06-11) | ||
7 | 68 | ||
8 | 69 | ||
9 | ### Bug Fixes | 70 | ### Bug Fixes |
@@ -13,6 +74,13 @@ | |||
13 | * **Announcements:** Fixes issue with rendering announcements in workspaces ([1e38ec5](https://github.com/meetfranz/franz/commit/1e38ec5)) | 74 | * **Announcements:** Fixes issue with rendering announcements in workspaces ([1e38ec5](https://github.com/meetfranz/franz/commit/1e38ec5)) |
14 | * **Windows:** Add Workspaces menu & fix Window menu ([92a61d4](https://github.com/meetfranz/franz/commit/92a61d4)) | 75 | * **Windows:** Add Workspaces menu & fix Window menu ([92a61d4](https://github.com/meetfranz/franz/commit/92a61d4)) |
15 | * **Windows:** Replace tray icon with high-res version ([a5eb399](https://github.com/meetfranz/franz/commit/a5eb399)) | 76 | * **Windows:** Replace tray icon with high-res version ([a5eb399](https://github.com/meetfranz/franz/commit/a5eb399)) |
77 | * **App:** Improved email validation ([dd8ddcc](https://github.com/meetfranz/franz/commit/dd8ddcc)) ([@Snuggle](https://github.com/Snuggle)) | ||
78 | |||
79 | |||
80 | ### General | ||
81 | |||
82 | * **Translations:** Improved translations. **[A million thanks to the amazing community. 🎉](http://i18n.meetfranz.com/)** | ||
83 | * **App:** Update electron to 5.0.2 ([5828062](https://github.com/meetfranz/franz/commit/5828062)) | ||
16 | 84 | ||
17 | 85 | ||
18 | 86 | ||
diff --git a/package-lock.json b/package-lock.json index 77575ad56..048425eb6 100644 --- a/package-lock.json +++ b/package-lock.json | |||
@@ -1,6 +1,6 @@ | |||
1 | { | 1 | { |
2 | "name": "franz", | 2 | "name": "franz", |
3 | "version": "5.2.0-beta.1", | 3 | "version": "5.2.1-beta.1", |
4 | "lockfileVersion": 1, | 4 | "lockfileVersion": 1, |
5 | "requires": true, | 5 | "requires": true, |
6 | "dependencies": { | 6 | "dependencies": { |
@@ -2149,9 +2149,9 @@ | |||
2149 | } | 2149 | } |
2150 | }, | 2150 | }, |
2151 | "@mdi/js": { | 2151 | "@mdi/js": { |
2152 | "version": "3.4.93", | 2152 | "version": "4.2.95", |
2153 | "resolved": "https://registry.npmjs.org/@mdi/js/-/js-3.4.93.tgz", | 2153 | "resolved": "https://registry.npmjs.org/@mdi/js/-/js-4.2.95.tgz", |
2154 | "integrity": "sha512-SEzolEqT8ErlWdHz4AAtQ1lTfAnM6j67Ppm6k5s/I1aIuuoFP/D8d/z838C28xHO1KOqrsS1fw2wlf6fRiEEJA==" | 2154 | "integrity": "sha512-3qqOZx2HkrQEUc9fr5MiQWlokwmO8TK5bQZ2EP1Rg0q2Q507jy+fUeL8lb9ko2ossYqoPnugIr7jI0/O7uhlrA==" |
2155 | }, | 2155 | }, |
2156 | "@mdi/react": { | 2156 | "@mdi/react": { |
2157 | "version": "1.1.0", | 2157 | "version": "1.1.0", |
@@ -2173,13 +2173,17 @@ | |||
2173 | "requires": { | 2173 | "requires": { |
2174 | "@mdi/js": "^3.3.92", | 2174 | "@mdi/js": "^3.3.92", |
2175 | "@mdi/react": "^1.1.0", | 2175 | "@mdi/react": "^1.1.0", |
2176 | "@meetfranz/theme": "^1.0.13", | 2176 | "@meetfranz/theme": "^1.0.14", |
2177 | "react-html-attributes": "^1.4.3", | 2177 | "react-html-attributes": "^1.4.3", |
2178 | "react-loader": "^2.4.5" | 2178 | "react-loader": "^2.4.5" |
2179 | }, | 2179 | }, |
2180 | "dependencies": { | 2180 | "dependencies": { |
2181 | "@mdi/js": { | ||
2182 | "version": "3.9.97", | ||
2183 | "bundled": true | ||
2184 | }, | ||
2181 | "@meetfranz/theme": { | 2185 | "@meetfranz/theme": { |
2182 | "version": "1.0.13", | 2186 | "version": "1.0.14", |
2183 | "bundled": true, | 2187 | "bundled": true, |
2184 | "requires": { | 2188 | "requires": { |
2185 | "color": "^3.1.0" | 2189 | "color": "^3.1.0" |
@@ -2198,12 +2202,16 @@ | |||
2198 | "requires": { | 2202 | "requires": { |
2199 | "@mdi/js": "^3.3.92", | 2203 | "@mdi/js": "^3.3.92", |
2200 | "@mdi/react": "^1.1.0", | 2204 | "@mdi/react": "^1.1.0", |
2201 | "@meetfranz/theme": "^1.0.13", | 2205 | "@meetfranz/theme": "^1.0.14", |
2202 | "react-loader": "^2.4.5" | 2206 | "react-loader": "^2.4.5" |
2203 | }, | 2207 | }, |
2204 | "dependencies": { | 2208 | "dependencies": { |
2209 | "@mdi/js": { | ||
2210 | "version": "3.9.97", | ||
2211 | "bundled": true | ||
2212 | }, | ||
2205 | "@meetfranz/theme": { | 2213 | "@meetfranz/theme": { |
2206 | "version": "1.0.13", | 2214 | "version": "1.0.14", |
2207 | "bundled": true, | 2215 | "bundled": true, |
2208 | "requires": { | 2216 | "requires": { |
2209 | "color": "^3.1.0" | 2217 | "color": "^3.1.0" |
@@ -6803,9 +6811,9 @@ | |||
6803 | "dev": true | 6811 | "dev": true |
6804 | }, | 6812 | }, |
6805 | "electron": { | 6813 | "electron": { |
6806 | "version": "5.0.2", | 6814 | "version": "4.2.4", |
6807 | "resolved": "https://registry.npmjs.org/electron/-/electron-5.0.2.tgz", | 6815 | "resolved": "https://registry.npmjs.org/electron/-/electron-4.2.4.tgz", |
6808 | "integrity": "sha512-bUHKQhyuOen/q8iHTkrnzqB9CAwBDI+vHbeu21kpq2bqAD+t25yfrmUEcYHaPL4fZOAhk6nnRqskF6/Xd+aZxg==", | 6816 | "integrity": "sha512-d4wEwJluMsRyRgbukLmFVTb6l1J+mc3RLB1ctbpMlSWDFvs+zknPWa+cHBzTWwrdgwINLddr69qsAW1ku6FqYw==", |
6809 | "dev": true, | 6817 | "dev": true, |
6810 | "requires": { | 6818 | "requires": { |
6811 | "@types/node": "^10.12.18", | 6819 | "@types/node": "^10.12.18", |
@@ -6814,9 +6822,9 @@ | |||
6814 | }, | 6822 | }, |
6815 | "dependencies": { | 6823 | "dependencies": { |
6816 | "@types/node": { | 6824 | "@types/node": { |
6817 | "version": "10.14.4", | 6825 | "version": "10.14.9", |
6818 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.4.tgz", | 6826 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.9.tgz", |
6819 | "integrity": "sha512-DT25xX/YgyPKiHFOpNuANIQIVvYEwCWXgK2jYYwqgaMrYE6+tq+DtmMwlD3drl6DJbUwtlIDnn0d7tIn/EbXBg==", | 6827 | "integrity": "sha512-NelG/dSahlXYtSoVPErrp06tYFrvzj8XLWmKA+X8x0W//4MqbUyZu++giUG/v0bjAT6/Qxa8IjodrfdACyb0Fg==", |
6820 | "dev": true | 6828 | "dev": true |
6821 | } | 6829 | } |
6822 | } | 6830 | } |
@@ -7043,12 +7051,14 @@ | |||
7043 | } | 7051 | } |
7044 | }, | 7052 | }, |
7045 | "electron-hunspell": { | 7053 | "electron-hunspell": { |
7046 | "version": "1.0.0-beta.7", | 7054 | "version": "0.1.1", |
7047 | "resolved": "https://registry.npmjs.org/electron-hunspell/-/electron-hunspell-1.0.0-beta.7.tgz", | 7055 | "resolved": "https://registry.npmjs.org/electron-hunspell/-/electron-hunspell-0.1.1.tgz", |
7048 | "integrity": "sha512-BByCXqU8sZbuzyoxKcBYjycp8ORiqjeYZd2OT8RNjVW+XGPmZkHewXUu4tUa1IXW6ij6IqojV5kr+xhYKLN1DA==", | 7056 | "integrity": "sha512-B3nOQqHexIX+8bz72FZkNk+iFBrdqS9DpV2SaH+t7T9SLbONBVBRLJ2Jj2ytXFUzvw81q7vz2dfxPCddh/E3ww==", |
7049 | "requires": { | 7057 | "requires": { |
7050 | "hunspell-asm": "^2.0.0", | 7058 | "hunspell-asm": "1.0.2", |
7051 | "tslib": "1.9.3" | 7059 | "lodash": "^4.17.11", |
7060 | "tslib": "1.9.3", | ||
7061 | "unixify": "1.0.0" | ||
7052 | } | 7062 | } |
7053 | }, | 7063 | }, |
7054 | "electron-is-dev": { | 7064 | "electron-is-dev": { |
@@ -11379,34 +11389,14 @@ | |||
11379 | } | 11389 | } |
11380 | }, | 11390 | }, |
11381 | "hunspell-asm": { | 11391 | "hunspell-asm": { |
11382 | "version": "2.0.0", | 11392 | "version": "1.0.2", |
11383 | "resolved": "https://registry.npmjs.org/hunspell-asm/-/hunspell-asm-2.0.0.tgz", | 11393 | "resolved": "https://registry.npmjs.org/hunspell-asm/-/hunspell-asm-1.0.2.tgz", |
11384 | "integrity": "sha512-FMIUBpy+bRREFAvC63RcYEK9U6+FdlEojGSVsvMTpuZ2CekYyUBwEfG4+ExIQOQyEN0U6f1MoVgrFqvgPNSA2g==", | 11394 | "integrity": "sha512-UTLBvc0yZiIcHl9qrgxnFTZbX3zF4CprzEY+u+N0iXlUKZnUJRIgvgppTdgiQTsucm5b0aN/rHsgXz2q/0kBRA==", |
11385 | "requires": { | 11395 | "requires": { |
11386 | "emscripten-wasm-loader": "^2.2.3", | 11396 | "emscripten-wasm-loader": "^1.0.0", |
11387 | "nanoid": "^2.0.1", | 11397 | "nanoid": "^1.0.2", |
11388 | "tslib": "^1.9.3", | 11398 | "tslib": "^1.9.0", |
11389 | "unixify": "^1.0.0" | 11399 | "unixify": "^1.0.0" |
11390 | }, | ||
11391 | "dependencies": { | ||
11392 | "emscripten-wasm-loader": { | ||
11393 | "version": "2.2.3", | ||
11394 | "resolved": "https://registry.npmjs.org/emscripten-wasm-loader/-/emscripten-wasm-loader-2.2.3.tgz", | ||
11395 | "integrity": "sha512-//gI0afvtVnY7smttrPOW/BM+pTJLmdIcXAQV3fgRdQ0o6wm2vdSI0kjLYVOeo/rbtRsGgVuMLu6fT+O//EfaA==", | ||
11396 | "requires": { | ||
11397 | "getroot": "^1.0.0", | ||
11398 | "nanoid": "^1.3.4", | ||
11399 | "tslib": "^1.9.3", | ||
11400 | "unixify": "^1.0.0" | ||
11401 | }, | ||
11402 | "dependencies": { | ||
11403 | "nanoid": { | ||
11404 | "version": "1.3.4", | ||
11405 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-1.3.4.tgz", | ||
11406 | "integrity": "sha512-4ug4BsuHxiVHoRUe1ud6rUFT3WUMmjXt1W0quL0CviZQANdan7D8kqN5/maw53hmAApY/jfzMRkC57BNNs60ZQ==" | ||
11407 | } | ||
11408 | } | ||
11409 | } | ||
11410 | } | 11400 | } |
11411 | }, | 11401 | }, |
11412 | "husky": { | 11402 | "husky": { |
@@ -14385,9 +14375,9 @@ | |||
14385 | "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==" | 14375 | "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==" |
14386 | }, | 14376 | }, |
14387 | "nanoid": { | 14377 | "nanoid": { |
14388 | "version": "2.0.3", | 14378 | "version": "1.3.4", |
14389 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.0.3.tgz", | 14379 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-1.3.4.tgz", |
14390 | "integrity": "sha512-NbaoqdhIYmY6FXDRB4eYtDVC9Z9eCbn8TyaiC16LNKtpPv/aqa0tOPD8y6gNE4yUNnaZ7LLhYtXOev/6+cBtfw==" | 14380 | "integrity": "sha512-4ug4BsuHxiVHoRUe1ud6rUFT3WUMmjXt1W0quL0CviZQANdan7D8kqN5/maw53hmAApY/jfzMRkC57BNNs60ZQ==" |
14391 | }, | 14381 | }, |
14392 | "nanomatch": { | 14382 | "nanomatch": { |
14393 | "version": "1.2.13", | 14383 | "version": "1.2.13", |
@@ -16766,6 +16756,14 @@ | |||
16766 | "react-transition-group": "^1.2.0" | 16756 | "react-transition-group": "^1.2.0" |
16767 | } | 16757 | } |
16768 | }, | 16758 | }, |
16759 | "react-confetti": { | ||
16760 | "version": "3.1.0", | ||
16761 | "resolved": "https://registry.npmjs.org/react-confetti/-/react-confetti-3.1.0.tgz", | ||
16762 | "integrity": "sha512-T1DKt09C9rrf2BJ0OxFu8saPohFalOJfOgci11/ePz6DxbY+0cd/3CMimxj/ZITl7jQWnmC/bNWBgGheke3WZQ==", | ||
16763 | "requires": { | ||
16764 | "tween-functions": "^1.2.0" | ||
16765 | } | ||
16766 | }, | ||
16769 | "react-dom": { | 16767 | "react-dom": { |
16770 | "version": "16.6.3", | 16768 | "version": "16.6.3", |
16771 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.6.3.tgz", | 16769 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.6.3.tgz", |
@@ -19917,6 +19915,11 @@ | |||
19917 | "safe-buffer": "^5.0.1" | 19915 | "safe-buffer": "^5.0.1" |
19918 | } | 19916 | } |
19919 | }, | 19917 | }, |
19918 | "tween-functions": { | ||
19919 | "version": "1.2.0", | ||
19920 | "resolved": "https://registry.npmjs.org/tween-functions/-/tween-functions-1.2.0.tgz", | ||
19921 | "integrity": "sha1-GuOlDnxguz3vd06scHrLynO7w/8=" | ||
19922 | }, | ||
19920 | "tweetnacl": { | 19923 | "tweetnacl": { |
19921 | "version": "0.14.5", | 19924 | "version": "0.14.5", |
19922 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", | 19925 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", |
diff --git a/package.json b/package.json index 3df95362d..d30fa08c5 100644 --- a/package.json +++ b/package.json | |||
@@ -2,7 +2,7 @@ | |||
2 | "name": "franz", | 2 | "name": "franz", |
3 | "productName": "Franz", | 3 | "productName": "Franz", |
4 | "appId": "com.meetfranz.franz", | 4 | "appId": "com.meetfranz.franz", |
5 | "version": "5.2.0-beta.1", | 5 | "version": "5.2.1-beta.1", |
6 | "description": "Messaging app for WhatsApp, Slack, Telegram, HipChat, Hangouts and many many more.", | 6 | "description": "Messaging app for WhatsApp, Slack, Telegram, HipChat, Hangouts and many many more.", |
7 | "copyright": "adlk x franz - Stefan Malzner", | 7 | "copyright": "adlk x franz - Stefan Malzner", |
8 | "main": "index.js", | 8 | "main": "index.js", |
@@ -36,6 +36,7 @@ | |||
36 | "dependencies": { | 36 | "dependencies": { |
37 | "@babel/polyfill": "7.4.4", | 37 | "@babel/polyfill": "7.4.4", |
38 | "@babel/runtime": "7.4.5", | 38 | "@babel/runtime": "7.4.5", |
39 | "@mdi/js": "4.2.95", | ||
39 | "@meetfranz/electron-notification-state": "1.0.0", | 40 | "@meetfranz/electron-notification-state": "1.0.0", |
40 | "@meetfranz/forms": "file:packages/forms", | 41 | "@meetfranz/forms": "file:packages/forms", |
41 | "@meetfranz/theme": "file:packages/theme", | 42 | "@meetfranz/theme": "file:packages/theme", |
@@ -47,7 +48,7 @@ | |||
47 | "du": "^0.1.0", | 48 | "du": "^0.1.0", |
48 | "electron-dl": "1.12.0", | 49 | "electron-dl": "1.12.0", |
49 | "electron-fetch": "1.3.0", | 50 | "electron-fetch": "1.3.0", |
50 | "electron-hunspell": "1.0.0-beta.7", | 51 | "electron-hunspell": "0.1.1", |
51 | "electron-is-dev": "1.0.1", | 52 | "electron-is-dev": "1.0.1", |
52 | "electron-react-titlebar": "0.8.1", | 53 | "electron-react-titlebar": "0.8.1", |
53 | "electron-updater": "4.0.6", | 54 | "electron-updater": "4.0.6", |
@@ -71,6 +72,7 @@ | |||
71 | "prop-types": "^15.5.10", | 72 | "prop-types": "^15.5.10", |
72 | "react": "16.6.3", | 73 | "react": "16.6.3", |
73 | "react-addons-css-transition-group": "15.6.2", | 74 | "react-addons-css-transition-group": "15.6.2", |
75 | "react-confetti": "3.1.0", | ||
74 | "react-dom": "16.6.3", | 76 | "react-dom": "16.6.3", |
75 | "react-dropzone": "7.0.1", | 77 | "react-dropzone": "7.0.1", |
76 | "react-electron-web-view": "^2.0.1", | 78 | "react-electron-web-view": "^2.0.1", |
@@ -118,7 +120,7 @@ | |||
118 | "cross-env": "^5.0.5", | 120 | "cross-env": "^5.0.5", |
119 | "cz-conventional-changelog": "2.1.0", | 121 | "cz-conventional-changelog": "2.1.0", |
120 | "dotenv": "^4.0.0", | 122 | "dotenv": "^4.0.0", |
121 | "electron": "5.0.2", | 123 | "electron": "4.2.4", |
122 | "electron-builder": "20.40.2", | 124 | "electron-builder": "20.40.2", |
123 | "electron-rebuild": "1.8.4", | 125 | "electron-rebuild": "1.8.4", |
124 | "eslint": "5.10.0", | 126 | "eslint": "5.10.0", |
diff --git a/packages/forms/package.json b/packages/forms/package.json index d50f4c756..bb76462d8 100644 --- a/packages/forms/package.json +++ b/packages/forms/package.json | |||
@@ -1,6 +1,6 @@ | |||
1 | { | 1 | { |
2 | "name": "@meetfranz/forms", | 2 | "name": "@meetfranz/forms", |
3 | "version": "1.0.16", | 3 | "version": "1.1.0", |
4 | "description": "React form components for Franz", | 4 | "description": "React form components for Franz", |
5 | "main": "lib/index.js", | 5 | "main": "lib/index.js", |
6 | "scripts": { | 6 | "scripts": { |
@@ -35,5 +35,5 @@ | |||
35 | "react-dom": "16.7.0", | 35 | "react-dom": "16.7.0", |
36 | "react-jss": "^8.6.1" | 36 | "react-jss": "^8.6.1" |
37 | }, | 37 | }, |
38 | "gitHead": "9f2ab40b7602bc3df26ebb093b484b9917768f69" | 38 | "gitHead": "e1e46986d902adc4c19ee009016290f9733a7d61" |
39 | } | 39 | } |
diff --git a/packages/forms/src/button/index.tsx b/packages/forms/src/button/index.tsx index 9faedc8f1..b53c2da05 100644 --- a/packages/forms/src/button/index.tsx +++ b/packages/forms/src/button/index.tsx | |||
@@ -1,4 +1,3 @@ | |||
1 | import * as mdiIcons from '@mdi/js'; | ||
2 | import Icon from '@mdi/react'; | 1 | import Icon from '@mdi/react'; |
3 | import { Theme } from '@meetfranz/theme'; | 2 | import { Theme } from '@meetfranz/theme'; |
4 | import classnames from 'classnames'; | 3 | import classnames from 'classnames'; |
@@ -21,7 +20,7 @@ interface IProps extends IFormField, IWithStyle { | |||
21 | stretch?: boolean; | 20 | stretch?: boolean; |
22 | loaded?: boolean; | 21 | loaded?: boolean; |
23 | busy?: boolean; | 22 | busy?: boolean; |
24 | icon?: keyof typeof mdiIcons; | 23 | icon?: string; |
25 | href?: string; | 24 | href?: string; |
26 | target?: string; | 25 | target?: string; |
27 | } | 26 | } |
@@ -175,7 +174,7 @@ class ButtonComponent extends Component<IProps> { | |||
175 | onClick, | 174 | onClick, |
176 | buttonType, | 175 | buttonType, |
177 | loaded, | 176 | loaded, |
178 | icon: iconName, | 177 | icon, |
179 | busy: busyProp, | 178 | busy: busyProp, |
180 | href, | 179 | href, |
181 | target, | 180 | target, |
@@ -185,13 +184,6 @@ class ButtonComponent extends Component<IProps> { | |||
185 | busy, | 184 | busy, |
186 | } = this.state; | 185 | } = this.state; |
187 | 186 | ||
188 | let icon = ''; | ||
189 | if (iconName && mdiIcons[iconName]) { | ||
190 | icon = mdiIcons[iconName]; | ||
191 | } else if (iconName && !mdiIcons[iconName]) { | ||
192 | console.warn(`Icon '${iconName}' was not found`); | ||
193 | } | ||
194 | |||
195 | let showLoader = false; | 187 | let showLoader = false; |
196 | if (loaded) { | 188 | if (loaded) { |
197 | showLoader = !loaded; | 189 | showLoader = !loaded; |
diff --git a/packages/theme/src/themes/dark/index.ts b/packages/theme/src/themes/dark/index.ts index bd9f001e8..93c18efde 100644 --- a/packages/theme/src/themes/dark/index.ts +++ b/packages/theme/src/themes/dark/index.ts | |||
@@ -118,3 +118,28 @@ export const announcements = merge({}, defaultStyles.announcements, { | |||
118 | background: legacyStyles.darkThemeGrayDark, | 118 | background: legacyStyles.darkThemeGrayDark, |
119 | }, | 119 | }, |
120 | }); | 120 | }); |
121 | |||
122 | // Signup | ||
123 | export const signup = merge({}, defaultStyles.signup, { | ||
124 | pricing: { | ||
125 | feature: { | ||
126 | background: legacyStyles.darkThemeGrayLight, | ||
127 | border: color(legacyStyles.darkThemeGrayLight).lighten(0.2).hex(), | ||
128 | }, | ||
129 | }, | ||
130 | }); | ||
131 | |||
132 | // Todos | ||
133 | export const todos = merge({}, defaultStyles.todos, { | ||
134 | todosLayer: { | ||
135 | borderLeftColor: legacyStyles.darkThemeGrayDarker, | ||
136 | }, | ||
137 | toggleButton: { | ||
138 | background: defaultStyles.styleTypes.primary.accent, | ||
139 | textColor: defaultStyles.styleTypes.primary.contrast, | ||
140 | shadowColor: 'rgba(0, 0, 0, 0.2)', | ||
141 | }, | ||
142 | dragIndicator: { | ||
143 | background: legacyStyles.themeGrayLight, | ||
144 | }, | ||
145 | }); | ||
diff --git a/packages/theme/src/themes/default/index.ts b/packages/theme/src/themes/default/index.ts index 0f02fa3c8..7edf8331f 100644 --- a/packages/theme/src/themes/default/index.ts +++ b/packages/theme/src/themes/default/index.ts | |||
@@ -207,3 +207,31 @@ export const announcements = { | |||
207 | background: legacyStyles.themeGrayLightest, | 207 | background: legacyStyles.themeGrayLightest, |
208 | }, | 208 | }, |
209 | }; | 209 | }; |
210 | |||
211 | // Signup | ||
212 | export const signup = { | ||
213 | pricing: { | ||
214 | feature: { | ||
215 | background: legacyStyles.themeGrayLightest, | ||
216 | border: legacyStyles.themeGrayLighter, | ||
217 | }, | ||
218 | }, | ||
219 | }; | ||
220 | |||
221 | // Todos | ||
222 | export const todos = { | ||
223 | todosLayer: { | ||
224 | borderLeftColor: legacyStyles.themeGrayLighter, | ||
225 | }, | ||
226 | toggleButton: { | ||
227 | background: styleTypes.primary.accent, | ||
228 | textColor: styleTypes.primary.contrast, | ||
229 | shadowColor: 'rgba(0, 0, 0, 0.2)', | ||
230 | }, | ||
231 | dragIndicator: { | ||
232 | background: legacyStyles.themeGrayLight, | ||
233 | }, | ||
234 | resizeHandler: { | ||
235 | backgroundHover: styleTypes.primary.accent, | ||
236 | }, | ||
237 | }; | ||
diff --git a/packages/ui/package.json b/packages/ui/package.json index a851ed9cf..4f42b21b5 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json | |||
@@ -1,6 +1,6 @@ | |||
1 | { | 1 | { |
2 | "name": "@meetfranz/ui", | 2 | "name": "@meetfranz/ui", |
3 | "version": "0.0.9", | 3 | "version": "1.0.0", |
4 | "description": "React UI components for Franz", | 4 | "description": "React UI components for Franz", |
5 | "main": "lib/index.js", | 5 | "main": "lib/index.js", |
6 | "scripts": { | 6 | "scripts": { |
@@ -34,5 +34,5 @@ | |||
34 | "react-dom": "16.7.0", | 34 | "react-dom": "16.7.0", |
35 | "react-jss": "^8.6.1" | 35 | "react-jss": "^8.6.1" |
36 | }, | 36 | }, |
37 | "gitHead": "9f2ab40b7602bc3df26ebb093b484b9917768f69" | 37 | "gitHead": "e1e46986d902adc4c19ee009016290f9733a7d61" |
38 | } | 38 | } |
diff --git a/packages/ui/src/badge/ProBadge.tsx b/packages/ui/src/badge/ProBadge.tsx index 612e23210..5cc41f5b2 100644 --- a/packages/ui/src/badge/ProBadge.tsx +++ b/packages/ui/src/badge/ProBadge.tsx | |||
@@ -1,15 +1,17 @@ | |||
1 | import { mdiStar } from '@mdi/js'; | ||
1 | import { Theme } from '@meetfranz/theme'; | 2 | import { Theme } from '@meetfranz/theme'; |
2 | import classnames from 'classnames'; | 3 | import classnames from 'classnames'; |
3 | import React, { Component } from 'react'; | 4 | import React, { Component } from 'react'; |
4 | import injectStyle from 'react-jss'; | 5 | import injectStyle from 'react-jss'; |
5 | 6 | ||
6 | import { Icon, Badge } from '../'; | 7 | import { Badge, Icon } from '../'; |
7 | import { IWithStyle } from '../typings/generic'; | 8 | import { IWithStyle } from '../typings/generic'; |
8 | 9 | ||
9 | interface IProps extends IWithStyle { | 10 | interface IProps extends IWithStyle { |
10 | badgeClasses?: string; | 11 | badgeClasses?: string; |
11 | iconClasses?: string; | 12 | iconClasses?: string; |
12 | inverted?: boolean; | 13 | inverted?: boolean; |
14 | className?: string; | ||
13 | } | 15 | } |
14 | 16 | ||
15 | const styles = (theme: Theme) => ({ | 17 | const styles = (theme: Theme) => ({ |
@@ -37,6 +39,7 @@ class ProBadgeComponent extends Component<IProps> { | |||
37 | badgeClasses, | 39 | badgeClasses, |
38 | iconClasses, | 40 | iconClasses, |
39 | inverted, | 41 | inverted, |
42 | className, | ||
40 | } = this.props; | 43 | } = this.props; |
41 | 44 | ||
42 | return ( | 45 | return ( |
@@ -46,10 +49,11 @@ class ProBadgeComponent extends Component<IProps> { | |||
46 | classes.badge, | 49 | classes.badge, |
47 | inverted && classes.invertedBadge, | 50 | inverted && classes.invertedBadge, |
48 | badgeClasses, | 51 | badgeClasses, |
52 | className, | ||
49 | ])} | 53 | ])} |
50 | > | 54 | > |
51 | <Icon | 55 | <Icon |
52 | icon="mdiStar" | 56 | icon={mdiStar} |
53 | className={classnames([ | 57 | className={classnames([ |
54 | classes.icon, | 58 | classes.icon, |
55 | inverted && classes.invertedIcon, | 59 | inverted && classes.invertedIcon, |
diff --git a/packages/ui/src/icon/index.tsx b/packages/ui/src/icon/index.tsx index e30d3396d..af467c085 100644 --- a/packages/ui/src/icon/index.tsx +++ b/packages/ui/src/icon/index.tsx | |||
@@ -1,4 +1,3 @@ | |||
1 | import * as mdiIcons from '@mdi/js'; | ||
2 | import MdiIcon from '@mdi/react'; | 1 | import MdiIcon from '@mdi/react'; |
3 | import { Theme } from '@meetfranz/theme'; | 2 | import { Theme } from '@meetfranz/theme'; |
4 | import classnames from 'classnames'; | 3 | import classnames from 'classnames'; |
@@ -8,7 +7,7 @@ import injectStyle from 'react-jss'; | |||
8 | import { IWithStyle } from '../typings/generic'; | 7 | import { IWithStyle } from '../typings/generic'; |
9 | 8 | ||
10 | interface IProps extends IWithStyle { | 9 | interface IProps extends IWithStyle { |
11 | icon: keyof typeof mdiIcons; | 10 | icon: string; |
12 | size?: number; | 11 | size?: number; |
13 | className?: string; | 12 | className?: string; |
14 | } | 13 | } |
@@ -27,16 +26,13 @@ class IconComponent extends Component<IProps> { | |||
27 | render() { | 26 | render() { |
28 | const { | 27 | const { |
29 | classes, | 28 | classes, |
30 | icon: iconName, | 29 | icon, |
31 | size, | 30 | size, |
32 | className, | 31 | className, |
33 | } = this.props; | 32 | } = this.props; |
34 | 33 | ||
35 | let icon = ''; | 34 | if (!icon) { |
36 | if (iconName && mdiIcons[iconName]) { | 35 | console.warn('No Icon specified'); |
37 | icon = mdiIcons[iconName]; | ||
38 | } else if (iconName && !mdiIcons[iconName]) { | ||
39 | console.warn(`Icon '${iconName}' was not found`); | ||
40 | } | 36 | } |
41 | 37 | ||
42 | return ( | 38 | return ( |
diff --git a/packages/ui/src/infobox/index.tsx b/packages/ui/src/infobox/index.tsx index 9066a623e..e4c2c5a3e 100644 --- a/packages/ui/src/infobox/index.tsx +++ b/packages/ui/src/infobox/index.tsx | |||
@@ -1,3 +1,4 @@ | |||
1 | import { mdiClose } from '@mdi/js'; | ||
1 | import { Theme } from '@meetfranz/theme'; | 2 | import { Theme } from '@meetfranz/theme'; |
2 | import classnames from 'classnames'; | 3 | import classnames from 'classnames'; |
3 | import React, { Component } from 'react'; | 4 | import React, { Component } from 'react'; |
@@ -48,13 +49,13 @@ const styles = (theme: Theme) => ({ | |||
48 | position: 'relative', | 49 | position: 'relative', |
49 | overflow: 'hidden', | 50 | overflow: 'hidden', |
50 | height: 'auto', | 51 | height: 'auto', |
52 | marginBottom: 30, | ||
51 | }, | 53 | }, |
52 | infobox: { | 54 | infobox: { |
53 | alignItems: 'center', | 55 | alignItems: 'center', |
54 | borderRadius: theme.borderRadiusSmall, | 56 | borderRadius: theme.borderRadiusSmall, |
55 | display: 'flex', | 57 | display: 'flex', |
56 | height: 'auto', | 58 | height: 'auto', |
57 | marginBottom: 30, | ||
58 | padding: '15px 20px', | 59 | padding: '15px 20px', |
59 | top: 0, | 60 | top: 0, |
60 | transition: 'all 0.5s', | 61 | transition: 'all 0.5s', |
@@ -192,7 +193,7 @@ class InfoboxComponent extends Component<IProps, IState> { | |||
192 | onClick={this.dismiss.bind(this)} | 193 | onClick={this.dismiss.bind(this)} |
193 | className={classes.close} | 194 | className={classes.close} |
194 | > | 195 | > |
195 | <Icon icon="mdiClose" /> | 196 | <Icon icon={mdiClose} /> |
196 | </button> | 197 | </button> |
197 | )} | 198 | )} |
198 | </div> | 199 | </div> |
diff --git a/src/actions/index.js b/src/actions/index.js index fc525afeb..336344d76 100644 --- a/src/actions/index.js +++ b/src/actions/index.js | |||
@@ -13,6 +13,7 @@ import settings from './settings'; | |||
13 | import requests from './requests'; | 13 | import requests from './requests'; |
14 | import announcements from '../features/announcements/actions'; | 14 | import announcements from '../features/announcements/actions'; |
15 | import workspaces from '../features/workspaces/actions'; | 15 | import workspaces from '../features/workspaces/actions'; |
16 | import todos from '../features/todos/actions'; | ||
16 | 17 | ||
17 | const actions = Object.assign({}, { | 18 | const actions = Object.assign({}, { |
18 | service, | 19 | service, |
@@ -31,4 +32,5 @@ export default Object.assign( | |||
31 | defineActions(actions, PropTypes.checkPropTypes), | 32 | defineActions(actions, PropTypes.checkPropTypes), |
32 | { announcements }, | 33 | { announcements }, |
33 | { workspaces }, | 34 | { workspaces }, |
35 | { todos }, | ||
34 | ); | 36 | ); |
diff --git a/src/actions/user.js b/src/actions/user.js index ccf1fa56a..5d7d9a899 100644 --- a/src/actions/user.js +++ b/src/actions/user.js | |||
@@ -17,6 +17,9 @@ export default { | |||
17 | retrievePassword: { | 17 | retrievePassword: { |
18 | email: PropTypes.string.isRequired, | 18 | email: PropTypes.string.isRequired, |
19 | }, | 19 | }, |
20 | activateTrial: { | ||
21 | planId: PropTypes.string.isRequired, | ||
22 | }, | ||
20 | invite: { | 23 | invite: { |
21 | invites: PropTypes.array.isRequired, | 24 | invites: PropTypes.array.isRequired, |
22 | }, | 25 | }, |
diff --git a/src/api/UserApi.js b/src/api/UserApi.js index edfb88988..8ba8cd1e9 100644 --- a/src/api/UserApi.js +++ b/src/api/UserApi.js | |||
@@ -25,6 +25,10 @@ export default class UserApi { | |||
25 | return this.server.retrievePassword(email); | 25 | return this.server.retrievePassword(email); |
26 | } | 26 | } |
27 | 27 | ||
28 | activateTrial(data) { | ||
29 | return this.server.activateTrial(data); | ||
30 | } | ||
31 | |||
28 | invite(data) { | 32 | invite(data) { |
29 | return this.server.inviteUser(data); | 33 | return this.server.inviteUser(data); |
30 | } | 34 | } |
diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js index a9ce202ff..f56c7b6e4 100644 --- a/src/api/server/ServerApi.js +++ b/src/api/server/ServerApi.js | |||
@@ -77,6 +77,20 @@ export default class ServerApi { | |||
77 | return u.token; | 77 | return u.token; |
78 | } | 78 | } |
79 | 79 | ||
80 | async activateTrial(data) { | ||
81 | const request = await sendAuthRequest(`${API_URL}/payment/trial`, { | ||
82 | method: 'POST', | ||
83 | body: JSON.stringify(data), | ||
84 | }); | ||
85 | if (!request.ok) { | ||
86 | throw request; | ||
87 | } | ||
88 | const trial = await request.json(); | ||
89 | |||
90 | debug('ServerApi::signup resolves', trial); | ||
91 | return true; | ||
92 | } | ||
93 | |||
80 | async inviteUser(data) { | 94 | async inviteUser(data) { |
81 | const request = await sendAuthRequest(`${API_URL}/invite`, { | 95 | const request = await sendAuthRequest(`${API_URL}/invite`, { |
82 | method: 'POST', | 96 | method: 'POST', |
@@ -469,7 +483,7 @@ export default class ServerApi { | |||
469 | return services; | 483 | return services; |
470 | } | 484 | } |
471 | } catch (err) { | 485 | } catch (err) { |
472 | throw (new Error('ServerApi::getLegacyServices no config found')); | 486 | console.error('ServerApi::getLegacyServices no config found'); |
473 | } | 487 | } |
474 | 488 | ||
475 | return []; | 489 | return []; |
diff --git a/src/components/TrialActivationInfoBar.js b/src/components/TrialActivationInfoBar.js new file mode 100644 index 000000000..acdf51d08 --- /dev/null +++ b/src/components/TrialActivationInfoBar.js | |||
@@ -0,0 +1,94 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { defineMessages, intlShape } from 'react-intl'; | ||
4 | import ms from 'ms'; | ||
5 | import injectSheet from 'react-jss'; | ||
6 | import classnames from 'classnames'; | ||
7 | |||
8 | import InfoBar from './ui/InfoBar'; | ||
9 | |||
10 | const messages = defineMessages({ | ||
11 | message: { | ||
12 | id: 'infobar.trialActivated', | ||
13 | defaultMessage: '!!!Your trial was successfully activated. Happy messaging!', | ||
14 | }, | ||
15 | }); | ||
16 | |||
17 | const styles = { | ||
18 | notification: { | ||
19 | height: 'auto', | ||
20 | position: 'absolute', | ||
21 | top: -50, | ||
22 | transition: 'top 0.3s', | ||
23 | zIndex: 300, | ||
24 | width: 'calc(100% - 300px)', | ||
25 | }, | ||
26 | show: { | ||
27 | top: 0, | ||
28 | }, | ||
29 | }; | ||
30 | |||
31 | @injectSheet(styles) | ||
32 | class TrialActivationInfoBar extends Component { | ||
33 | static propTypes = { | ||
34 | // eslint-disable-next-line | ||
35 | classes: PropTypes.object.isRequired, | ||
36 | }; | ||
37 | |||
38 | static contextTypes = { | ||
39 | intl: intlShape, | ||
40 | }; | ||
41 | |||
42 | state = { | ||
43 | showing: false, | ||
44 | removed: false, | ||
45 | } | ||
46 | |||
47 | componentDidMount() { | ||
48 | setTimeout(() => { | ||
49 | this.setState({ | ||
50 | showing: true, | ||
51 | }); | ||
52 | }, 0); | ||
53 | |||
54 | setTimeout(() => { | ||
55 | this.setState({ | ||
56 | showing: false, | ||
57 | }); | ||
58 | }, ms('6s')); | ||
59 | |||
60 | setTimeout(() => { | ||
61 | this.setState({ | ||
62 | removed: true, | ||
63 | }); | ||
64 | }, ms('7s')); | ||
65 | } | ||
66 | |||
67 | render() { | ||
68 | const { classes } = this.props; | ||
69 | const { showing, removed } = this.state; | ||
70 | const { intl } = this.context; | ||
71 | |||
72 | if (removed) return null; | ||
73 | |||
74 | return ( | ||
75 | <div | ||
76 | className={classnames({ | ||
77 | [classes.notification]: true, | ||
78 | [classes.show]: showing, | ||
79 | })} | ||
80 | > | ||
81 | <InfoBar | ||
82 | type="primary" | ||
83 | position="top" | ||
84 | sticky | ||
85 | > | ||
86 | <span className="mdi mdi-information" /> | ||
87 | {intl.formatMessage(messages.message)} | ||
88 | </InfoBar> | ||
89 | </div> | ||
90 | ); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | export default TrialActivationInfoBar; | ||
diff --git a/src/components/auth/AuthLayout.js b/src/components/auth/AuthLayout.js index 3d43d4e5c..75a8cfc61 100644 --- a/src/components/auth/AuthLayout.js +++ b/src/components/auth/AuthLayout.js | |||
@@ -22,7 +22,6 @@ export default @observer class AuthLayout extends Component { | |||
22 | retryHealthCheck: PropTypes.func.isRequired, | 22 | retryHealthCheck: PropTypes.func.isRequired, |
23 | isHealthCheckLoading: PropTypes.bool.isRequired, | 23 | isHealthCheckLoading: PropTypes.bool.isRequired, |
24 | isFullScreen: PropTypes.bool.isRequired, | 24 | isFullScreen: PropTypes.bool.isRequired, |
25 | darkMode: PropTypes.bool.isRequired, | ||
26 | nextAppReleaseVersion: PropTypes.string, | 25 | nextAppReleaseVersion: PropTypes.string, |
27 | installAppUpdate: PropTypes.func.isRequired, | 26 | installAppUpdate: PropTypes.func.isRequired, |
28 | appUpdateIsDownloaded: PropTypes.bool.isRequired, | 27 | appUpdateIsDownloaded: PropTypes.bool.isRequired, |
@@ -45,7 +44,6 @@ export default @observer class AuthLayout extends Component { | |||
45 | retryHealthCheck, | 44 | retryHealthCheck, |
46 | isHealthCheckLoading, | 45 | isHealthCheckLoading, |
47 | isFullScreen, | 46 | isFullScreen, |
48 | darkMode, | ||
49 | nextAppReleaseVersion, | 47 | nextAppReleaseVersion, |
50 | installAppUpdate, | 48 | installAppUpdate, |
51 | appUpdateIsDownloaded, | 49 | appUpdateIsDownloaded, |
@@ -53,7 +51,7 @@ export default @observer class AuthLayout extends Component { | |||
53 | const { intl } = this.context; | 51 | const { intl } = this.context; |
54 | 52 | ||
55 | return ( | 53 | return ( |
56 | <div className={darkMode ? 'theme__dark' : ''}> | 54 | <> |
57 | {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />} | 55 | {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />} |
58 | <div className="auth"> | 56 | <div className="auth"> |
59 | {!isOnline && ( | 57 | {!isOnline && ( |
@@ -93,7 +91,7 @@ export default @observer class AuthLayout extends Component { | |||
93 | <img src="./assets/images/adlk.svg" alt="" /> | 91 | <img src="./assets/images/adlk.svg" alt="" /> |
94 | </Link> | 92 | </Link> |
95 | </div> | 93 | </div> |
96 | </div> | 94 | </> |
97 | ); | 95 | ); |
98 | } | 96 | } |
99 | } | 97 | } |
diff --git a/src/components/auth/Pricing.js b/src/components/auth/Pricing.js index 7ab14f429..cbeaaa5d9 100644 --- a/src/components/auth/Pricing.js +++ b/src/components/auth/Pricing.js | |||
@@ -1,40 +1,107 @@ | |||
1 | import React, { Component } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | // import { Link } from 'react-router'; | 5 | import injectSheet from 'react-jss'; |
6 | import { H2, Loader } from '@meetfranz/ui'; | ||
7 | import classnames from 'classnames'; | ||
8 | |||
9 | import { Button } from '@meetfranz/forms'; | ||
10 | import { FeatureItem } from '../ui/FeatureItem'; | ||
11 | import { FeatureList } from '../ui/FeatureList'; | ||
6 | 12 | ||
7 | // import Button from '../ui/Button'; | ||
8 | import Loader from '../ui/Loader'; | ||
9 | import Appear from '../ui/effects/Appear'; | ||
10 | import SubscriptionForm from '../../containers/subscription/SubscriptionFormScreen'; | ||
11 | 13 | ||
12 | const messages = defineMessages({ | 14 | const messages = defineMessages({ |
13 | headline: { | 15 | headline: { |
14 | id: 'pricing.headline', | 16 | id: 'pricing.trial.headline', |
15 | defaultMessage: '!!!Support Franz', | 17 | defaultMessage: '!!!Franz Professional', |
18 | }, | ||
19 | personalOffer: { | ||
20 | id: 'pricing.trial.subheadline', | ||
21 | defaultMessage: '!!!Your personal welcome offer:', | ||
22 | }, | ||
23 | noStringsAttachedHeadline: { | ||
24 | id: 'pricing.trial.terms.headline', | ||
25 | defaultMessage: '!!!No strings attached', | ||
26 | }, | ||
27 | noCreditCard: { | ||
28 | id: 'pricing.trial.terms.noCreditCard', | ||
29 | defaultMessage: '!!!No credit card required', | ||
16 | }, | 30 | }, |
17 | monthlySupportLabel: { | 31 | automaticTrialEnd: { |
18 | id: 'pricing.support.label', | 32 | id: 'pricing.trial.terms.automaticTrialEnd', |
19 | defaultMessage: '!!!Select your support plan', | 33 | defaultMessage: '!!!Your free trial ends automatically after 14 days', |
20 | }, | 34 | }, |
21 | submitButtonLabel: { | 35 | activationError: { |
22 | id: 'pricing.submit.label', | 36 | id: 'pricing.trial.error', |
23 | defaultMessage: '!!!Support the development of Franz', | 37 | defaultMessage: '!!!Sorry, we could not activate your trial!', |
24 | }, | 38 | }, |
25 | skipPayment: { | 39 | ctaAccept: { |
26 | id: 'pricing.link.skipPayment', | 40 | id: 'pricing.trial.cta.accept', |
27 | defaultMessage: '!!!I don\'t want to support the development of Franz.', | 41 | defaultMessage: '!!!Yes, upgrade my account to Franz Professional', |
42 | }, | ||
43 | ctaSkip: { | ||
44 | id: 'pricing.trial.cta.skip', | ||
45 | defaultMessage: '!!!Continue to Franz', | ||
46 | }, | ||
47 | featuresHeadline: { | ||
48 | id: 'pricing.trial.features.headline', | ||
49 | defaultMessage: '!!!Franz Professional includes:', | ||
28 | }, | 50 | }, |
29 | }); | 51 | }); |
30 | 52 | ||
31 | export default @observer class Signup extends Component { | 53 | const styles = theme => ({ |
54 | container: { | ||
55 | position: 'relative', | ||
56 | marginLeft: -150, | ||
57 | }, | ||
58 | welcomeOffer: { | ||
59 | textAlign: 'center', | ||
60 | fontWeight: 'bold', | ||
61 | }, | ||
62 | keyTerms: { | ||
63 | textAlign: 'center', | ||
64 | }, | ||
65 | content: { | ||
66 | position: 'relative', | ||
67 | zIndex: 20, | ||
68 | }, | ||
69 | featureContainer: { | ||
70 | width: 300, | ||
71 | position: 'absolute', | ||
72 | left: 'calc(100% / 2 + 225px)', | ||
73 | top: 155, | ||
74 | background: theme.signup.pricing.feature.background, | ||
75 | height: 'auto', | ||
76 | padding: 20, | ||
77 | borderTopRightRadius: theme.borderRadius, | ||
78 | borderBottomRightRadius: theme.borderRadius, | ||
79 | zIndex: 10, | ||
80 | }, | ||
81 | featureItem: { | ||
82 | borderBottom: [1, 'solid', theme.signup.pricing.feature.border], | ||
83 | }, | ||
84 | cta: { | ||
85 | marginTop: 40, | ||
86 | width: '100%', | ||
87 | }, | ||
88 | skipLink: { | ||
89 | textAlign: 'center', | ||
90 | marginTop: 10, | ||
91 | }, | ||
92 | error: { | ||
93 | margin: [20, 0, 0], | ||
94 | color: theme.styleTypes.danger.accent, | ||
95 | }, | ||
96 | }); | ||
97 | |||
98 | export default @observer @injectSheet(styles) class Signup extends Component { | ||
32 | static propTypes = { | 99 | static propTypes = { |
33 | donor: MobxPropTypes.objectOrObservableObject.isRequired, | 100 | onSubmit: PropTypes.func.isRequired, |
34 | isLoading: PropTypes.bool.isRequired, | 101 | isLoadingRequiredData: PropTypes.bool.isRequired, |
35 | isLoadingUser: PropTypes.bool.isRequired, | 102 | isActivatingTrial: PropTypes.bool.isRequired, |
36 | onCloseSubscriptionWindow: PropTypes.func.isRequired, | 103 | trialActivationError: PropTypes.bool.isRequired, |
37 | skipAction: PropTypes.func.isRequired, | 104 | classes: PropTypes.object.isRequired, |
38 | }; | 105 | }; |
39 | 106 | ||
40 | static contextTypes = { | 107 | static contextTypes = { |
@@ -43,70 +110,37 @@ export default @observer class Signup extends Component { | |||
43 | 110 | ||
44 | render() { | 111 | render() { |
45 | const { | 112 | const { |
46 | donor, | 113 | onSubmit, |
47 | isLoading, | 114 | isLoadingRequiredData, |
48 | isLoadingUser, | 115 | isActivatingTrial, |
49 | onCloseSubscriptionWindow, | 116 | trialActivationError, |
50 | skipAction, | 117 | classes, |
51 | } = this.props; | 118 | } = this.props; |
52 | const { intl } = this.context; | 119 | const { intl } = this.context; |
53 | 120 | ||
54 | return ( | 121 | return ( |
55 | <div className="auth__scroll-container"> | 122 | <div className={classnames('auth__scroll-container', classes.container)}> |
56 | <div className="auth__container auth__container--signup"> | 123 | <div className={classnames('auth__container', 'auth__container--signup', classes.content)}> |
57 | <form className="franz-form auth__form"> | 124 | <form className="franz-form auth__form"> |
58 | <img | 125 | {isLoadingRequiredData ? <Loader /> : ( |
59 | src="./assets/images/sm.png" | 126 | <img |
60 | className="auth__logo auth__logo--sm" | 127 | src="./assets/images/sm.png" |
61 | alt="" | 128 | className="auth__logo auth__logo--sm" |
62 | /> | 129 | alt="" |
130 | /> | ||
131 | )} | ||
132 | <p className={classes.welcomeOffer}>{intl.formatMessage(messages.personalOffer)}</p> | ||
63 | <h1>{intl.formatMessage(messages.headline)}</h1> | 133 | <h1>{intl.formatMessage(messages.headline)}</h1> |
64 | <div className="auth__letter"> | 134 | <div className="auth__letter"> |
65 | {isLoadingUser && ( | 135 | <p> |
66 | <p>Loading</p> | 136 | We built Franz with a lot of effort, manpower and love, |
67 | )} | 137 | to boost up your messaging experience. |
68 | {!isLoadingUser && ( | 138 | <br /> |
69 | donor.amount ? ( | 139 | </p> |
70 | <span> | 140 | <p> |
71 | <p> | 141 | Get the free 14 day Franz Professional trial and see your communication evolving. |
72 | Thank you so much for your previous donation of | 142 | <br /> |
73 | {' '} | 143 | </p> |
74 | <strong> | ||
75 | $ | ||
76 | {donor.amount} | ||
77 | </strong> | ||
78 | . | ||
79 | <br /> | ||
80 | Your support allowed us to get where we are today. | ||
81 | <br /> | ||
82 | </p> | ||
83 | <p> | ||
84 | As an early supporter, you get | ||
85 | {' '} | ||
86 | <strong>a lifetime premium supporter license</strong> | ||
87 | {' '} | ||
88 | without any | ||
89 | additional charges. | ||
90 | </p> | ||
91 | <p> | ||
92 | However, If you want to keep supporting us, you are more than welcome to subscribe to a plan. | ||
93 | <br /> | ||
94 | <br /> | ||
95 | </p> | ||
96 | </span> | ||
97 | ) : ( | ||
98 | <span> | ||
99 | <p> | ||
100 | We built Franz with a lot of effort, manpower and love, | ||
101 | to bring you the best messaging experience. | ||
102 | <br /> | ||
103 | </p> | ||
104 | <p> | ||
105 | Getting a Franz Premium Supporter License will allow us to keep improving Franz for you. | ||
106 | </p> | ||
107 | </span> | ||
108 | ) | ||
109 | )} | ||
110 | <p> | 144 | <p> |
111 | Thanks for being a hero. | 145 | Thanks for being a hero. |
112 | </p> | 146 | </p> |
@@ -114,20 +148,48 @@ export default @observer class Signup extends Component { | |||
114 | <strong>Stefan Malzner</strong> | 148 | <strong>Stefan Malzner</strong> |
115 | </p> | 149 | </p> |
116 | </div> | 150 | </div> |
117 | <Loader loaded={!isLoading}> | 151 | <div className={classes.keyTerms}> |
118 | <Appear transitionName="slideDown"> | 152 | <H2> |
119 | <span className="label">{intl.formatMessage(messages.monthlySupportLabel)}</span> | 153 | {intl.formatMessage(messages.noStringsAttachedHeadline)} |
120 | <SubscriptionForm | 154 | </H2> |
121 | onCloseWindow={onCloseSubscriptionWindow} | 155 | <ul className={classes.keyTermsList}> |
122 | showSkipOption | 156 | <FeatureItem icon="👉" name={intl.formatMessage(messages.noCreditCard)} /> |
123 | skipAction={skipAction} | 157 | <FeatureItem icon="👉" name={intl.formatMessage(messages.automaticTrialEnd)} /> |
124 | hideInfo={Boolean(donor.amount)} | 158 | </ul> |
125 | skipButtonLabel={intl.formatMessage(messages.skipPayment)} | 159 | </div> |
126 | /> | 160 | {trialActivationError && ( |
127 | </Appear> | 161 | <p className={classes.error}>{intl.formatMessage(messages.activationError)}</p> |
128 | </Loader> | 162 | )} |
163 | <Button | ||
164 | label={intl.formatMessage(messages.ctaAccept)} | ||
165 | className={classes.cta} | ||
166 | onClick={onSubmit} | ||
167 | busy={isActivatingTrial} | ||
168 | disabled={isLoadingRequiredData || isActivatingTrial} | ||
169 | /> | ||
170 | <p className={classes.skipLink}> | ||
171 | <a href="#/">{intl.formatMessage(messages.ctaSkip)}</a> | ||
172 | </p> | ||
129 | </form> | 173 | </form> |
130 | </div> | 174 | </div> |
175 | <div className={classes.featureContainer}> | ||
176 | <H2> | ||
177 | {intl.formatMessage(messages.featuresHeadline)} | ||
178 | </H2> | ||
179 | {/* <ul className={classes.features}> | ||
180 | <FeatureItem name="Add unlimited services" className={classes.featureItem} /> | ||
181 | <FeatureItem name="Spellchecker support" className={classes.featureItem} /> | ||
182 | <FeatureItem name="Workspaces" className={classes.featureItem} /> | ||
183 | <FeatureItem name="Add Custom Websites" className={classes.featureItem} /> | ||
184 | <FeatureItem name="On-premise & other Hosted Services" className={classes.featureItem} /> | ||
185 | <FeatureItem name="Install 3rd party services" className={classes.featureItem} /> | ||
186 | <FeatureItem name="Service Proxies" className={classes.featureItem} /> | ||
187 | <FeatureItem name="Team Management" className={classes.featureItem} /> | ||
188 | <FeatureItem name="No Waiting Screens" className={classes.featureItem} /> | ||
189 | <FeatureItem name="Forever ad-free" className={classes.featureItem} /> | ||
190 | </ul> */} | ||
191 | <FeatureList /> | ||
192 | </div> | ||
131 | </div> | 193 | </div> |
132 | ); | 194 | ); |
133 | } | 195 | } |
diff --git a/src/components/auth/Signup.js b/src/components/auth/Signup.js index d9b83eeb8..0499d764b 100644 --- a/src/components/auth/Signup.js +++ b/src/components/auth/Signup.js | |||
@@ -7,7 +7,6 @@ import { isDevMode, useLiveAPI } from '../../environment'; | |||
7 | import Form from '../../lib/Form'; | 7 | import Form from '../../lib/Form'; |
8 | import { required, email, minLength } from '../../helpers/validation-helpers'; | 8 | import { required, email, minLength } from '../../helpers/validation-helpers'; |
9 | import Input from '../ui/Input'; | 9 | import Input from '../ui/Input'; |
10 | import Radio from '../ui/Radio'; | ||
11 | import Button from '../ui/Button'; | 10 | import Button from '../ui/Button'; |
12 | import Link from '../ui/Link'; | 11 | import Link from '../ui/Link'; |
13 | import Infobox from '../ui/Infobox'; | 12 | import Infobox from '../ui/Infobox'; |
@@ -31,10 +30,10 @@ const messages = defineMessages({ | |||
31 | id: 'signup.email.label', | 30 | id: 'signup.email.label', |
32 | defaultMessage: '!!!Email address', | 31 | defaultMessage: '!!!Email address', |
33 | }, | 32 | }, |
34 | companyLabel: { | 33 | // companyLabel: { |
35 | id: 'signup.company.label', | 34 | // id: 'signup.company.label', |
36 | defaultMessage: '!!!Company', | 35 | // defaultMessage: '!!!Company', |
37 | }, | 36 | // }, |
38 | passwordLabel: { | 37 | passwordLabel: { |
39 | id: 'signup.password.label', | 38 | id: 'signup.password.label', |
40 | defaultMessage: '!!!Password', | 39 | defaultMessage: '!!!Password', |
@@ -79,20 +78,6 @@ export default @observer class Signup extends Component { | |||
79 | 78 | ||
80 | form = new Form({ | 79 | form = new Form({ |
81 | fields: { | 80 | fields: { |
82 | accountType: { | ||
83 | value: 'individual', | ||
84 | validators: [required], | ||
85 | options: [{ | ||
86 | value: 'individual', | ||
87 | label: 'Individual', | ||
88 | }, { | ||
89 | value: 'non-profit', | ||
90 | label: 'Non-Profit', | ||
91 | }, { | ||
92 | value: 'company', | ||
93 | label: 'Company', | ||
94 | }], | ||
95 | }, | ||
96 | firstname: { | 81 | firstname: { |
97 | label: this.context.intl.formatMessage(messages.firstnameLabel), | 82 | label: this.context.intl.formatMessage(messages.firstnameLabel), |
98 | value: '', | 83 | value: '', |
@@ -108,10 +93,6 @@ export default @observer class Signup extends Component { | |||
108 | value: '', | 93 | value: '', |
109 | validators: [required, email], | 94 | validators: [required, email], |
110 | }, | 95 | }, |
111 | organization: { | ||
112 | label: this.context.intl.formatMessage(messages.companyLabel), | ||
113 | value: '', // TODO: make required when accountType: company | ||
114 | }, | ||
115 | password: { | 96 | password: { |
116 | label: this.context.intl.formatMessage(messages.passwordLabel), | 97 | label: this.context.intl.formatMessage(messages.passwordLabel), |
117 | value: '', | 98 | value: '', |
@@ -151,7 +132,6 @@ export default @observer class Signup extends Component { | |||
151 | In Dev Mode your data is not persistent. Please use the live app for accesing the production API. | 132 | In Dev Mode your data is not persistent. Please use the live app for accesing the production API. |
152 | </Infobox> | 133 | </Infobox> |
153 | )} | 134 | )} |
154 | <Radio field={form.$('accountType')} showLabel={false} /> | ||
155 | <div className="grid__row"> | 135 | <div className="grid__row"> |
156 | <Input field={form.$('firstname')} focus /> | 136 | <Input field={form.$('firstname')} focus /> |
157 | <Input field={form.$('lastname')} /> | 137 | <Input field={form.$('lastname')} /> |
@@ -162,9 +142,6 @@ export default @observer class Signup extends Component { | |||
162 | showPasswordToggle | 142 | showPasswordToggle |
163 | scorePassword | 143 | scorePassword |
164 | /> | 144 | /> |
165 | {form.$('accountType').value === 'company' && ( | ||
166 | <Input field={form.$('organization')} /> | ||
167 | )} | ||
168 | {error.code === 'email-duplicate' && ( | 145 | {error.code === 'email-duplicate' && ( |
169 | <p className="error-message center">{intl.formatMessage(messages.emailDuplicate)}</p> | 146 | <p className="error-message center">{intl.formatMessage(messages.emailDuplicate)}</p> |
170 | )} | 147 | )} |
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js index 499bc097a..941e60bfd 100644 --- a/src/components/layout/AppLayout.js +++ b/src/components/layout/AppLayout.js | |||
@@ -17,6 +17,8 @@ import { isWindows } from '../../environment'; | |||
17 | import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator'; | 17 | import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator'; |
18 | import { workspaceStore } from '../../features/workspaces'; | 18 | import { workspaceStore } from '../../features/workspaces'; |
19 | import AppUpdateInfoBar from '../AppUpdateInfoBar'; | 19 | import AppUpdateInfoBar from '../AppUpdateInfoBar'; |
20 | import TrialActivationInfoBar from '../TrialActivationInfoBar'; | ||
21 | import Todos from '../../features/todos/containers/TodosScreen'; | ||
20 | 22 | ||
21 | function createMarkup(HTMLString) { | 23 | function createMarkup(HTMLString) { |
22 | return { __html: HTMLString }; | 24 | return { __html: HTMLString }; |
@@ -39,7 +41,8 @@ const messages = defineMessages({ | |||
39 | 41 | ||
40 | const styles = theme => ({ | 42 | const styles = theme => ({ |
41 | appContent: { | 43 | appContent: { |
42 | width: `calc(100% + ${theme.workspaces.drawer.width}px)`, | 44 | // width: `calc(100% + ${theme.workspaces.drawer.width}px)`, |
45 | width: '100%', | ||
43 | transition: 'transform 0.5s ease', | 46 | transition: 'transform 0.5s ease', |
44 | transform() { | 47 | transform() { |
45 | return workspaceStore.isWorkspaceDrawerOpen ? 'translateX(0)' : `translateX(-${theme.workspaces.drawer.width}px)`; | 48 | return workspaceStore.isWorkspaceDrawerOpen ? 'translateX(0)' : `translateX(-${theme.workspaces.drawer.width}px)`; |
@@ -57,7 +60,6 @@ class AppLayout extends Component { | |||
57 | services: PropTypes.element.isRequired, | 60 | services: PropTypes.element.isRequired, |
58 | children: PropTypes.element, | 61 | children: PropTypes.element, |
59 | news: MobxPropTypes.arrayOrObservableArray.isRequired, | 62 | news: MobxPropTypes.arrayOrObservableArray.isRequired, |
60 | // isOnline: PropTypes.bool.isRequired, | ||
61 | showServicesUpdatedInfoBar: PropTypes.bool.isRequired, | 63 | showServicesUpdatedInfoBar: PropTypes.bool.isRequired, |
62 | appUpdateIsDownloaded: PropTypes.bool.isRequired, | 64 | appUpdateIsDownloaded: PropTypes.bool.isRequired, |
63 | nextAppReleaseVersion: PropTypes.string, | 65 | nextAppReleaseVersion: PropTypes.string, |
@@ -68,8 +70,8 @@ class AppLayout extends Component { | |||
68 | areRequiredRequestsSuccessful: PropTypes.bool.isRequired, | 70 | areRequiredRequestsSuccessful: PropTypes.bool.isRequired, |
69 | retryRequiredRequests: PropTypes.func.isRequired, | 71 | retryRequiredRequests: PropTypes.func.isRequired, |
70 | areRequiredRequestsLoading: PropTypes.bool.isRequired, | 72 | areRequiredRequestsLoading: PropTypes.bool.isRequired, |
71 | darkMode: PropTypes.bool.isRequired, | ||
72 | isDelayAppScreenVisible: PropTypes.bool.isRequired, | 73 | isDelayAppScreenVisible: PropTypes.bool.isRequired, |
74 | hasActivatedTrial: PropTypes.bool.isRequired, | ||
73 | }; | 75 | }; |
74 | 76 | ||
75 | static defaultProps = { | 77 | static defaultProps = { |
@@ -89,7 +91,6 @@ class AppLayout extends Component { | |||
89 | sidebar, | 91 | sidebar, |
90 | services, | 92 | services, |
91 | children, | 93 | children, |
92 | // isOnline, | ||
93 | news, | 94 | news, |
94 | showServicesUpdatedInfoBar, | 95 | showServicesUpdatedInfoBar, |
95 | appUpdateIsDownloaded, | 96 | appUpdateIsDownloaded, |
@@ -101,78 +102,71 @@ class AppLayout extends Component { | |||
101 | areRequiredRequestsSuccessful, | 102 | areRequiredRequestsSuccessful, |
102 | retryRequiredRequests, | 103 | retryRequiredRequests, |
103 | areRequiredRequestsLoading, | 104 | areRequiredRequestsLoading, |
104 | darkMode, | ||
105 | isDelayAppScreenVisible, | 105 | isDelayAppScreenVisible, |
106 | hasActivatedTrial, | ||
106 | } = this.props; | 107 | } = this.props; |
107 | 108 | ||
108 | const { intl } = this.context; | 109 | const { intl } = this.context; |
109 | 110 | ||
110 | return ( | 111 | return ( |
111 | <ErrorBoundary> | 112 | <ErrorBoundary> |
112 | <div className={(darkMode ? 'theme__dark' : '')}> | 113 | <div className="app"> |
113 | <div className="app"> | 114 | {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />} |
114 | {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />} | 115 | <div className={`app__content ${classes.appContent}`}> |
115 | <div className={`app__content ${classes.appContent}`}> | 116 | {workspacesDrawer} |
116 | {workspacesDrawer} | 117 | {sidebar} |
117 | {sidebar} | 118 | <div className="app__service"> |
118 | <div className="app__service"> | 119 | <WorkspaceSwitchingIndicator /> |
119 | <WorkspaceSwitchingIndicator /> | 120 | {news.length > 0 && news.map(item => ( |
120 | {news.length > 0 && news.map(item => ( | 121 | <InfoBar |
121 | <InfoBar | 122 | key={item.id} |
122 | key={item.id} | 123 | position="top" |
123 | position="top" | 124 | type={item.type} |
124 | type={item.type} | 125 | sticky={item.sticky} |
125 | sticky={item.sticky} | 126 | onHide={() => removeNewsItem({ newsId: item.id })} |
126 | onHide={() => removeNewsItem({ newsId: item.id })} | 127 | > |
127 | > | 128 | <span dangerouslySetInnerHTML={createMarkup(item.message)} /> |
128 | <span dangerouslySetInnerHTML={createMarkup(item.message)} /> | 129 | </InfoBar> |
129 | </InfoBar> | 130 | ))} |
130 | ))} | 131 | {hasActivatedTrial && ( |
131 | {/* {!isOnline && ( | 132 | <TrialActivationInfoBar /> |
132 | <InfoBar | 133 | )} |
133 | type="danger" | 134 | {!areRequiredRequestsSuccessful && showRequiredRequestsError && ( |
134 | sticky | 135 | <InfoBar |
135 | > | 136 | type="danger" |
136 | <span className="mdi mdi-flash" /> | 137 | ctaLabel="Try again" |
137 | {intl.formatMessage(globalMessages.notConnectedToTheInternet)} | 138 | ctaLoading={areRequiredRequestsLoading} |
138 | </InfoBar> | 139 | sticky |
139 | )} */} | 140 | onClick={retryRequiredRequests} |
140 | {!areRequiredRequestsSuccessful && showRequiredRequestsError && ( | 141 | > |
141 | <InfoBar | 142 | <span className="mdi mdi-flash" /> |
142 | type="danger" | 143 | {intl.formatMessage(messages.requiredRequestsFailed)} |
143 | ctaLabel="Try again" | 144 | </InfoBar> |
144 | ctaLoading={areRequiredRequestsLoading} | 145 | )} |
145 | sticky | 146 | {showServicesUpdatedInfoBar && ( |
146 | onClick={retryRequiredRequests} | 147 | <InfoBar |
147 | > | 148 | type="primary" |
148 | <span className="mdi mdi-flash" /> | 149 | ctaLabel={intl.formatMessage(messages.buttonReloadServices)} |
149 | {intl.formatMessage(messages.requiredRequestsFailed)} | 150 | onClick={reloadServicesAfterUpdate} |
150 | </InfoBar> | 151 | sticky |
151 | )} | 152 | > |
152 | {showServicesUpdatedInfoBar && ( | 153 | <span className="mdi mdi-power-plug" /> |
153 | <InfoBar | 154 | {intl.formatMessage(messages.servicesUpdated)} |
154 | type="primary" | 155 | </InfoBar> |
155 | ctaLabel={intl.formatMessage(messages.buttonReloadServices)} | 156 | )} |
156 | onClick={reloadServicesAfterUpdate} | 157 | {appUpdateIsDownloaded && ( |
157 | sticky | 158 | <AppUpdateInfoBar |
158 | > | 159 | nextAppReleaseVersion={nextAppReleaseVersion} |
159 | <span className="mdi mdi-power-plug" /> | 160 | onInstallUpdate={installAppUpdate} |
160 | {intl.formatMessage(messages.servicesUpdated)} | 161 | /> |
161 | </InfoBar> | 162 | )} |
162 | )} | 163 | {isDelayAppScreenVisible && (<DelayApp />)} |
163 | {appUpdateIsDownloaded && ( | 164 | <BasicAuth /> |
164 | <AppUpdateInfoBar | 165 | <ShareFranz /> |
165 | nextAppReleaseVersion={nextAppReleaseVersion} | 166 | {services} |
166 | onInstallUpdate={installAppUpdate} | 167 | {children} |
167 | /> | ||
168 | )} | ||
169 | {isDelayAppScreenVisible && (<DelayApp />)} | ||
170 | <BasicAuth /> | ||
171 | <ShareFranz /> | ||
172 | {services} | ||
173 | {children} | ||
174 | </div> | ||
175 | </div> | 168 | </div> |
169 | <Todos /> | ||
176 | </div> | 170 | </div> |
177 | </div> | 171 | </div> |
178 | </ErrorBoundary> | 172 | </ErrorBoundary> |
diff --git a/src/components/services/content/ServiceRestricted.js b/src/components/services/content/ServiceRestricted.js new file mode 100644 index 000000000..4b8d926aa --- /dev/null +++ b/src/components/services/content/ServiceRestricted.js | |||
@@ -0,0 +1,78 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | |||
6 | import { serviceLimitStore } from '../../../features/serviceLimit'; | ||
7 | import Button from '../../ui/Button'; | ||
8 | import { RESTRICTION_TYPES } from '../../../models/Service'; | ||
9 | |||
10 | const messages = defineMessages({ | ||
11 | headlineServiceLimit: { | ||
12 | id: 'service.restrictedHandler.serviceLimit.headline', | ||
13 | defaultMessage: '!!!You have reached your service limit.', | ||
14 | }, | ||
15 | textServiceLimit: { | ||
16 | id: 'service.restrictedHandler.serviceLimit.text', | ||
17 | defaultMessage: '!!!Please upgrade your account to use more than {count} services.', | ||
18 | }, | ||
19 | headlineCustomUrl: { | ||
20 | id: 'service.restrictedHandler.customUrl.headline', | ||
21 | defaultMessage: '!!!Franz Professional Plan required', | ||
22 | }, | ||
23 | textCustomUrl: { | ||
24 | id: 'service.restrictedHandler.customUrl.text', | ||
25 | defaultMessage: '!!!Please upgrade to the Franz Professional plan to use custom urls & self hosted services.', | ||
26 | }, | ||
27 | action: { | ||
28 | id: 'service.restrictedHandler.action', | ||
29 | defaultMessage: '!!!Upgrade Account', | ||
30 | }, | ||
31 | }); | ||
32 | |||
33 | export default @observer class ServiceRestricted extends Component { | ||
34 | static propTypes = { | ||
35 | name: PropTypes.string.isRequired, | ||
36 | upgrade: PropTypes.func.isRequired, | ||
37 | type: PropTypes.number.isRequired, | ||
38 | }; | ||
39 | |||
40 | static contextTypes = { | ||
41 | intl: intlShape, | ||
42 | }; | ||
43 | |||
44 | countdownInterval = null; | ||
45 | |||
46 | countdownIntervalTimeout = 1000; | ||
47 | |||
48 | render() { | ||
49 | const { | ||
50 | name, | ||
51 | upgrade, | ||
52 | type, | ||
53 | } = this.props; | ||
54 | const { intl } = this.context; | ||
55 | |||
56 | return ( | ||
57 | <div className="services__info-layer"> | ||
58 | {type === RESTRICTION_TYPES.SERVICE_LIMIT && ( | ||
59 | <> | ||
60 | <h1>{intl.formatMessage(messages.headlineServiceLimit)}</h1> | ||
61 | <p>{intl.formatMessage(messages.textServiceLimit, { count: serviceLimitStore.serviceLimit })}</p> | ||
62 | </> | ||
63 | )} | ||
64 | {type === RESTRICTION_TYPES.CUSTOM_URL && ( | ||
65 | <> | ||
66 | <h1>{intl.formatMessage(messages.headlineCustomUrl)}</h1> | ||
67 | <p>{intl.formatMessage(messages.textCustomUrl)}</p> | ||
68 | </> | ||
69 | )} | ||
70 | <Button | ||
71 | label={intl.formatMessage(messages.action, { name })} | ||
72 | buttonType="inverted" | ||
73 | onClick={() => upgrade()} | ||
74 | /> | ||
75 | </div> | ||
76 | ); | ||
77 | } | ||
78 | } | ||
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js index 13148b9b3..f65f51346 100644 --- a/src/components/services/content/ServiceView.js +++ b/src/components/services/content/ServiceView.js | |||
@@ -10,6 +10,7 @@ import WebviewLoader from '../../ui/WebviewLoader'; | |||
10 | import WebviewCrashHandler from './WebviewCrashHandler'; | 10 | import WebviewCrashHandler from './WebviewCrashHandler'; |
11 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; | 11 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; |
12 | import ServiceDisabled from './ServiceDisabled'; | 12 | import ServiceDisabled from './ServiceDisabled'; |
13 | import ServiceRestricted from './ServiceRestricted'; | ||
13 | import ServiceWebview from './ServiceWebview'; | 14 | import ServiceWebview from './ServiceWebview'; |
14 | 15 | ||
15 | export default @observer class ServiceView extends Component { | 16 | export default @observer class ServiceView extends Component { |
@@ -21,6 +22,7 @@ export default @observer class ServiceView extends Component { | |||
21 | edit: PropTypes.func.isRequired, | 22 | edit: PropTypes.func.isRequired, |
22 | enable: PropTypes.func.isRequired, | 23 | enable: PropTypes.func.isRequired, |
23 | isActive: PropTypes.bool, | 24 | isActive: PropTypes.bool, |
25 | upgrade: PropTypes.func.isRequired, | ||
24 | }; | 26 | }; |
25 | 27 | ||
26 | static defaultProps = { | 28 | static defaultProps = { |
@@ -72,6 +74,7 @@ export default @observer class ServiceView extends Component { | |||
72 | reload, | 74 | reload, |
73 | edit, | 75 | edit, |
74 | enable, | 76 | enable, |
77 | upgrade, | ||
75 | } = this.props; | 78 | } = this.props; |
76 | 79 | ||
77 | const webviewClasses = classnames({ | 80 | const webviewClasses = classnames({ |
@@ -99,7 +102,7 @@ export default @observer class ServiceView extends Component { | |||
99 | reload={reload} | 102 | reload={reload} |
100 | /> | 103 | /> |
101 | )} | 104 | )} |
102 | {service.isEnabled && service.isLoading && service.isFirstLoad && ( | 105 | {service.isEnabled && service.isLoading && service.isFirstLoad && !service.isServiceAccessRestricted && ( |
103 | <WebviewLoader | 106 | <WebviewLoader |
104 | loaded={false} | 107 | loaded={false} |
105 | name={service.name} | 108 | name={service.name} |
@@ -126,11 +129,21 @@ export default @observer class ServiceView extends Component { | |||
126 | )} | 129 | )} |
127 | </Fragment> | 130 | </Fragment> |
128 | ) : ( | 131 | ) : ( |
129 | <ServiceWebview | 132 | <> |
130 | service={service} | 133 | {service.isServiceAccessRestricted ? ( |
131 | setWebviewReference={setWebviewReference} | 134 | <ServiceRestricted |
132 | detachService={detachService} | 135 | name={service.recipe.name} |
133 | /> | 136 | upgrade={upgrade} |
137 | type={service.restrictionType} | ||
138 | /> | ||
139 | ) : ( | ||
140 | <ServiceWebview | ||
141 | service={service} | ||
142 | setWebviewReference={setWebviewReference} | ||
143 | detachService={detachService} | ||
144 | /> | ||
145 | )} | ||
146 | </> | ||
134 | )} | 147 | )} |
135 | {statusBar} | 148 | {statusBar} |
136 | </div> | 149 | </div> |
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js index 8f8c38a11..73c27bfb6 100644 --- a/src/components/services/content/Services.js +++ b/src/components/services/content/Services.js | |||
@@ -3,6 +3,9 @@ import PropTypes from 'prop-types'; | |||
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; |
4 | import { Link } from 'react-router'; | 4 | import { Link } from 'react-router'; |
5 | import { defineMessages, intlShape } from 'react-intl'; | 5 | import { defineMessages, intlShape } from 'react-intl'; |
6 | import Confetti from 'react-confetti'; | ||
7 | import ms from 'ms'; | ||
8 | import injectSheet from 'react-jss'; | ||
6 | 9 | ||
7 | import ServiceView from './ServiceView'; | 10 | import ServiceView from './ServiceView'; |
8 | import Appear from '../../ui/effects/Appear'; | 11 | import Appear from '../../ui/effects/Appear'; |
@@ -18,7 +21,17 @@ const messages = defineMessages({ | |||
18 | }, | 21 | }, |
19 | }); | 22 | }); |
20 | 23 | ||
21 | export default @observer class Services extends Component { | 24 | |
25 | const styles = { | ||
26 | confettiContainer: { | ||
27 | position: 'absolute', | ||
28 | width: '100%', | ||
29 | zIndex: 9999, | ||
30 | pointerEvents: 'none', | ||
31 | }, | ||
32 | }; | ||
33 | |||
34 | export default @observer @injectSheet(styles) class Services extends Component { | ||
22 | static propTypes = { | 35 | static propTypes = { |
23 | services: MobxPropTypes.arrayOrObservableArray, | 36 | services: MobxPropTypes.arrayOrObservableArray, |
24 | setWebviewReference: PropTypes.func.isRequired, | 37 | setWebviewReference: PropTypes.func.isRequired, |
@@ -28,6 +41,9 @@ export default @observer class Services extends Component { | |||
28 | reload: PropTypes.func.isRequired, | 41 | reload: PropTypes.func.isRequired, |
29 | openSettings: PropTypes.func.isRequired, | 42 | openSettings: PropTypes.func.isRequired, |
30 | update: PropTypes.func.isRequired, | 43 | update: PropTypes.func.isRequired, |
44 | userHasCompletedSignup: PropTypes.bool.isRequired, | ||
45 | hasActivatedTrial: PropTypes.bool.isRequired, | ||
46 | classes: PropTypes.object.isRequired, | ||
31 | }; | 47 | }; |
32 | 48 | ||
33 | static defaultProps = { | 49 | static defaultProps = { |
@@ -38,6 +54,18 @@ export default @observer class Services extends Component { | |||
38 | intl: intlShape, | 54 | intl: intlShape, |
39 | }; | 55 | }; |
40 | 56 | ||
57 | state = { | ||
58 | showConfetti: true, | ||
59 | } | ||
60 | |||
61 | componentDidMount() { | ||
62 | window.setTimeout(() => { | ||
63 | this.setState({ | ||
64 | showConfetti: false, | ||
65 | }); | ||
66 | }, ms('8s')); | ||
67 | } | ||
68 | |||
41 | render() { | 69 | render() { |
42 | const { | 70 | const { |
43 | services, | 71 | services, |
@@ -48,11 +76,28 @@ export default @observer class Services extends Component { | |||
48 | reload, | 76 | reload, |
49 | openSettings, | 77 | openSettings, |
50 | update, | 78 | update, |
79 | userHasCompletedSignup, | ||
80 | hasActivatedTrial, | ||
81 | classes, | ||
51 | } = this.props; | 82 | } = this.props; |
83 | |||
84 | const { | ||
85 | showConfetti, | ||
86 | } = this.state; | ||
87 | |||
52 | const { intl } = this.context; | 88 | const { intl } = this.context; |
53 | 89 | ||
54 | return ( | 90 | return ( |
55 | <div className="services"> | 91 | <div className="services"> |
92 | {(userHasCompletedSignup || hasActivatedTrial) && ( | ||
93 | <div className={classes.confettiContainer}> | ||
94 | <Confetti | ||
95 | width={window.width} | ||
96 | height={window.height} | ||
97 | numberOfPieces={showConfetti ? 200 : 0} | ||
98 | /> | ||
99 | </div> | ||
100 | )} | ||
56 | {services.length === 0 && ( | 101 | {services.length === 0 && ( |
57 | <Appear | 102 | <Appear |
58 | timeout={1500} | 103 | timeout={1500} |
@@ -89,6 +134,7 @@ export default @observer class Services extends Component { | |||
89 | }, | 134 | }, |
90 | redirect: false, | 135 | redirect: false, |
91 | })} | 136 | })} |
137 | upgrade={() => openSettings({ path: 'user' })} | ||
92 | /> | 138 | /> |
93 | ))} | 139 | ))} |
94 | </div> | 140 | </div> |
diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js index 3f6964b6b..900a83a78 100644 --- a/src/components/settings/account/AccountDashboard.js +++ b/src/components/settings/account/AccountDashboard.js | |||
@@ -1,14 +1,18 @@ | |||
1 | import React, { Component, Fragment } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; |
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import ReactTooltip from 'react-tooltip'; | 5 | import ReactTooltip from 'react-tooltip'; |
6 | import { ProBadge } from '@meetfranz/ui'; | 6 | import { |
7 | ProBadge, H1, H2, | ||
8 | } from '@meetfranz/ui'; | ||
9 | import moment from 'moment'; | ||
7 | 10 | ||
8 | import Loader from '../../ui/Loader'; | 11 | import Loader from '../../ui/Loader'; |
9 | import Button from '../../ui/Button'; | 12 | import Button from '../../ui/Button'; |
10 | import Infobox from '../../ui/Infobox'; | 13 | import Infobox from '../../ui/Infobox'; |
11 | import SubscriptionForm from '../../../containers/subscription/SubscriptionFormScreen'; | 14 | import SubscriptionForm from '../../../containers/subscription/SubscriptionFormScreen'; |
15 | import { i18nPlanName } from '../../../helpers/plan-helpers'; | ||
12 | 16 | ||
13 | const messages = defineMessages({ | 17 | const messages = defineMessages({ |
14 | headline: { | 18 | headline: { |
@@ -19,10 +23,6 @@ const messages = defineMessages({ | |||
19 | id: 'settings.account.headlineSubscription', | 23 | id: 'settings.account.headlineSubscription', |
20 | defaultMessage: '!!!Your Subscription', | 24 | defaultMessage: '!!!Your Subscription', |
21 | }, | 25 | }, |
22 | headlineUpgrade: { | ||
23 | id: 'settings.account.headlineUpgrade', | ||
24 | defaultMessage: '!!!Upgrade your Account', | ||
25 | }, | ||
26 | headlineDangerZone: { | 26 | headlineDangerZone: { |
27 | id: 'settings.account.headlineDangerZone', | 27 | id: 'settings.account.headlineDangerZone', |
28 | defaultMessage: '!!Danger Zone', | 28 | defaultMessage: '!!Danger Zone', |
@@ -31,6 +31,10 @@ const messages = defineMessages({ | |||
31 | id: 'settings.account.manageSubscription.label', | 31 | id: 'settings.account.manageSubscription.label', |
32 | defaultMessage: '!!!Manage your subscription', | 32 | defaultMessage: '!!!Manage your subscription', |
33 | }, | 33 | }, |
34 | upgradeAccountToPro: { | ||
35 | id: 'settings.account.upgradeToPro.label', | ||
36 | defaultMessage: '!!!Upgrade to Franz Professional', | ||
37 | }, | ||
34 | accountTypeBasic: { | 38 | accountTypeBasic: { |
35 | id: 'settings.account.accountType.basic', | 39 | id: 'settings.account.accountType.basic', |
36 | defaultMessage: '!!!Basic Account', | 40 | defaultMessage: '!!!Basic Account', |
@@ -71,21 +75,36 @@ const messages = defineMessages({ | |||
71 | id: 'settings.account.deleteEmailSent', | 75 | id: 'settings.account.deleteEmailSent', |
72 | defaultMessage: '!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!', | 76 | defaultMessage: '!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!', |
73 | }, | 77 | }, |
78 | trial: { | ||
79 | id: 'settings.account.trial', | ||
80 | defaultMessage: '!!!Free Trial', | ||
81 | }, | ||
82 | yourLicense: { | ||
83 | id: 'settings.account.yourLicense', | ||
84 | defaultMessage: '!!!Your Franz License:', | ||
85 | }, | ||
86 | trialEndsIn: { | ||
87 | id: 'settings.account.trialEndsIn', | ||
88 | defaultMessage: '!!!Your free trial ends in {duration}.', | ||
89 | }, | ||
90 | trialUpdateBillingInformation: { | ||
91 | id: 'settings.account.trialUpdateBillingInfo', | ||
92 | defaultMessage: '!!!Please update your billing info to continue using {license} after your trial period.', | ||
93 | }, | ||
74 | }); | 94 | }); |
75 | 95 | ||
76 | export default @observer class AccountDashboard extends Component { | 96 | export default @observer class AccountDashboard extends Component { |
77 | static propTypes = { | 97 | static propTypes = { |
78 | user: MobxPropTypes.observableObject.isRequired, | 98 | user: MobxPropTypes.observableObject.isRequired, |
79 | isLoading: PropTypes.bool.isRequired, | 99 | isLoading: PropTypes.bool.isRequired, |
80 | isLoadingPlans: PropTypes.bool.isRequired, | ||
81 | userInfoRequestFailed: PropTypes.bool.isRequired, | 100 | userInfoRequestFailed: PropTypes.bool.isRequired, |
82 | retryUserInfoRequest: PropTypes.func.isRequired, | 101 | retryUserInfoRequest: PropTypes.func.isRequired, |
83 | onCloseSubscriptionWindow: PropTypes.func.isRequired, | ||
84 | deleteAccount: PropTypes.func.isRequired, | 102 | deleteAccount: PropTypes.func.isRequired, |
85 | isLoadingDeleteAccount: PropTypes.bool.isRequired, | 103 | isLoadingDeleteAccount: PropTypes.bool.isRequired, |
86 | isDeleteAccountSuccessful: PropTypes.bool.isRequired, | 104 | isDeleteAccountSuccessful: PropTypes.bool.isRequired, |
87 | openEditAccount: PropTypes.func.isRequired, | 105 | openEditAccount: PropTypes.func.isRequired, |
88 | openBilling: PropTypes.func.isRequired, | 106 | openBilling: PropTypes.func.isRequired, |
107 | upgradeToPro: PropTypes.func.isRequired, | ||
89 | openInvoices: PropTypes.func.isRequired, | 108 | openInvoices: PropTypes.func.isRequired, |
90 | }; | 109 | }; |
91 | 110 | ||
@@ -97,19 +116,24 @@ export default @observer class AccountDashboard extends Component { | |||
97 | const { | 116 | const { |
98 | user, | 117 | user, |
99 | isLoading, | 118 | isLoading, |
100 | isLoadingPlans, | ||
101 | userInfoRequestFailed, | 119 | userInfoRequestFailed, |
102 | retryUserInfoRequest, | 120 | retryUserInfoRequest, |
103 | onCloseSubscriptionWindow, | ||
104 | deleteAccount, | 121 | deleteAccount, |
105 | isLoadingDeleteAccount, | 122 | isLoadingDeleteAccount, |
106 | isDeleteAccountSuccessful, | 123 | isDeleteAccountSuccessful, |
107 | openEditAccount, | 124 | openEditAccount, |
108 | openBilling, | 125 | openBilling, |
126 | upgradeToPro, | ||
109 | openInvoices, | 127 | openInvoices, |
110 | } = this.props; | 128 | } = this.props; |
111 | const { intl } = this.context; | 129 | const { intl } = this.context; |
112 | 130 | ||
131 | let planName = ''; | ||
132 | |||
133 | if (user.team && user.team.plan) { | ||
134 | planName = i18nPlanName(user.team.plan, intl); | ||
135 | } | ||
136 | |||
113 | return ( | 137 | return ( |
114 | <div className="settings__main"> | 138 | <div className="settings__main"> |
115 | <div className="settings__header"> | 139 | <div className="settings__header"> |
@@ -135,82 +159,113 @@ export default @observer class AccountDashboard extends Component { | |||
135 | )} | 159 | )} |
136 | 160 | ||
137 | {!userInfoRequestFailed && ( | 161 | {!userInfoRequestFailed && ( |
138 | <Fragment> | 162 | <> |
139 | {!isLoading && ( | 163 | {!isLoading && ( |
140 | <div className="account"> | 164 | <> |
141 | <div className="account__box account__box--flex"> | 165 | <div className="account"> |
142 | <div className="account__avatar"> | 166 | <div className="account__box account__box--flex"> |
143 | <img | 167 | <div className="account__avatar"> |
144 | src="./assets/images/logo.svg" | 168 | <img |
145 | alt="" | 169 | src="./assets/images/logo.svg" |
146 | /> | 170 | alt="" |
147 | </div> | 171 | /> |
148 | <div className="account__info"> | 172 | </div> |
149 | <h2> | 173 | <div className="account__info"> |
150 | <span className="username">{`${user.firstname} ${user.lastname}`}</span> | 174 | <H1> |
175 | <span className="username">{`${user.firstname} ${user.lastname}`}</span> | ||
176 | {user.isPremium && ( | ||
177 | <> | ||
178 | {' '} | ||
179 | <ProBadge /> | ||
180 | </> | ||
181 | )} | ||
182 | </H1> | ||
183 | <p> | ||
184 | {user.organization && `${user.organization}, `} | ||
185 | {user.email} | ||
186 | </p> | ||
151 | {user.isPremium && ( | 187 | {user.isPremium && ( |
188 | <div className="manage-user-links"> | ||
189 | <Button | ||
190 | label={intl.formatMessage(messages.accountEditButton)} | ||
191 | className="franz-form__button--inverted" | ||
192 | onClick={openEditAccount} | ||
193 | /> | ||
194 | </div> | ||
195 | )} | ||
196 | </div> | ||
197 | {!user.isPremium && ( | ||
198 | <Button | ||
199 | label={intl.formatMessage(messages.accountEditButton)} | ||
200 | className="franz-form__button--inverted" | ||
201 | onClick={openEditAccount} | ||
202 | /> | ||
203 | )} | ||
204 | </div> | ||
205 | </div> | ||
206 | {user.isPremium && user.isSubscriptionOwner && ( | ||
207 | <div className="account"> | ||
208 | <div className="account__box"> | ||
209 | <H2> | ||
210 | {intl.formatMessage(messages.yourLicense)} | ||
211 | </H2> | ||
212 | <p> | ||
213 | {planName} | ||
214 | {user.team.isTrial && ( | ||
215 | <> | ||
216 | {' – '} | ||
217 | {intl.formatMessage(messages.trial)} | ||
218 | </> | ||
219 | )} | ||
220 | </p> | ||
221 | {user.team.isTrial && ( | ||
152 | <> | 222 | <> |
153 | {' '} | 223 | <br /> |
154 | <ProBadge /> | 224 | <p> |
155 | <span className="badge badge--premium">{intl.formatMessage(messages.accountTypePremium)}</span> | 225 | {intl.formatMessage(messages.trialEndsIn, { |
226 | duration: moment.duration(moment().diff(user.team.trialEnd)).humanize(), | ||
227 | })} | ||
228 | </p> | ||
229 | <p> | ||
230 | {intl.formatMessage(messages.trialUpdateBillingInformation, { | ||
231 | license: planName, | ||
232 | })} | ||
233 | </p> | ||
156 | </> | 234 | </> |
157 | )} | 235 | )} |
158 | </h2> | ||
159 | {user.organization && `${user.organization}, `} | ||
160 | {user.email} | ||
161 | {user.isPremium && ( | ||
162 | <div className="manage-user-links"> | 236 | <div className="manage-user-links"> |
163 | <Button | 237 | <Button |
164 | label={intl.formatMessage(messages.accountEditButton)} | 238 | label={intl.formatMessage(messages.upgradeAccountToPro)} |
239 | className="franz-form__button--primary" | ||
240 | onClick={upgradeToPro} | ||
241 | /> | ||
242 | <Button | ||
243 | label={intl.formatMessage(messages.manageSubscriptionButtonLabel)} | ||
165 | className="franz-form__button--inverted" | 244 | className="franz-form__button--inverted" |
166 | onClick={openEditAccount} | 245 | onClick={openBilling} |
246 | /> | ||
247 | <Button | ||
248 | label={intl.formatMessage(messages.invoicesButton)} | ||
249 | className="franz-form__button--inverted" | ||
250 | onClick={openInvoices} | ||
167 | /> | 251 | /> |
168 | {user.isSubscriptionOwner && ( | ||
169 | <> | ||
170 | <Button | ||
171 | label={intl.formatMessage(messages.manageSubscriptionButtonLabel)} | ||
172 | className="franz-form__button--inverted" | ||
173 | onClick={openBilling} | ||
174 | /> | ||
175 | <Button | ||
176 | label={intl.formatMessage(messages.invoicesButton)} | ||
177 | className="franz-form__button--inverted" | ||
178 | onClick={openInvoices} | ||
179 | /> | ||
180 | </> | ||
181 | )} | ||
182 | </div> | 252 | </div> |
183 | )} | 253 | </div> |
184 | </div> | 254 | </div> |
185 | {!user.isPremium && ( | 255 | )} |
186 | <Button | 256 | {!user.isPremium && ( |
187 | label={intl.formatMessage(messages.accountEditButton)} | 257 | <div className="account franz-form"> |
188 | className="franz-form__button--inverted" | 258 | <div className="account__box"> |
189 | onClick={openEditAccount} | 259 | <SubscriptionForm /> |
190 | /> | 260 | </div> |
191 | )} | ||
192 | </div> | ||
193 | </div> | ||
194 | )} | ||
195 | |||
196 | {!user.isPremium && ( | ||
197 | isLoadingPlans ? ( | ||
198 | <Loader /> | ||
199 | ) : ( | ||
200 | <div className="account franz-form"> | ||
201 | <div className="account__box"> | ||
202 | <h2>{intl.formatMessage(messages.headlineUpgrade)}</h2> | ||
203 | <SubscriptionForm | ||
204 | onCloseWindow={onCloseSubscriptionWindow} | ||
205 | /> | ||
206 | </div> | 261 | </div> |
207 | </div> | 262 | )} |
208 | ) | 263 | </> |
209 | )} | 264 | )} |
210 | 265 | ||
211 | <div className="account franz-form"> | 266 | <div className="account franz-form"> |
212 | <div className="account__box"> | 267 | <div className="account__box"> |
213 | <h2>{intl.formatMessage(messages.headlineDangerZone)}</h2> | 268 | <H2>{intl.formatMessage(messages.headlineDangerZone)}</H2> |
214 | {!isDeleteAccountSuccessful && ( | 269 | {!isDeleteAccountSuccessful && ( |
215 | <div className="account__subscription"> | 270 | <div className="account__subscription"> |
216 | <p>{intl.formatMessage(messages.deleteInfo)}</p> | 271 | <p>{intl.formatMessage(messages.deleteInfo)}</p> |
@@ -227,7 +282,7 @@ export default @observer class AccountDashboard extends Component { | |||
227 | )} | 282 | )} |
228 | </div> | 283 | </div> |
229 | </div> | 284 | </div> |
230 | </Fragment> | 285 | </> |
231 | )} | 286 | )} |
232 | </div> | 287 | </div> |
233 | <ReactTooltip place="right" type="dark" effect="solid" /> | 288 | <ReactTooltip place="right" type="dark" effect="solid" /> |
diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.js index df4b3b3b2..4696b82eb 100644 --- a/src/components/settings/navigation/SettingsNavigation.js +++ b/src/components/settings/navigation/SettingsNavigation.js | |||
@@ -8,6 +8,7 @@ import Link from '../../ui/Link'; | |||
8 | import { workspaceStore } from '../../../features/workspaces'; | 8 | import { workspaceStore } from '../../../features/workspaces'; |
9 | import UIStore from '../../../stores/UIStore'; | 9 | import UIStore from '../../../stores/UIStore'; |
10 | import UserStore from '../../../stores/UserStore'; | 10 | import UserStore from '../../../stores/UserStore'; |
11 | import { serviceLimitStore } from '../../../features/serviceLimit'; | ||
11 | 12 | ||
12 | const messages = defineMessages({ | 13 | const messages = defineMessages({ |
13 | availableServices: { | 14 | availableServices: { |
@@ -80,7 +81,12 @@ export default @inject('stores') @observer class SettingsNavigation extends Comp | |||
80 | > | 81 | > |
81 | {intl.formatMessage(messages.yourServices)} | 82 | {intl.formatMessage(messages.yourServices)} |
82 | {' '} | 83 | {' '} |
83 | <span className="badge">{serviceCount}</span> | 84 | <span className="badge"> |
85 | {serviceCount} | ||
86 | {serviceLimitStore.serviceLimit !== 0 && ( | ||
87 | `/${serviceLimitStore.serviceLimit}` | ||
88 | )} | ||
89 | </span> | ||
84 | </Link> | 90 | </Link> |
85 | {workspaceStore.isFeatureEnabled ? ( | 91 | {workspaceStore.isFeatureEnabled ? ( |
86 | <Link | 92 | <Link |
diff --git a/src/components/settings/recipes/RecipeItem.js b/src/components/settings/recipes/RecipeItem.js index 3bb0852b2..12e3775f6 100644 --- a/src/components/settings/recipes/RecipeItem.js +++ b/src/components/settings/recipes/RecipeItem.js | |||
@@ -19,7 +19,7 @@ export default @observer class RecipeItem extends Component { | |||
19 | className="recipe-teaser" | 19 | className="recipe-teaser" |
20 | onClick={onClick} | 20 | onClick={onClick} |
21 | > | 21 | > |
22 | {recipe.local && ( | 22 | {recipe.isDevRecipe && ( |
23 | <span className="recipe-teaser__dev-badge">dev</span> | 23 | <span className="recipe-teaser__dev-badge">dev</span> |
24 | )} | 24 | )} |
25 | <img | 25 | <img |
diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js index 00cd725cf..75e60b7ec 100644 --- a/src/components/settings/recipes/RecipesDashboard.js +++ b/src/components/settings/recipes/RecipesDashboard.js | |||
@@ -4,12 +4,17 @@ import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | |||
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import { Link } from 'react-router'; | 5 | import { Link } from 'react-router'; |
6 | 6 | ||
7 | import { Button, Input } from '@meetfranz/forms'; | ||
8 | import injectSheet from 'react-jss'; | ||
9 | import { H3, H2, ProBadge } from '@meetfranz/ui'; | ||
7 | import SearchInput from '../../ui/SearchInput'; | 10 | import SearchInput from '../../ui/SearchInput'; |
8 | import Infobox from '../../ui/Infobox'; | 11 | import Infobox from '../../ui/Infobox'; |
9 | import RecipeItem from './RecipeItem'; | 12 | import RecipeItem from './RecipeItem'; |
10 | import Loader from '../../ui/Loader'; | 13 | import Loader from '../../ui/Loader'; |
11 | import Appear from '../../ui/effects/Appear'; | 14 | import Appear from '../../ui/effects/Appear'; |
12 | import { FRANZ_SERVICE_REQUEST } from '../../../config'; | 15 | import { FRANZ_SERVICE_REQUEST } from '../../../config'; |
16 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; | ||
17 | import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; | ||
13 | 18 | ||
14 | const messages = defineMessages({ | 19 | const messages = defineMessages({ |
15 | headline: { | 20 | headline: { |
@@ -28,9 +33,9 @@ const messages = defineMessages({ | |||
28 | id: 'settings.recipes.all', | 33 | id: 'settings.recipes.all', |
29 | defaultMessage: '!!!All services', | 34 | defaultMessage: '!!!All services', |
30 | }, | 35 | }, |
31 | devRecipes: { | 36 | customRecipes: { |
32 | id: 'settings.recipes.dev', | 37 | id: 'settings.recipes.custom', |
33 | defaultMessage: '!!!Development', | 38 | defaultMessage: '!!!Custom Services', |
34 | }, | 39 | }, |
35 | nothingFound: { | 40 | nothingFound: { |
36 | id: 'settings.recipes.nothingFound', | 41 | id: 'settings.recipes.nothingFound', |
@@ -44,9 +49,61 @@ const messages = defineMessages({ | |||
44 | id: 'settings.recipes.missingService', | 49 | id: 'settings.recipes.missingService', |
45 | defaultMessage: '!!!Missing a service?', | 50 | defaultMessage: '!!!Missing a service?', |
46 | }, | 51 | }, |
52 | customRecipeIntro: { | ||
53 | id: 'settings.recipes.customService.intro', | ||
54 | defaultMessage: '!!!To add a custom service, copy the recipe folder into:', | ||
55 | }, | ||
56 | openFolder: { | ||
57 | id: 'settings.recipes.customService.openFolder', | ||
58 | defaultMessage: '!!!Open directory', | ||
59 | }, | ||
60 | openDevDocs: { | ||
61 | id: 'settings.recipes.customService.openDevDocs', | ||
62 | defaultMessage: '!!!Developer Documentation', | ||
63 | }, | ||
64 | headlineCustomRecipes: { | ||
65 | id: 'settings.recipes.customService.headline.customRecipes', | ||
66 | defaultMessage: '!!!Custom Service Recipes', | ||
67 | }, | ||
68 | headlineCommunityRecipes: { | ||
69 | id: 'settings.recipes.customService.headline.communityRecipes', | ||
70 | defaultMessage: '!!!Community Services', | ||
71 | }, | ||
72 | headlineDevRecipes: { | ||
73 | id: 'settings.recipes.customService.headline.devRecipes', | ||
74 | defaultMessage: '!!!Your Development Service Recipes', | ||
75 | }, | ||
47 | }); | 76 | }); |
48 | 77 | ||
49 | export default @observer class RecipesDashboard extends Component { | 78 | const styles = { |
79 | devRecipeIntroContainer: { | ||
80 | textAlign: 'center', | ||
81 | width: '100%', | ||
82 | height: 'auto', | ||
83 | margin: [40, 0], | ||
84 | }, | ||
85 | path: { | ||
86 | marginTop: 20, | ||
87 | |||
88 | '& > div': { | ||
89 | fontFamily: 'SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace', | ||
90 | }, | ||
91 | }, | ||
92 | actionContainer: { | ||
93 | '& button': { | ||
94 | margin: [0, 10], | ||
95 | }, | ||
96 | }, | ||
97 | devRecipeList: { | ||
98 | marginTop: 20, | ||
99 | height: 'auto', | ||
100 | }, | ||
101 | proBadge: { | ||
102 | marginLeft: '10px !important', | ||
103 | }, | ||
104 | }; | ||
105 | |||
106 | export default @injectSheet(styles) @observer class RecipesDashboard extends Component { | ||
50 | static propTypes = { | 107 | static propTypes = { |
51 | recipes: MobxPropTypes.arrayOrObservableArray.isRequired, | 108 | recipes: MobxPropTypes.arrayOrObservableArray.isRequired, |
52 | isLoading: PropTypes.bool.isRequired, | 109 | isLoading: PropTypes.bool.isRequired, |
@@ -55,12 +112,18 @@ export default @observer class RecipesDashboard extends Component { | |||
55 | searchRecipes: PropTypes.func.isRequired, | 112 | searchRecipes: PropTypes.func.isRequired, |
56 | resetSearch: PropTypes.func.isRequired, | 113 | resetSearch: PropTypes.func.isRequired, |
57 | serviceStatus: MobxPropTypes.arrayOrObservableArray.isRequired, | 114 | serviceStatus: MobxPropTypes.arrayOrObservableArray.isRequired, |
58 | devRecipesCount: PropTypes.number.isRequired, | ||
59 | searchNeedle: PropTypes.string, | 115 | searchNeedle: PropTypes.string, |
116 | recipeFilter: PropTypes.string, | ||
117 | recipeDirectory: PropTypes.string.isRequired, | ||
118 | openRecipeDirectory: PropTypes.func.isRequired, | ||
119 | openDevDocs: PropTypes.func.isRequired, | ||
120 | classes: PropTypes.object.isRequired, | ||
121 | isCommunityRecipesIncludedInCurrentPlan: PropTypes.bool.isRequired, | ||
60 | }; | 122 | }; |
61 | 123 | ||
62 | static defaultProps = { | 124 | static defaultProps = { |
63 | searchNeedle: '', | 125 | searchNeedle: '', |
126 | recipeFilter: 'all', | ||
64 | } | 127 | } |
65 | 128 | ||
66 | static contextTypes = { | 129 | static contextTypes = { |
@@ -76,16 +139,26 @@ export default @observer class RecipesDashboard extends Component { | |||
76 | searchRecipes, | 139 | searchRecipes, |
77 | resetSearch, | 140 | resetSearch, |
78 | serviceStatus, | 141 | serviceStatus, |
79 | devRecipesCount, | ||
80 | searchNeedle, | 142 | searchNeedle, |
143 | recipeFilter, | ||
144 | recipeDirectory, | ||
145 | openRecipeDirectory, | ||
146 | openDevDocs, | ||
147 | classes, | ||
148 | isCommunityRecipesIncludedInCurrentPlan, | ||
81 | } = this.props; | 149 | } = this.props; |
82 | const { intl } = this.context; | 150 | const { intl } = this.context; |
83 | 151 | ||
152 | |||
153 | const communityRecipes = recipes.filter(r => !r.isDevRecipe); | ||
154 | const devRecipes = recipes.filter(r => r.isDevRecipe); | ||
155 | |||
84 | return ( | 156 | return ( |
85 | <div className="settings__main"> | 157 | <div className="settings__main"> |
86 | <div className="settings__header"> | 158 | <div className="settings__header"> |
87 | <h1>{intl.formatMessage(messages.headline)}</h1> | 159 | <h1>{intl.formatMessage(messages.headline)}</h1> |
88 | </div> | 160 | </div> |
161 | <LimitReachedInfobox /> | ||
89 | <div className="settings__body recipes"> | 162 | <div className="settings__body recipes"> |
90 | {serviceStatus.length > 0 && serviceStatus.includes('created') && ( | 163 | {serviceStatus.length > 0 && serviceStatus.includes('created') && ( |
91 | <Appear> | 164 | <Appear> |
@@ -122,20 +195,14 @@ export default @observer class RecipesDashboard extends Component { | |||
122 | > | 195 | > |
123 | {intl.formatMessage(messages.allRecipes)} | 196 | {intl.formatMessage(messages.allRecipes)} |
124 | </Link> | 197 | </Link> |
125 | {devRecipesCount > 0 && ( | 198 | <Link |
126 | <Link | 199 | to="/settings/recipes/dev" |
127 | to="/settings/recipes/dev" | 200 | className="badge" |
128 | className="badge" | 201 | activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`} |
129 | activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`} | 202 | onClick={() => resetSearch()} |
130 | onClick={() => resetSearch()} | 203 | > |
131 | > | 204 | {intl.formatMessage(messages.customRecipes)} |
132 | {intl.formatMessage(messages.devRecipes)} | 205 | </Link> |
133 | {' '} | ||
134 | ( | ||
135 | {devRecipesCount} | ||
136 | ) | ||
137 | </Link> | ||
138 | )} | ||
139 | <a href={FRANZ_SERVICE_REQUEST} target="_blank" className="link recipes__service-request"> | 206 | <a href={FRANZ_SERVICE_REQUEST} target="_blank" className="link recipes__service-request"> |
140 | {intl.formatMessage(messages.missingService)} | 207 | {intl.formatMessage(messages.missingService)} |
141 | {' '} | 208 | {' '} |
@@ -146,23 +213,78 @@ export default @observer class RecipesDashboard extends Component { | |||
146 | {isLoading ? ( | 213 | {isLoading ? ( |
147 | <Loader /> | 214 | <Loader /> |
148 | ) : ( | 215 | ) : ( |
149 | <div className="recipes__list"> | 216 | <> |
150 | {hasLoadedRecipes && recipes.length === 0 && ( | 217 | {recipeFilter === 'dev' && ( |
151 | <p className="align-middle settings__empty-state"> | 218 | <> |
152 | <span className="emoji"> | 219 | <H2> |
153 | <img src="./assets/images/emoji/dontknow.png" alt="" /> | 220 | {intl.formatMessage(messages.headlineCustomRecipes)} |
154 | </span> | 221 | {isCommunityRecipesIncludedInCurrentPlan && ( |
155 | {intl.formatMessage(messages.nothingFound)} | 222 | <ProBadge className={classes.proBadge} /> |
156 | </p> | 223 | )} |
224 | </H2> | ||
225 | <div className={classes.devRecipeIntroContainer}> | ||
226 | <p> | ||
227 | {intl.formatMessage(messages.customRecipeIntro)} | ||
228 | </p> | ||
229 | <Input | ||
230 | value={recipeDirectory} | ||
231 | className={classes.path} | ||
232 | showLabel={false} | ||
233 | /> | ||
234 | <div className={classes.actionContainer}> | ||
235 | <Button | ||
236 | onClick={openRecipeDirectory} | ||
237 | buttonType="secondary" | ||
238 | label={intl.formatMessage(messages.openFolder)} | ||
239 | /> | ||
240 | <Button | ||
241 | onClick={openDevDocs} | ||
242 | buttonType="secondary" | ||
243 | label={intl.formatMessage(messages.openDevDocs)} | ||
244 | /> | ||
245 | </div> | ||
246 | </div> | ||
247 | </> | ||
248 | )} | ||
249 | <PremiumFeatureContainer | ||
250 | condition={(recipeFilter === 'dev' && communityRecipes.length > 0) && isCommunityRecipesIncludedInCurrentPlan} | ||
251 | > | ||
252 | {recipeFilter === 'dev' && communityRecipes.length > 0 && ( | ||
253 | <H3>{intl.formatMessage(messages.headlineCommunityRecipes)}</H3> | ||
254 | )} | ||
255 | <div className="recipes__list"> | ||
256 | {hasLoadedRecipes && recipes.length === 0 && recipeFilter !== 'dev' && ( | ||
257 | <p className="align-middle settings__empty-state"> | ||
258 | <span className="emoji"> | ||
259 | <img src="./assets/images/emoji/dontknow.png" alt="" /> | ||
260 | </span> | ||
261 | {intl.formatMessage(messages.nothingFound)} | ||
262 | </p> | ||
263 | )} | ||
264 | {communityRecipes.map(recipe => ( | ||
265 | <RecipeItem | ||
266 | key={recipe.id} | ||
267 | recipe={recipe} | ||
268 | onClick={() => showAddServiceInterface({ recipeId: recipe.id })} | ||
269 | /> | ||
270 | ))} | ||
271 | </div> | ||
272 | </PremiumFeatureContainer> | ||
273 | {recipeFilter === 'dev' && devRecipes.length > 0 && ( | ||
274 | <div className={classes.devRecipeList}> | ||
275 | <H3>{intl.formatMessage(messages.headlineDevRecipes)}</H3> | ||
276 | <div className="recipes__list"> | ||
277 | {devRecipes.map(recipe => ( | ||
278 | <RecipeItem | ||
279 | key={recipe.id} | ||
280 | recipe={recipe} | ||
281 | onClick={() => showAddServiceInterface({ recipeId: recipe.id })} | ||
282 | /> | ||
283 | ))} | ||
284 | </div> | ||
285 | </div> | ||
157 | )} | 286 | )} |
158 | {recipes.map(recipe => ( | 287 | </> |
159 | <RecipeItem | ||
160 | key={recipe.id} | ||
161 | recipe={recipe} | ||
162 | onClick={() => showAddServiceInterface({ recipeId: recipe.id })} | ||
163 | /> | ||
164 | ))} | ||
165 | </div> | ||
166 | )} | 288 | )} |
167 | </div> | 289 | </div> |
168 | </div> | 290 | </div> |
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index 4ba2eb844..5cde0db8e 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js | |||
@@ -17,6 +17,8 @@ import ImageUpload from '../../ui/ImageUpload'; | |||
17 | import Select from '../../ui/Select'; | 17 | import Select from '../../ui/Select'; |
18 | 18 | ||
19 | import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; | 19 | import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; |
20 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; | ||
21 | import { serviceLimitStore } from '../../../features/serviceLimit'; | ||
20 | 22 | ||
21 | const messages = defineMessages({ | 23 | const messages = defineMessages({ |
22 | saveService: { | 24 | saveService: { |
@@ -128,8 +130,8 @@ export default @observer class EditServiceForm extends Component { | |||
128 | isSaving: PropTypes.bool.isRequired, | 130 | isSaving: PropTypes.bool.isRequired, |
129 | isDeleting: PropTypes.bool.isRequired, | 131 | isDeleting: PropTypes.bool.isRequired, |
130 | isProxyFeatureEnabled: PropTypes.bool.isRequired, | 132 | isProxyFeatureEnabled: PropTypes.bool.isRequired, |
131 | isProxyPremiumFeature: PropTypes.bool.isRequired, | 133 | isServiceProxyIncludedInCurrentPlan: PropTypes.bool.isRequired, |
132 | isSpellcheckerPremiumFeature: PropTypes.bool.isRequired, | 134 | isSpellcheckerIncludedInCurrentPlan: PropTypes.bool.isRequired, |
133 | }; | 135 | }; |
134 | 136 | ||
135 | static defaultProps = { | 137 | static defaultProps = { |
@@ -192,8 +194,8 @@ export default @observer class EditServiceForm extends Component { | |||
192 | isDeleting, | 194 | isDeleting, |
193 | onDelete, | 195 | onDelete, |
194 | isProxyFeatureEnabled, | 196 | isProxyFeatureEnabled, |
195 | isProxyPremiumFeature, | 197 | isServiceProxyIncludedInCurrentPlan, |
196 | isSpellcheckerPremiumFeature, | 198 | isSpellcheckerIncludedInCurrentPlan, |
197 | } = this.props; | 199 | } = this.props; |
198 | const { intl } = this.context; | 200 | const { intl } = this.context; |
199 | 201 | ||
@@ -252,6 +254,7 @@ export default @observer class EditServiceForm extends Component { | |||
252 | )} | 254 | )} |
253 | </span> | 255 | </span> |
254 | </div> | 256 | </div> |
257 | <LimitReachedInfobox /> | ||
255 | <div className="settings__body"> | 258 | <div className="settings__body"> |
256 | <form onSubmit={e => this.submit(e)} id="form"> | 259 | <form onSubmit={e => this.submit(e)} id="form"> |
257 | <div className="service-name"> | 260 | <div className="service-name"> |
@@ -342,7 +345,7 @@ export default @observer class EditServiceForm extends Component { | |||
342 | </div> | 345 | </div> |
343 | 346 | ||
344 | <PremiumFeatureContainer | 347 | <PremiumFeatureContainer |
345 | condition={isSpellcheckerPremiumFeature} | 348 | condition={!isSpellcheckerIncludedInCurrentPlan} |
346 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} | 349 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} |
347 | > | 350 | > |
348 | <div className="settings__settings-group"> | 351 | <div className="settings__settings-group"> |
@@ -352,7 +355,7 @@ export default @observer class EditServiceForm extends Component { | |||
352 | 355 | ||
353 | {isProxyFeatureEnabled && ( | 356 | {isProxyFeatureEnabled && ( |
354 | <PremiumFeatureContainer | 357 | <PremiumFeatureContainer |
355 | condition={isProxyPremiumFeature} | 358 | condition={!isServiceProxyIncludedInCurrentPlan} |
356 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'proxy' }} | 359 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'proxy' }} |
357 | > | 360 | > |
358 | <div className="settings__settings-group"> | 361 | <div className="settings__settings-group"> |
@@ -418,7 +421,7 @@ export default @observer class EditServiceForm extends Component { | |||
418 | type="submit" | 421 | type="submit" |
419 | label={intl.formatMessage(messages.saveService)} | 422 | label={intl.formatMessage(messages.saveService)} |
420 | htmlForm="form" | 423 | htmlForm="form" |
421 | disabled={action !== 'edit' && form.isPristine && requiresUserInput} | 424 | disabled={action !== 'edit' && ((form.isPristine && requiresUserInput) || serviceLimitStore.userHasReachedServiceLimit)} |
422 | /> | 425 | /> |
423 | )} | 426 | )} |
424 | </div> | 427 | </div> |
diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js index 53bae12df..78038e86a 100644 --- a/src/components/settings/services/ServicesDashboard.js +++ b/src/components/settings/services/ServicesDashboard.js | |||
@@ -9,6 +9,7 @@ import Infobox from '../../ui/Infobox'; | |||
9 | import Loader from '../../ui/Loader'; | 9 | import Loader from '../../ui/Loader'; |
10 | import ServiceItem from './ServiceItem'; | 10 | import ServiceItem from './ServiceItem'; |
11 | import Appear from '../../ui/effects/Appear'; | 11 | import Appear from '../../ui/effects/Appear'; |
12 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; | ||
12 | 13 | ||
13 | const messages = defineMessages({ | 14 | const messages = defineMessages({ |
14 | headline: { | 15 | headline: { |
@@ -91,6 +92,7 @@ export default @observer class ServicesDashboard extends Component { | |||
91 | <div className="settings__header"> | 92 | <div className="settings__header"> |
92 | <h1>{intl.formatMessage(messages.headline)}</h1> | 93 | <h1>{intl.formatMessage(messages.headline)}</h1> |
93 | </div> | 94 | </div> |
95 | <LimitReachedInfobox /> | ||
94 | <div className="settings__body"> | 96 | <div className="settings__body"> |
95 | {!isLoading && ( | 97 | {!isLoading && ( |
96 | <SearchInput | 98 | <SearchInput |
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index efd453356..3f9e0a6bc 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js | |||
@@ -100,7 +100,7 @@ export default @observer class EditSettingsForm extends Component { | |||
100 | isClearingAllCache: PropTypes.bool.isRequired, | 100 | isClearingAllCache: PropTypes.bool.isRequired, |
101 | onClearAllCache: PropTypes.func.isRequired, | 101 | onClearAllCache: PropTypes.func.isRequired, |
102 | cacheSize: PropTypes.string.isRequired, | 102 | cacheSize: PropTypes.string.isRequired, |
103 | isSpellcheckerPremiumFeature: PropTypes.bool.isRequired, | 103 | isSpellcheckerIncludedInCurrentPlan: PropTypes.bool.isRequired, |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static contextTypes = { | 106 | static contextTypes = { |
@@ -130,7 +130,7 @@ export default @observer class EditSettingsForm extends Component { | |||
130 | isClearingAllCache, | 130 | isClearingAllCache, |
131 | onClearAllCache, | 131 | onClearAllCache, |
132 | cacheSize, | 132 | cacheSize, |
133 | isSpellcheckerPremiumFeature, | 133 | isSpellcheckerIncludedInCurrentPlan, |
134 | } = this.props; | 134 | } = this.props; |
135 | const { intl } = this.context; | 135 | const { intl } = this.context; |
136 | 136 | ||
@@ -173,7 +173,7 @@ export default @observer class EditSettingsForm extends Component { | |||
173 | <h2 id="language">{intl.formatMessage(messages.headlineLanguage)}</h2> | 173 | <h2 id="language">{intl.formatMessage(messages.headlineLanguage)}</h2> |
174 | <Select field={form.$('locale')} showLabel={false} /> | 174 | <Select field={form.$('locale')} showLabel={false} /> |
175 | <PremiumFeatureContainer | 175 | <PremiumFeatureContainer |
176 | condition={isSpellcheckerPremiumFeature} | 176 | condition={!isSpellcheckerIncludedInCurrentPlan} |
177 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} | 177 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} |
178 | > | 178 | > |
179 | <Fragment> | 179 | <Fragment> |
diff --git a/src/components/settings/team/TeamDashboard.js b/src/components/settings/team/TeamDashboard.js index 82c517fcb..990ee52e7 100644 --- a/src/components/settings/team/TeamDashboard.js +++ b/src/components/settings/team/TeamDashboard.js | |||
@@ -133,13 +133,13 @@ export default @injectSheet(styles) @observer class TeamDashboard extends Compon | |||
133 | </div> | 133 | </div> |
134 | <img className={classes.image} src="https://cdn.franzinfra.com/announcements/assets/teams.png" alt="Franz for Teams" /> | 134 | <img className={classes.image} src="https://cdn.franzinfra.com/announcements/assets/teams.png" alt="Franz for Teams" /> |
135 | </div> | 135 | </div> |
136 | <Button | ||
137 | label={intl.formatMessage(messages.manageButton)} | ||
138 | onClick={openTeamManagement} | ||
139 | className={classes.cta} | ||
140 | /> | ||
141 | </> | 136 | </> |
142 | </PremiumFeatureContainer> | 137 | </PremiumFeatureContainer> |
138 | <Button | ||
139 | label={intl.formatMessage(messages.manageButton)} | ||
140 | onClick={openTeamManagement} | ||
141 | className={classes.cta} | ||
142 | /> | ||
143 | </> | 143 | </> |
144 | )} | 144 | )} |
145 | </> | 145 | </> |
diff --git a/src/components/subscription/SubscriptionForm.js b/src/components/subscription/SubscriptionForm.js index 50f1e0522..cdfbbe60d 100644 --- a/src/components/subscription/SubscriptionForm.js +++ b/src/components/subscription/SubscriptionForm.js | |||
@@ -1,214 +1,78 @@ | |||
1 | import React, { Component, Fragment } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import injectSheet from 'react-jss'; | ||
5 | 6 | ||
6 | import Form from '../../lib/Form'; | 7 | import { H3, H2 } from '@meetfranz/ui'; |
7 | import Radio from '../ui/Radio'; | ||
8 | import Button from '../ui/Button'; | ||
9 | import Loader from '../ui/Loader'; | ||
10 | 8 | ||
11 | import { required } from '../../helpers/validation-helpers'; | 9 | import { Button } from '@meetfranz/forms'; |
10 | import { FeatureList } from '../ui/FeatureList'; | ||
12 | 11 | ||
13 | const messages = defineMessages({ | 12 | const messages = defineMessages({ |
14 | submitButtonLabel: { | 13 | submitButtonLabel: { |
15 | id: 'subscription.submit.label', | 14 | id: 'subscription.cta.choosePlan', |
16 | defaultMessage: '!!!Support the development of Franz', | 15 | defaultMessage: '!!!Choose your plan', |
17 | }, | 16 | }, |
18 | paymentSessionError: { | 17 | teaserHeadline: { |
19 | id: 'subscription.paymentSessionError', | 18 | id: 'settings.account.headlineUpgradeAccount', |
20 | defaultMessage: '!!!Could not initialize payment form', | 19 | defaultMessage: '!!!Upgrade your account and get the full Franz experience', |
21 | }, | 20 | }, |
22 | typeFree: { | 21 | teaserText: { |
23 | id: 'subscription.type.free', | 22 | id: 'subscription.teaser.intro', |
24 | defaultMessage: '!!!free', | 23 | defaultMessage: '!!!Franz 5 comes with a wide range of new features to boost up your everyday communication - batteries included. Check out our new plans and find out which one suits you most!', |
25 | }, | ||
26 | typeMonthly: { | ||
27 | id: 'subscription.type.month', | ||
28 | defaultMessage: '!!!month', | ||
29 | }, | ||
30 | typeYearly: { | ||
31 | id: 'subscription.type.year', | ||
32 | defaultMessage: '!!!year', | ||
33 | }, | 24 | }, |
34 | includedFeatures: { | 25 | includedFeatures: { |
35 | id: 'subscription.includedFeatures', | 26 | id: 'subscription.teaser.includedFeatures', |
36 | defaultMessage: '!!!The Franz Premium Supporter Account includes', | 27 | defaultMessage: '!!!Paid Franz Plans include:', |
37 | }, | ||
38 | onpremise: { | ||
39 | id: 'subscription.features.onpremise.mattermost', | ||
40 | defaultMessage: '!!!Add on-premise/hosted services like Mattermost', | ||
41 | }, | ||
42 | noInterruptions: { | ||
43 | id: 'subscription.features.noInterruptions', | ||
44 | defaultMessage: '!!!No app delays & nagging to upgrade license', | ||
45 | }, | ||
46 | proxy: { | ||
47 | id: 'subscription.features.proxy', | ||
48 | defaultMessage: '!!!Proxy support for services', | ||
49 | }, | ||
50 | spellchecker: { | ||
51 | id: 'subscription.features.spellchecker', | ||
52 | defaultMessage: '!!!Support for Spellchecker', | ||
53 | }, | 28 | }, |
54 | workspaces: { | 29 | }); |
55 | id: 'subscription.features.workspaces', | 30 | |
56 | defaultMessage: '!!!Organize your services in workspaces', | 31 | const styles = () => ({ |
57 | }, | 32 | activateTrialButton: { |
58 | ads: { | 33 | margin: [40, 0, 50], |
59 | id: 'subscription.features.ads', | ||
60 | defaultMessage: '!!!No ads, ever!', | ||
61 | }, | ||
62 | comingSoon: { | ||
63 | id: 'subscription.features.comingSoon', | ||
64 | defaultMessage: '!!!coming soon', | ||
65 | }, | ||
66 | euTaxInfo: { | ||
67 | id: 'subscription.euTaxInfo', | ||
68 | defaultMessage: '!!!EU residents: local sales tax may apply', | ||
69 | }, | 34 | }, |
70 | }); | 35 | }); |
71 | 36 | ||
72 | export default @observer class SubscriptionForm extends Component { | 37 | export default @observer @injectSheet(styles) class SubscriptionForm extends Component { |
73 | static propTypes = { | 38 | static propTypes = { |
74 | plan: MobxPropTypes.objectOrObservableObject.isRequired, | 39 | selectPlan: PropTypes.func.isRequired, |
75 | isLoading: PropTypes.bool.isRequired, | 40 | isActivatingTrial: PropTypes.bool.isRequired, |
76 | handlePayment: PropTypes.func.isRequired, | 41 | classes: PropTypes.object.isRequired, |
77 | retryPlanRequest: PropTypes.func.isRequired, | ||
78 | isCreatingHostedPage: PropTypes.bool.isRequired, | ||
79 | error: PropTypes.bool.isRequired, | ||
80 | showSkipOption: PropTypes.bool, | ||
81 | skipAction: PropTypes.func, | ||
82 | skipButtonLabel: PropTypes.string, | ||
83 | hideInfo: PropTypes.bool.isRequired, | ||
84 | }; | ||
85 | |||
86 | static defaultProps = { | ||
87 | showSkipOption: false, | ||
88 | skipAction: () => null, | ||
89 | skipButtonLabel: '', | ||
90 | }; | 42 | }; |
91 | 43 | ||
92 | static contextTypes = { | 44 | static contextTypes = { |
93 | intl: intlShape, | 45 | intl: intlShape, |
94 | }; | 46 | }; |
95 | 47 | ||
96 | componentWillMount() { | ||
97 | this.form = this.prepareForm(); | ||
98 | } | ||
99 | |||
100 | prepareForm() { | ||
101 | const { intl } = this.context; | ||
102 | |||
103 | const form = { | ||
104 | fields: { | ||
105 | paymentTier: { | ||
106 | value: 'year', | ||
107 | validators: [required], | ||
108 | options: [{ | ||
109 | value: 'month', | ||
110 | label: `€ ${Object.hasOwnProperty.call(this.props.plan, 'month') | ||
111 | ? `${this.props.plan.month.price} / ${intl.formatMessage(messages.typeMonthly)}` | ||
112 | : 'monthly'}`, | ||
113 | }, { | ||
114 | value: 'year', | ||
115 | label: `€ ${Object.hasOwnProperty.call(this.props.plan, 'year') | ||
116 | ? `${this.props.plan.year.price} / ${intl.formatMessage(messages.typeYearly)}` | ||
117 | : 'yearly'}`, | ||
118 | }], | ||
119 | }, | ||
120 | }, | ||
121 | }; | ||
122 | |||
123 | if (this.props.showSkipOption) { | ||
124 | form.fields.paymentTier.options.unshift({ | ||
125 | value: 'skip', | ||
126 | label: `€ 0 / ${intl.formatMessage(messages.typeFree)}`, | ||
127 | }); | ||
128 | } | ||
129 | |||
130 | return new Form(form, this.context.intl); | ||
131 | } | ||
132 | |||
133 | render() { | 48 | render() { |
134 | const { | 49 | const { |
135 | isLoading, | 50 | isActivatingTrial, |
136 | isCreatingHostedPage, | 51 | selectPlan, |
137 | handlePayment, | 52 | classes, |
138 | retryPlanRequest, | ||
139 | error, | ||
140 | showSkipOption, | ||
141 | skipAction, | ||
142 | skipButtonLabel, | ||
143 | hideInfo, | ||
144 | } = this.props; | 53 | } = this.props; |
145 | const { intl } = this.context; | 54 | const { intl } = this.context; |
146 | 55 | ||
147 | if (error) { | 56 | return ( |
148 | return ( | 57 | <> |
58 | <H2>{intl.formatMessage(messages.teaserHeadline)}</H2> | ||
59 | <p>{intl.formatMessage(messages.teaserText)}</p> | ||
149 | <Button | 60 | <Button |
150 | label="Reload" | 61 | label={intl.formatMessage(messages.submitButtonLabel)} |
151 | onClick={retryPlanRequest} | 62 | className={classes.activateTrialButton} |
152 | isLoaded={!isLoading} | 63 | busy={isActivatingTrial} |
64 | onClick={selectPlan} | ||
65 | stretch | ||
153 | /> | 66 | /> |
154 | ); | 67 | <div className="subscription__premium-info"> |
155 | } | 68 | <H3> |
156 | 69 | {intl.formatMessage(messages.includedFeatures)} | |
157 | return ( | 70 | </H3> |
158 | <Loader loaded={!isLoading}> | 71 | <div className="subscription"> |
159 | <Radio field={this.form.$('paymentTier')} showLabel={false} className="paymentTiers" /> | 72 | <FeatureList /> |
160 | {!hideInfo && ( | ||
161 | <div className="subscription__premium-info"> | ||
162 | <p> | ||
163 | <strong>{intl.formatMessage(messages.includedFeatures)}</strong> | ||
164 | </p> | ||
165 | <div className="subscription"> | ||
166 | <ul className="subscription__premium-features"> | ||
167 | <li>{intl.formatMessage(messages.onpremise)}</li> | ||
168 | <li> | ||
169 | {intl.formatMessage(messages.noInterruptions)} | ||
170 | </li> | ||
171 | <li> | ||
172 | {intl.formatMessage(messages.spellchecker)} | ||
173 | </li> | ||
174 | <li> | ||
175 | {intl.formatMessage(messages.proxy)} | ||
176 | </li> | ||
177 | <li> | ||
178 | {intl.formatMessage(messages.workspaces)} | ||
179 | </li> | ||
180 | <li> | ||
181 | {intl.formatMessage(messages.ads)} | ||
182 | </li> | ||
183 | </ul> | ||
184 | </div> | ||
185 | </div> | 73 | </div> |
186 | )} | 74 | </div> |
187 | <Fragment> | 75 | </> |
188 | {error.code === 'no-payment-session' && ( | ||
189 | <p className="error-message center">{intl.formatMessage(messages.paymentSessionError)}</p> | ||
190 | )} | ||
191 | </Fragment> | ||
192 | {showSkipOption && this.form.$('paymentTier').value === 'skip' ? ( | ||
193 | <Button | ||
194 | label={skipButtonLabel} | ||
195 | className="auth__button" | ||
196 | onClick={skipAction} | ||
197 | /> | ||
198 | ) : ( | ||
199 | <Button | ||
200 | label={intl.formatMessage(messages.submitButtonLabel)} | ||
201 | className="auth__button" | ||
202 | loaded={!isCreatingHostedPage} | ||
203 | onClick={() => handlePayment(this.form.$('paymentTier').value)} | ||
204 | /> | ||
205 | )} | ||
206 | {this.form.$('paymentTier').value !== 'skip' && ( | ||
207 | <p className="legal"> | ||
208 | {intl.formatMessage(messages.euTaxInfo)} | ||
209 | </p> | ||
210 | )} | ||
211 | </Loader> | ||
212 | ); | 76 | ); |
213 | } | 77 | } |
214 | } | 78 | } |
diff --git a/src/components/subscription/SubscriptionPopup.js b/src/components/subscription/SubscriptionPopup.js index 0f6f0260f..12ef8a6e9 100644 --- a/src/components/subscription/SubscriptionPopup.js +++ b/src/components/subscription/SubscriptionPopup.js | |||
@@ -43,7 +43,7 @@ export default @observer class SubscriptionPopup extends Component { | |||
43 | 43 | ||
44 | setTimeout(() => { | 44 | setTimeout(() => { |
45 | this.props.closeWindow(); | 45 | this.props.closeWindow(); |
46 | }, ms('4s')); | 46 | }, ms('1s')); |
47 | } | 47 | } |
48 | 48 | ||
49 | render() { | 49 | render() { |
@@ -61,8 +61,6 @@ export default @observer class SubscriptionPopup extends Component { | |||
61 | autosize | 61 | autosize |
62 | src={encodeURI(url)} | 62 | src={encodeURI(url)} |
63 | onDidNavigate={completeCheck} | 63 | onDidNavigate={completeCheck} |
64 | // onNewWindow={(event, url, frameName, options) => | ||
65 | // openWindow({ event, url, frameName, options })} | ||
66 | /> | 64 | /> |
67 | </div> | 65 | </div> |
68 | <div className="subscription-popup__toolbar franz-form"> | 66 | <div className="subscription-popup__toolbar franz-form"> |
diff --git a/src/components/subscription/TrialForm.js b/src/components/subscription/TrialForm.js new file mode 100644 index 000000000..9fe1c93b7 --- /dev/null +++ b/src/components/subscription/TrialForm.js | |||
@@ -0,0 +1,114 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | import injectSheet from 'react-jss'; | ||
6 | |||
7 | import { H3, H2 } from '@meetfranz/ui'; | ||
8 | |||
9 | import { Button } from '@meetfranz/forms'; | ||
10 | import { FeatureList } from '../ui/FeatureList'; | ||
11 | import { FeatureItem } from '../ui/FeatureItem'; | ||
12 | |||
13 | const messages = defineMessages({ | ||
14 | submitButtonLabel: { | ||
15 | id: 'subscription.cta.activateTrial', | ||
16 | defaultMessage: '!!!Yes, start the free Franz Professional trial', | ||
17 | }, | ||
18 | allOptionsButton: { | ||
19 | id: 'subscription.cta.allOptions', | ||
20 | defaultMessage: '!!!See all options', | ||
21 | }, | ||
22 | teaserHeadline: { | ||
23 | id: 'settings.account.headlineTrialUpgrade', | ||
24 | defaultMessage: '!!!Get the free 14 day Franz Professional Trial', | ||
25 | }, | ||
26 | includedFeatures: { | ||
27 | id: 'subscription.includedProFeatures', | ||
28 | defaultMessage: '!!!The Franz Professional Plan includes:', | ||
29 | }, | ||
30 | noStringsAttachedHeadline: { | ||
31 | id: 'pricing.trial.terms.headline', | ||
32 | defaultMessage: '!!!No strings attached', | ||
33 | }, | ||
34 | noCreditCard: { | ||
35 | id: 'pricing.trial.terms.noCreditCard', | ||
36 | defaultMessage: '!!!No credit card required', | ||
37 | }, | ||
38 | automaticTrialEnd: { | ||
39 | id: 'pricing.trial.terms.automaticTrialEnd', | ||
40 | defaultMessage: '!!!Your free trial ends automatically after 14 days', | ||
41 | }, | ||
42 | }); | ||
43 | |||
44 | const styles = () => ({ | ||
45 | activateTrialButton: { | ||
46 | margin: [40, 0, 10], | ||
47 | }, | ||
48 | allOptionsButton: { | ||
49 | margin: [0, 0, 40], | ||
50 | background: 'none', | ||
51 | border: 'none', | ||
52 | }, | ||
53 | keyTerms: { | ||
54 | marginTop: 20, | ||
55 | }, | ||
56 | }); | ||
57 | |||
58 | export default @observer @injectSheet(styles) class TrialForm extends Component { | ||
59 | static propTypes = { | ||
60 | activateTrial: PropTypes.func.isRequired, | ||
61 | isActivatingTrial: PropTypes.bool.isRequired, | ||
62 | showAllOptions: PropTypes.func.isRequired, | ||
63 | classes: PropTypes.object.isRequired, | ||
64 | }; | ||
65 | |||
66 | static contextTypes = { | ||
67 | intl: intlShape, | ||
68 | }; | ||
69 | |||
70 | render() { | ||
71 | const { | ||
72 | isActivatingTrial, | ||
73 | activateTrial, | ||
74 | showAllOptions, | ||
75 | classes, | ||
76 | } = this.props; | ||
77 | const { intl } = this.context; | ||
78 | |||
79 | return ( | ||
80 | <> | ||
81 | <H2>{intl.formatMessage(messages.teaserHeadline)}</H2> | ||
82 | <H3 className={classes.keyTerms}> | ||
83 | {intl.formatMessage(messages.noStringsAttachedHeadline)} | ||
84 | </H3> | ||
85 | <ul> | ||
86 | <FeatureItem icon="👉" name={intl.formatMessage(messages.noCreditCard)} /> | ||
87 | <FeatureItem icon="👉" name={intl.formatMessage(messages.automaticTrialEnd)} /> | ||
88 | </ul> | ||
89 | |||
90 | <Button | ||
91 | label={intl.formatMessage(messages.submitButtonLabel)} | ||
92 | className={classes.activateTrialButton} | ||
93 | busy={isActivatingTrial} | ||
94 | onClick={activateTrial} | ||
95 | stretch | ||
96 | /> | ||
97 | <Button | ||
98 | label={intl.formatMessage(messages.allOptionsButton)} | ||
99 | className={classes.allOptionsButton} | ||
100 | onClick={showAllOptions} | ||
101 | stretch | ||
102 | /> | ||
103 | <div className="subscription__premium-info"> | ||
104 | <H3> | ||
105 | {intl.formatMessage(messages.includedFeatures)} | ||
106 | </H3> | ||
107 | <div className="subscription"> | ||
108 | <FeatureList /> | ||
109 | </div> | ||
110 | </div> | ||
111 | </> | ||
112 | ); | ||
113 | } | ||
114 | } | ||
diff --git a/src/components/ui/FeatureItem.js b/src/components/ui/FeatureItem.js new file mode 100644 index 000000000..53616f2eb --- /dev/null +++ b/src/components/ui/FeatureItem.js | |||
@@ -0,0 +1,37 @@ | |||
1 | import React from 'react'; | ||
2 | import injectSheet from 'react-jss'; | ||
3 | import { Icon } from '@meetfranz/ui'; | ||
4 | import classnames from 'classnames'; | ||
5 | import { mdiCheckCircle } from '@mdi/js'; | ||
6 | |||
7 | const styles = theme => ({ | ||
8 | featureItem: { | ||
9 | borderBottom: [1, 'solid', theme.legacyStyles.themeGrayDark], | ||
10 | padding: [8, 0], | ||
11 | display: 'flex', | ||
12 | alignItems: 'center', | ||
13 | }, | ||
14 | featureIcon: { | ||
15 | fill: theme.brandSuccess, | ||
16 | marginRight: 10, | ||
17 | }, | ||
18 | }); | ||
19 | |||
20 | export const FeatureItem = injectSheet(styles)(({ | ||
21 | classes, className, name, icon, | ||
22 | }) => ( | ||
23 | <li className={classnames({ | ||
24 | [classes.featureItem]: true, | ||
25 | [className]: className, | ||
26 | })} | ||
27 | > | ||
28 | {icon ? ( | ||
29 | <span className={classes.featureIcon}>{icon}</span> | ||
30 | ) : ( | ||
31 | <Icon icon={mdiCheckCircle} className={classes.featureIcon} size={1.5} /> | ||
32 | )} | ||
33 | {name} | ||
34 | </li> | ||
35 | )); | ||
36 | |||
37 | export default FeatureItem; | ||
diff --git a/src/components/ui/FeatureList.js b/src/components/ui/FeatureList.js new file mode 100644 index 000000000..62944ad75 --- /dev/null +++ b/src/components/ui/FeatureList.js | |||
@@ -0,0 +1,89 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { defineMessages, intlShape } from 'react-intl'; | ||
4 | |||
5 | import { FeatureItem } from './FeatureItem'; | ||
6 | |||
7 | const messages = defineMessages({ | ||
8 | unlimitedServices: { | ||
9 | id: 'pricing.features.unlimitedServices', | ||
10 | defaultMessage: '!!!Add unlimited services', | ||
11 | }, | ||
12 | spellchecker: { | ||
13 | id: 'pricing.features.spellchecker', | ||
14 | defaultMessage: '!!!Spellchecker support', | ||
15 | }, | ||
16 | workspaces: { | ||
17 | id: 'pricing.features.workspaces', | ||
18 | defaultMessage: '!!!Workspaces', | ||
19 | }, | ||
20 | customWebsites: { | ||
21 | id: 'pricing.features.customWebsites', | ||
22 | defaultMessage: '!!!Add Custom Websites', | ||
23 | }, | ||
24 | onPremise: { | ||
25 | id: 'pricing.features.onPremise', | ||
26 | defaultMessage: '!!!On-premise & other Hosted Services', | ||
27 | }, | ||
28 | thirdPartyServices: { | ||
29 | id: 'pricing.features.thirdPartyServices', | ||
30 | defaultMessage: '!!!Install 3rd party services', | ||
31 | }, | ||
32 | serviceProxies: { | ||
33 | id: 'pricing.features.serviceProxies', | ||
34 | defaultMessage: '!!!Service Proxies', | ||
35 | }, | ||
36 | teamManagement: { | ||
37 | id: 'pricing.features.teamManagement', | ||
38 | defaultMessage: '!!!Team Management', | ||
39 | }, | ||
40 | appDelays: { | ||
41 | id: 'pricing.features.appDelays', | ||
42 | defaultMessage: '!!!No Waiting Screens', | ||
43 | }, | ||
44 | adFree: { | ||
45 | id: 'pricing.features.adFree', | ||
46 | defaultMessage: '!!!Forever ad-free', | ||
47 | }, | ||
48 | }); | ||
49 | |||
50 | export class FeatureList extends Component { | ||
51 | static propTypes = { | ||
52 | className: PropTypes.string, | ||
53 | featureClassName: PropTypes.string, | ||
54 | }; | ||
55 | |||
56 | static defaultProps = { | ||
57 | className: '', | ||
58 | featureClassName: '', | ||
59 | } | ||
60 | |||
61 | static contextTypes = { | ||
62 | intl: intlShape, | ||
63 | }; | ||
64 | |||
65 | render() { | ||
66 | const { | ||
67 | className, | ||
68 | featureClassName, | ||
69 | } = this.props; | ||
70 | const { intl } = this.context; | ||
71 | |||
72 | return ( | ||
73 | <ul className={className}> | ||
74 | <FeatureItem name={intl.formatMessage(messages.unlimitedServices)} className={featureClassName} /> | ||
75 | <FeatureItem name={intl.formatMessage(messages.spellchecker)} className={featureClassName} /> | ||
76 | <FeatureItem name={intl.formatMessage(messages.workspaces)} className={featureClassName} /> | ||
77 | <FeatureItem name={intl.formatMessage(messages.customWebsites)} className={featureClassName} /> | ||
78 | <FeatureItem name={intl.formatMessage(messages.onPremise)} className={featureClassName} /> | ||
79 | <FeatureItem name={intl.formatMessage(messages.thirdPartyServices)} className={featureClassName} /> | ||
80 | <FeatureItem name={intl.formatMessage(messages.serviceProxies)} className={featureClassName} /> | ||
81 | <FeatureItem name={intl.formatMessage(messages.teamManagement)} className={featureClassName} /> | ||
82 | <FeatureItem name={intl.formatMessage(messages.appDelays)} className={featureClassName} /> | ||
83 | <FeatureItem name={intl.formatMessage(messages.adFree)} className={featureClassName} /> | ||
84 | </ul> | ||
85 | ); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | export default FeatureList; | ||
diff --git a/src/components/ui/Modal/index.js b/src/components/ui/Modal/index.js index 0b7154760..63d858c47 100644 --- a/src/components/ui/Modal/index.js +++ b/src/components/ui/Modal/index.js | |||
@@ -5,6 +5,7 @@ import classnames from 'classnames'; | |||
5 | import injectCSS from 'react-jss'; | 5 | import injectCSS from 'react-jss'; |
6 | import { Icon } from '@meetfranz/ui'; | 6 | import { Icon } from '@meetfranz/ui'; |
7 | 7 | ||
8 | import { mdiClose } from '@mdi/js'; | ||
8 | import styles from './styles'; | 9 | import styles from './styles'; |
9 | 10 | ||
10 | // ReactModal.setAppElement('#root'); | 11 | // ReactModal.setAppElement('#root'); |
@@ -59,7 +60,7 @@ export default @injectCSS(styles) class Modal extends Component { | |||
59 | className={classes.close} | 60 | className={classes.close} |
60 | onClick={close} | 61 | onClick={close} |
61 | > | 62 | > |
62 | <Icon icon="mdiClose" size={1.5} /> | 63 | <Icon icon={mdiClose} size={1.5} /> |
63 | </button> | 64 | </button> |
64 | )} | 65 | )} |
65 | <div className={classes.content}> | 66 | <div className={classes.content}> |
diff --git a/src/config.js b/src/config.js index 5bc318545..405cc5253 100644 --- a/src/config.js +++ b/src/config.js | |||
@@ -19,11 +19,16 @@ export const DEV_WS_API = 'wss://dev.franzinfra.com'; | |||
19 | export const LIVE_WS_API = 'wss://api.franzinfra.com'; | 19 | export const LIVE_WS_API = 'wss://api.franzinfra.com'; |
20 | 20 | ||
21 | export const LOCAL_API_WEBSITE = 'http://localhost:3333'; | 21 | export const LOCAL_API_WEBSITE = 'http://localhost:3333'; |
22 | export const DEV_API_WEBSITE = 'https://meetfranz.com'; | 22 | // export const DEV_API_WEBSITE = 'https://meetfranz.com';t |
23 | export const DEV_API_WEBSITE = 'http://hash-3ac3ccd2472269cf585c58a4f6973d86f3c9e7bd.franzstaging.com/'; // TODO: revert me | ||
23 | export const LIVE_API_WEBSITE = 'https://meetfranz.com'; | 24 | export const LIVE_API_WEBSITE = 'https://meetfranz.com'; |
24 | 25 | ||
25 | export const STATS_API = 'https://stats.franzinfra.com'; | 26 | export const STATS_API = 'https://stats.franzinfra.com'; |
26 | 27 | ||
28 | export const LOCAL_TODOS_FRONTEND_URL = 'http://localhost:4000'; | ||
29 | export const PRODUCTION_TODOS_FRONTEND_URL = 'https://app.franztodos.com'; | ||
30 | export const DEVELOPMENT_TODOS_FRONTEND_URL = 'https://development--franz-todos.netlify.com'; | ||
31 | |||
27 | export const GA_ID = !isDevMode ? 'UA-74126766-10' : 'UA-74126766-12'; | 32 | export const GA_ID = !isDevMode ? 'UA-74126766-10' : 'UA-74126766-12'; |
28 | 33 | ||
29 | export const DEFAULT_APP_SETTINGS = { | 34 | export const DEFAULT_APP_SETTINGS = { |
@@ -45,16 +50,16 @@ export const DEFAULT_APP_SETTINGS = { | |||
45 | }; | 50 | }; |
46 | 51 | ||
47 | export const DEFAULT_FEATURES_CONFIG = { | 52 | export const DEFAULT_FEATURES_CONFIG = { |
48 | isSpellcheckerPremiumFeature: false, | 53 | isSpellcheckerIncludedInCurrentPlan: true, |
49 | needToWaitToProceed: false, | 54 | needToWaitToProceed: false, |
50 | needToWaitToProceedConfig: { | 55 | needToWaitToProceedConfig: { |
51 | delayOffset: ms('1h'), | 56 | delayOffset: ms('1h'), |
52 | wait: ms('10s'), | 57 | wait: ms('10s'), |
53 | }, | 58 | }, |
54 | isServiceProxyEnabled: false, | 59 | isServiceProxyEnabled: false, |
55 | isServiceProxyPremiumFeature: true, | 60 | isServiceProxyIncludedInCurrentPlan: false, |
56 | isAnnouncementsEnabled: true, | 61 | isAnnouncementsEnabled: true, |
57 | isWorkspacePremiumFeature: true, | 62 | isWorkspaceIncludedInCurrentPlan: true, |
58 | isWorkspaceEnabled: false, | 63 | isWorkspaceEnabled: false, |
59 | }; | 64 | }; |
60 | 65 | ||
@@ -67,6 +72,7 @@ export const DEFAULT_WINDOW_OPTIONS = { | |||
67 | 72 | ||
68 | export const FRANZ_SERVICE_REQUEST = 'https://bit.ly/franz-plugin-docs'; | 73 | export const FRANZ_SERVICE_REQUEST = 'https://bit.ly/franz-plugin-docs'; |
69 | export const FRANZ_TRANSLATION = 'https://bit.ly/franz-translate'; | 74 | export const FRANZ_TRANSLATION = 'https://bit.ly/franz-translate'; |
75 | export const FRANZ_DEV_DOCS = 'http://bit.ly/franz-dev-hub'; | ||
70 | 76 | ||
71 | export const FILE_SYSTEM_SETTINGS_TYPES = [ | 77 | export const FILE_SYSTEM_SETTINGS_TYPES = [ |
72 | 'app', | 78 | 'app', |
@@ -83,3 +89,25 @@ export const ALLOWED_PROTOCOLS = [ | |||
83 | 'http:', | 89 | 'http:', |
84 | 'ftp:', | 90 | 'ftp:', |
85 | ]; | 91 | ]; |
92 | |||
93 | export const PLANS = { | ||
94 | PERSONAL: 'PERSONAL_MONTHLY', | ||
95 | PRO: 'PRO_MONTHLY', | ||
96 | LEGACY: 'LEGACY', | ||
97 | FREE: 'FREE', | ||
98 | }; | ||
99 | |||
100 | export const PLANS_MAPPING = { | ||
101 | 'franz-personal-monthly': PLANS.PERSONAL, | ||
102 | 'franz-personal-yearly': PLANS.PERSONAL, | ||
103 | 'franz-pro-monthly': PLANS.PRO, | ||
104 | 'franz-pro-yearly': PLANS.PRO, | ||
105 | 'franz-supporter-license': PLANS.LEGACY, | ||
106 | 'franz-supporter-license-x1': PLANS.LEGACY, | ||
107 | 'franz-supporter-license-x2': PLANS.LEGACY, | ||
108 | 'franz-supporter-license-year': PLANS.LEGACY, | ||
109 | 'franz-supporter-license-year-x1': PLANS.LEGACY, | ||
110 | 'franz-supporter-license-year-x2': PLANS.LEGACY, | ||
111 | 'franz-supporter-license-year-2019': PLANS.LEGACY, | ||
112 | free: PLANS.FREE, | ||
113 | }; | ||
diff --git a/src/containers/auth/AuthLayoutContainer.js b/src/containers/auth/AuthLayoutContainer.js index 1f9c1ea61..427054d3d 100644 --- a/src/containers/auth/AuthLayoutContainer.js +++ b/src/containers/auth/AuthLayoutContainer.js | |||
@@ -2,7 +2,6 @@ import React, { Component } from 'react'; | |||
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { inject, observer } from 'mobx-react'; | 3 | import { inject, observer } from 'mobx-react'; |
4 | import { ThemeProvider } from 'react-jss'; | 4 | import { ThemeProvider } from 'react-jss'; |
5 | import { theme } from '@meetfranz/theme'; | ||
6 | 5 | ||
7 | import AuthLayout from '../../components/auth/AuthLayout'; | 6 | import AuthLayout from '../../components/auth/AuthLayout'; |
8 | import AppStore from '../../stores/AppStore'; | 7 | import AppStore from '../../stores/AppStore'; |
@@ -24,24 +23,22 @@ export default @inject('stores', 'actions') @observer class AuthLayoutContainer | |||
24 | stores, actions, children, location, | 23 | stores, actions, children, location, |
25 | } = this.props; | 24 | } = this.props; |
26 | const { | 25 | const { |
27 | app, features, globalError, settings, | 26 | app, features, globalError, |
28 | } = stores; | 27 | } = stores; |
29 | 28 | ||
30 | const isLoadingBaseFeatures = features.defaultFeaturesRequest.isExecuting | 29 | const isLoadingBaseFeatures = features.defaultFeaturesRequest.isExecuting |
31 | && !features.defaultFeaturesRequest.wasExecuted; | 30 | && !features.defaultFeaturesRequest.wasExecuted; |
32 | 31 | ||
33 | const themeType = theme(settings.app.darkMode ? 'dark' : 'default'); | ||
34 | |||
35 | if (isLoadingBaseFeatures) { | 32 | if (isLoadingBaseFeatures) { |
36 | return ( | 33 | return ( |
37 | <ThemeProvider theme={theme(themeType)}> | 34 | <ThemeProvider theme={stores.ui.theme}> |
38 | <AppLoader /> | 35 | <AppLoader /> |
39 | </ThemeProvider> | 36 | </ThemeProvider> |
40 | ); | 37 | ); |
41 | } | 38 | } |
42 | 39 | ||
43 | return ( | 40 | return ( |
44 | <ThemeProvider theme={theme(themeType)}> | 41 | <ThemeProvider theme={stores.ui.theme}> |
45 | <AuthLayout | 42 | <AuthLayout |
46 | error={globalError.response} | 43 | error={globalError.response} |
47 | pathname={location.pathname} | 44 | pathname={location.pathname} |
@@ -50,7 +47,6 @@ export default @inject('stores', 'actions') @observer class AuthLayoutContainer | |||
50 | retryHealthCheck={actions.app.healthCheck} | 47 | retryHealthCheck={actions.app.healthCheck} |
51 | isHealthCheckLoading={app.healthCheckRequest.isExecuting} | 48 | isHealthCheckLoading={app.healthCheckRequest.isExecuting} |
52 | isFullScreen={app.isFullScreen} | 49 | isFullScreen={app.isFullScreen} |
53 | darkMode={app.isSystemDarkModeEnabled} | ||
54 | installAppUpdate={actions.app.installUpdate} | 50 | installAppUpdate={actions.app.installUpdate} |
55 | nextAppReleaseVersion={app.nextAppReleaseVersion} | 51 | nextAppReleaseVersion={app.nextAppReleaseVersion} |
56 | appUpdateIsDownloaded={app.updateStatus === app.updateStatusTypes.DOWNLOADED} | 52 | appUpdateIsDownloaded={app.updateStatus === app.updateStatusTypes.DOWNLOADED} |
diff --git a/src/containers/auth/PricingScreen.js b/src/containers/auth/PricingScreen.js index 8d179a170..af1651931 100644 --- a/src/containers/auth/PricingScreen.js +++ b/src/containers/auth/PricingScreen.js | |||
@@ -5,7 +5,6 @@ import { RouterStore } from 'mobx-react-router'; | |||
5 | 5 | ||
6 | import Pricing from '../../components/auth/Pricing'; | 6 | import Pricing from '../../components/auth/Pricing'; |
7 | import UserStore from '../../stores/UserStore'; | 7 | import UserStore from '../../stores/UserStore'; |
8 | import PaymentStore from '../../stores/PaymentStore'; | ||
9 | 8 | ||
10 | import { globalError as globalErrorPropType } from '../../prop-types'; | 9 | import { globalError as globalErrorPropType } from '../../prop-types'; |
11 | 10 | ||
@@ -14,20 +13,40 @@ export default @inject('stores', 'actions') @observer class PricingScreen extend | |||
14 | error: globalErrorPropType.isRequired, | 13 | error: globalErrorPropType.isRequired, |
15 | }; | 14 | }; |
16 | 15 | ||
16 | async submit() { | ||
17 | const { | ||
18 | actions, | ||
19 | stores, | ||
20 | } = this.props; | ||
21 | |||
22 | const { activateTrialRequest } = stores.user; | ||
23 | const { defaultTrialPlan } = stores.features.features; | ||
24 | |||
25 | actions.user.activateTrial({ planId: defaultTrialPlan }); | ||
26 | await activateTrialRequest._promise; | ||
27 | |||
28 | if (!activateTrialRequest.isError) { | ||
29 | stores.router.push('/'); | ||
30 | stores.user.hasCompletedSignup = true; | ||
31 | } | ||
32 | } | ||
33 | |||
17 | render() { | 34 | render() { |
18 | const { actions, stores, error } = this.props; | 35 | const { |
36 | error, | ||
37 | stores, | ||
38 | } = this.props; | ||
19 | 39 | ||
20 | const nextStepRoute = stores.user.legacyServices.length ? stores.user.importRoute : stores.user.inviteRoute; | 40 | const { getUserInfoRequest, activateTrialRequest } = stores.user; |
41 | const { featuresRequest } = stores.features; | ||
21 | 42 | ||
22 | return ( | 43 | return ( |
23 | <Pricing | 44 | <Pricing |
24 | donor={stores.user.data.donor || {}} | 45 | onSubmit={this.submit.bind(this)} |
25 | onSubmit={actions.user.signup} | 46 | isLoadingRequiredData={(getUserInfoRequest.isExecuting || !getUserInfoRequest.wasExecuted) || (featuresRequest.isExecuting || !featuresRequest.wasExecuted)} |
26 | onCloseSubscriptionWindow={() => this.props.stores.router.push(nextStepRoute)} | 47 | isActivatingTrial={activateTrialRequest.isExecuting} |
27 | isLoading={stores.payment.plansRequest.isExecuting} | 48 | trialActivationError={activateTrialRequest.isError} |
28 | isLoadingUser={stores.user.getUserInfoRequest.isExecuting} | ||
29 | error={error} | 49 | error={error} |
30 | skipAction={() => this.props.stores.router.push(nextStepRoute)} | ||
31 | /> | 50 | /> |
32 | ); | 51 | ); |
33 | } | 52 | } |
@@ -36,12 +55,11 @@ export default @inject('stores', 'actions') @observer class PricingScreen extend | |||
36 | PricingScreen.wrappedComponent.propTypes = { | 55 | PricingScreen.wrappedComponent.propTypes = { |
37 | actions: PropTypes.shape({ | 56 | actions: PropTypes.shape({ |
38 | user: PropTypes.shape({ | 57 | user: PropTypes.shape({ |
39 | signup: PropTypes.func.isRequired, | 58 | activateTrial: PropTypes.func.isRequired, |
40 | }).isRequired, | 59 | }).isRequired, |
41 | }).isRequired, | 60 | }).isRequired, |
42 | stores: PropTypes.shape({ | 61 | stores: PropTypes.shape({ |
43 | user: PropTypes.instanceOf(UserStore).isRequired, | 62 | user: PropTypes.instanceOf(UserStore).isRequired, |
44 | payment: PropTypes.instanceOf(PaymentStore).isRequired, | ||
45 | router: PropTypes.instanceOf(RouterStore).isRequired, | 63 | router: PropTypes.instanceOf(RouterStore).isRequired, |
46 | }).isRequired, | 64 | }).isRequired, |
47 | }; | 65 | }; |
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index d290a6094..a14a98554 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js | |||
@@ -10,6 +10,7 @@ import FeaturesStore from '../../stores/FeaturesStore'; | |||
10 | import UIStore from '../../stores/UIStore'; | 10 | import UIStore from '../../stores/UIStore'; |
11 | import NewsStore from '../../stores/NewsStore'; | 11 | import NewsStore from '../../stores/NewsStore'; |
12 | import SettingsStore from '../../stores/SettingsStore'; | 12 | import SettingsStore from '../../stores/SettingsStore'; |
13 | import UserStore from '../../stores/UserStore'; | ||
13 | import RequestStore from '../../stores/RequestStore'; | 14 | import RequestStore from '../../stores/RequestStore'; |
14 | import GlobalErrorStore from '../../stores/GlobalErrorStore'; | 15 | import GlobalErrorStore from '../../stores/GlobalErrorStore'; |
15 | 16 | ||
@@ -39,6 +40,7 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e | |||
39 | settings, | 40 | settings, |
40 | globalError, | 41 | globalError, |
41 | requests, | 42 | requests, |
43 | user, | ||
42 | } = this.props.stores; | 44 | } = this.props.stores; |
43 | 45 | ||
44 | const { | 46 | const { |
@@ -125,6 +127,8 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e | |||
125 | reload={reload} | 127 | reload={reload} |
126 | openSettings={openSettings} | 128 | openSettings={openSettings} |
127 | update={updateService} | 129 | update={updateService} |
130 | userHasCompletedSignup={user.hasCompletedSignup} | ||
131 | hasActivatedTrial={user.hasActivatedTrial} | ||
128 | /> | 132 | /> |
129 | ); | 133 | ); |
130 | 134 | ||
@@ -148,8 +152,8 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e | |||
148 | areRequiredRequestsSuccessful={requests.areRequiredRequestsSuccessful} | 152 | areRequiredRequestsSuccessful={requests.areRequiredRequestsSuccessful} |
149 | retryRequiredRequests={retryRequiredRequests} | 153 | retryRequiredRequests={retryRequiredRequests} |
150 | areRequiredRequestsLoading={requests.areRequiredRequestsLoading} | 154 | areRequiredRequestsLoading={requests.areRequiredRequestsLoading} |
151 | darkMode={settings.all.app.darkMode} | ||
152 | isDelayAppScreenVisible={delayAppState.isDelayAppScreenVisible} | 155 | isDelayAppScreenVisible={delayAppState.isDelayAppScreenVisible} |
156 | hasActivatedTrial={user.hasActivatedTrial} | ||
153 | > | 157 | > |
154 | {React.Children.count(children) > 0 ? children : null} | 158 | {React.Children.count(children) > 0 ? children : null} |
155 | </AppLayout> | 159 | </AppLayout> |
@@ -167,6 +171,7 @@ AppLayoutContainer.wrappedComponent.propTypes = { | |||
167 | ui: PropTypes.instanceOf(UIStore).isRequired, | 171 | ui: PropTypes.instanceOf(UIStore).isRequired, |
168 | news: PropTypes.instanceOf(NewsStore).isRequired, | 172 | news: PropTypes.instanceOf(NewsStore).isRequired, |
169 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | 173 | settings: PropTypes.instanceOf(SettingsStore).isRequired, |
174 | user: PropTypes.instanceOf(UserStore).isRequired, | ||
170 | requests: PropTypes.instanceOf(RequestStore).isRequired, | 175 | requests: PropTypes.instanceOf(RequestStore).isRequired, |
171 | globalError: PropTypes.instanceOf(GlobalErrorStore).isRequired, | 176 | globalError: PropTypes.instanceOf(GlobalErrorStore).isRequired, |
172 | }).isRequired, | 177 | }).isRequired, |
diff --git a/src/containers/settings/AccountScreen.js b/src/containers/settings/AccountScreen.js index 66076504f..f9eae4957 100644 --- a/src/containers/settings/AccountScreen.js +++ b/src/containers/settings/AccountScreen.js | |||
@@ -26,7 +26,7 @@ export default @inject('stores', 'actions') @observer class AccountScreen extend | |||
26 | handleWebsiteLink(route) { | 26 | handleWebsiteLink(route) { |
27 | const { actions, stores } = this.props; | 27 | const { actions, stores } = this.props; |
28 | 28 | ||
29 | const url = `${WEBSITE}${route}?authToken=${stores.user.authToken}&utm_source=app&utm_medium=account_dashboard`; | 29 | const url = stores.user.getAuthURL(`${WEBSITE}${route}?utm_source=app&utm_medium=account_dashboard`); |
30 | 30 | ||
31 | actions.app.openExternalUrl({ url }); | 31 | actions.app.openExternalUrl({ url }); |
32 | } | 32 | } |
@@ -51,6 +51,7 @@ export default @inject('stores', 'actions') @observer class AccountScreen extend | |||
51 | isLoadingDeleteAccount={user.deleteAccountRequest.isExecuting} | 51 | isLoadingDeleteAccount={user.deleteAccountRequest.isExecuting} |
52 | isDeleteAccountSuccessful={user.deleteAccountRequest.wasExecuted && !user.deleteAccountRequest.isError} | 52 | isDeleteAccountSuccessful={user.deleteAccountRequest.wasExecuted && !user.deleteAccountRequest.isError} |
53 | openEditAccount={() => this.handleWebsiteLink('/user/profile')} | 53 | openEditAccount={() => this.handleWebsiteLink('/user/profile')} |
54 | upgradeToPro={() => this.handleWebsiteLink('/inapp/user/licenses')} | ||
54 | openBilling={() => this.handleWebsiteLink('/user/billing')} | 55 | openBilling={() => this.handleWebsiteLink('/user/billing')} |
55 | openInvoices={() => this.handleWebsiteLink('/user/invoices')} | 56 | openInvoices={() => this.handleWebsiteLink('/user/invoices')} |
56 | /> | 57 | /> |
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js index 870ca4ecd..e4ff03bb3 100644 --- a/src/containers/settings/EditServiceScreen.js +++ b/src/containers/settings/EditServiceScreen.js | |||
@@ -330,8 +330,8 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
330 | onSubmit={d => this.onSubmit(d)} | 330 | onSubmit={d => this.onSubmit(d)} |
331 | onDelete={() => this.deleteService()} | 331 | onDelete={() => this.deleteService()} |
332 | isProxyFeatureEnabled={proxyFeature.isEnabled} | 332 | isProxyFeatureEnabled={proxyFeature.isEnabled} |
333 | isProxyPremiumFeature={proxyFeature.isPremium} | 333 | isServiceProxyIncludedInCurrentPlan={proxyFeature.isIncludedInCurrentPlan} |
334 | isSpellcheckerPremiumFeature={spellcheckerFeature.isPremium} | 334 | isSpellcheckerIncludedInCurrentPlan={spellcheckerFeature.isIncludedInCurrentPlan} |
335 | /> | 335 | /> |
336 | </ErrorBoundary> | 336 | </ErrorBoundary> |
337 | ); | 337 | ); |
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index 97c1fa3b1..67d52f102 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js | |||
@@ -159,8 +159,8 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e | |||
159 | }, | 159 | }, |
160 | enableSpellchecking: { | 160 | enableSpellchecking: { |
161 | label: intl.formatMessage(messages.enableSpellchecking), | 161 | label: intl.formatMessage(messages.enableSpellchecking), |
162 | value: !this.props.stores.user.data.isPremium && spellcheckerConfig.isPremium ? false : settings.all.app.enableSpellchecking, | 162 | value: !this.props.stores.user.data.isPremium && !spellcheckerConfig.isIncludedInCurrentPlan ? false : settings.all.app.enableSpellchecking, |
163 | default: !this.props.stores.user.data.isPremium && spellcheckerConfig.isPremium ? false : DEFAULT_APP_SETTINGS.enableSpellchecking, | 163 | default: !this.props.stores.user.data.isPremium && !spellcheckerConfig.isIncludedInCurrentPlan ? false : DEFAULT_APP_SETTINGS.enableSpellchecking, |
164 | }, | 164 | }, |
165 | spellcheckerLanguage: { | 165 | spellcheckerLanguage: { |
166 | label: intl.formatMessage(globalMessages.spellcheckerLanguage), | 166 | label: intl.formatMessage(globalMessages.spellcheckerLanguage), |
@@ -223,7 +223,7 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e | |||
223 | cacheSize={cacheSize} | 223 | cacheSize={cacheSize} |
224 | isClearingAllCache={isClearingAllCache} | 224 | isClearingAllCache={isClearingAllCache} |
225 | onClearAllCache={clearAllCache} | 225 | onClearAllCache={clearAllCache} |
226 | isSpellcheckerPremiumFeature={spellcheckerConfig.isPremium} | 226 | isSpellcheckerIncludedInCurrentPlan={spellcheckerConfig.isIncludedInCurrentPlan} |
227 | /> | 227 | /> |
228 | </ErrorBoundary> | 228 | </ErrorBoundary> |
229 | ); | 229 | ); |
diff --git a/src/containers/settings/RecipesScreen.js b/src/containers/settings/RecipesScreen.js index eda5ae54c..132820b6f 100644 --- a/src/containers/settings/RecipesScreen.js +++ b/src/containers/settings/RecipesScreen.js | |||
@@ -1,7 +1,9 @@ | |||
1 | import { remote, shell } from 'electron'; | ||
1 | import React, { Component } from 'react'; | 2 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 3 | import PropTypes from 'prop-types'; |
3 | import { autorun } from 'mobx'; | 4 | import { autorun } from 'mobx'; |
4 | import { inject, observer } from 'mobx-react'; | 5 | import { inject, observer } from 'mobx-react'; |
6 | import path from 'path'; | ||
5 | 7 | ||
6 | import RecipePreviewsStore from '../../stores/RecipePreviewsStore'; | 8 | import RecipePreviewsStore from '../../stores/RecipePreviewsStore'; |
7 | import RecipeStore from '../../stores/RecipesStore'; | 9 | import RecipeStore from '../../stores/RecipesStore'; |
@@ -10,6 +12,11 @@ import UserStore from '../../stores/UserStore'; | |||
10 | 12 | ||
11 | import RecipesDashboard from '../../components/settings/recipes/RecipesDashboard'; | 13 | import RecipesDashboard from '../../components/settings/recipes/RecipesDashboard'; |
12 | import ErrorBoundary from '../../components/util/ErrorBoundary'; | 14 | import ErrorBoundary from '../../components/util/ErrorBoundary'; |
15 | import { FRANZ_DEV_DOCS } from '../../config'; | ||
16 | import { gaEvent } from '../../lib/analytics'; | ||
17 | import { communityRecipesStore } from '../../features/communityRecipes'; | ||
18 | |||
19 | const { app } = remote; | ||
13 | 20 | ||
14 | export default @inject('stores', 'actions') @observer class RecipesScreen extends Component { | 21 | export default @inject('stores', 'actions') @observer class RecipesScreen extends Component { |
15 | static propTypes = { | 22 | static propTypes = { |
@@ -67,9 +74,16 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend | |||
67 | 74 | ||
68 | render() { | 75 | render() { |
69 | const { | 76 | const { |
70 | recipePreviews, recipes, services, user, | 77 | recipePreviews, |
78 | recipes, | ||
79 | services, | ||
80 | user, | ||
71 | } = this.props.stores; | 81 | } = this.props.stores; |
72 | const { showAddServiceInterface } = this.props.actions.service; | 82 | |
83 | const { | ||
84 | app: appActions, | ||
85 | service: serviceActions, | ||
86 | } = this.props.actions; | ||
73 | 87 | ||
74 | const { filter } = this.props.params; | 88 | const { filter } = this.props.params; |
75 | let recipeFilter; | 89 | let recipeFilter; |
@@ -77,7 +91,7 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend | |||
77 | if (filter === 'all') { | 91 | if (filter === 'all') { |
78 | recipeFilter = recipePreviews.all; | 92 | recipeFilter = recipePreviews.all; |
79 | } else if (filter === 'dev') { | 93 | } else if (filter === 'dev') { |
80 | recipeFilter = recipePreviews.dev; | 94 | recipeFilter = communityRecipesStore.communityRecipes; |
81 | } else { | 95 | } else { |
82 | recipeFilter = recipePreviews.featured; | 96 | recipeFilter = recipePreviews.featured; |
83 | } | 97 | } |
@@ -89,6 +103,8 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend | |||
89 | || recipes.installRecipeRequest.isExecuting | 103 | || recipes.installRecipeRequest.isExecuting |
90 | || recipePreviews.searchRecipePreviewsRequest.isExecuting; | 104 | || recipePreviews.searchRecipePreviewsRequest.isExecuting; |
91 | 105 | ||
106 | const recipeDirectory = path.join(app.getPath('userData'), 'recipes', 'dev'); | ||
107 | |||
92 | return ( | 108 | return ( |
93 | <ErrorBoundary> | 109 | <ErrorBoundary> |
94 | <RecipesDashboard | 110 | <RecipesDashboard |
@@ -97,12 +113,23 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend | |||
97 | addedServiceCount={services.all.length} | 113 | addedServiceCount={services.all.length} |
98 | isPremium={user.data.isPremium} | 114 | isPremium={user.data.isPremium} |
99 | hasLoadedRecipes={recipePreviews.featuredRecipePreviewsRequest.wasExecuted} | 115 | hasLoadedRecipes={recipePreviews.featuredRecipePreviewsRequest.wasExecuted} |
100 | showAddServiceInterface={showAddServiceInterface} | 116 | showAddServiceInterface={serviceActions.showAddServiceInterface} |
101 | searchRecipes={e => this.searchRecipes(e)} | 117 | searchRecipes={e => this.searchRecipes(e)} |
102 | resetSearch={() => this.resetSearch()} | 118 | resetSearch={() => this.resetSearch()} |
103 | searchNeedle={this.state.needle} | 119 | searchNeedle={this.state.needle} |
104 | serviceStatus={services.actionStatus} | 120 | serviceStatus={services.actionStatus} |
105 | devRecipesCount={recipePreviews.dev.length} | 121 | recipeFilter={filter} |
122 | recipeDirectory={recipeDirectory} | ||
123 | openRecipeDirectory={() => { | ||
124 | shell.openItem(recipeDirectory); | ||
125 | gaEvent('Recipe', 'open-recipe-folder', 'Open Folder'); | ||
126 | }} | ||
127 | openDevDocs={() => { | ||
128 | appActions.openExternalUrl({ url: FRANZ_DEV_DOCS }); | ||
129 | gaEvent('Recipe', 'open-dev-docs', 'Developer Documentation'); | ||
130 | }} | ||
131 | isCommunityRecipesIncludedInCurrentPlan={communityRecipesStore.isCommunityRecipesIncludedInCurrentPlan} | ||
132 | isUserPremiumUser={user.isPremium} | ||
106 | /> | 133 | /> |
107 | </ErrorBoundary> | 134 | </ErrorBoundary> |
108 | ); | 135 | ); |
@@ -117,6 +144,9 @@ RecipesScreen.wrappedComponent.propTypes = { | |||
117 | user: PropTypes.instanceOf(UserStore).isRequired, | 144 | user: PropTypes.instanceOf(UserStore).isRequired, |
118 | }).isRequired, | 145 | }).isRequired, |
119 | actions: PropTypes.shape({ | 146 | actions: PropTypes.shape({ |
147 | app: PropTypes.shape({ | ||
148 | openExternalUrl: PropTypes.func.isRequired, | ||
149 | }).isRequired, | ||
120 | service: PropTypes.shape({ | 150 | service: PropTypes.shape({ |
121 | showAddServiceInterface: PropTypes.func.isRequired, | 151 | showAddServiceInterface: PropTypes.func.isRequired, |
122 | }).isRequired, | 152 | }).isRequired, |
diff --git a/src/containers/settings/SettingsWindow.js b/src/containers/settings/SettingsWindow.js index 663b9e2e4..440d32a46 100644 --- a/src/containers/settings/SettingsWindow.js +++ b/src/containers/settings/SettingsWindow.js | |||
@@ -1,4 +1,5 @@ | |||
1 | import React, { Component } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import ReactDOM from 'react-dom'; | ||
2 | import PropTypes from 'prop-types'; | 3 | import PropTypes from 'prop-types'; |
3 | import { observer, inject } from 'mobx-react'; | 4 | import { observer, inject } from 'mobx-react'; |
4 | 5 | ||
@@ -10,10 +11,23 @@ import ErrorBoundary from '../../components/util/ErrorBoundary'; | |||
10 | import { workspaceStore } from '../../features/workspaces'; | 11 | import { workspaceStore } from '../../features/workspaces'; |
11 | 12 | ||
12 | export default @inject('stores', 'actions') @observer class SettingsContainer extends Component { | 13 | export default @inject('stores', 'actions') @observer class SettingsContainer extends Component { |
14 | portalRoot = document.querySelector('#portalContainer'); | ||
15 | |||
16 | el = document.createElement('div'); | ||
17 | |||
18 | componentDidMount() { | ||
19 | this.portalRoot.appendChild(this.el); | ||
20 | } | ||
21 | |||
22 | componentWillUnmount() { | ||
23 | this.portalRoot.removeChild(this.el); | ||
24 | } | ||
25 | |||
13 | render() { | 26 | render() { |
14 | const { children, stores } = this.props; | 27 | const { children, stores } = this.props; |
15 | const { closeSettings } = this.props.actions.ui; | 28 | const { closeSettings } = this.props.actions.ui; |
16 | 29 | ||
30 | |||
17 | const navigation = ( | 31 | const navigation = ( |
18 | <Navigation | 32 | <Navigation |
19 | serviceCount={stores.services.all.length} | 33 | serviceCount={stores.services.all.length} |
@@ -21,15 +35,18 @@ export default @inject('stores', 'actions') @observer class SettingsContainer ex | |||
21 | /> | 35 | /> |
22 | ); | 36 | ); |
23 | 37 | ||
24 | return ( | 38 | return ReactDOM.createPortal( |
25 | <ErrorBoundary> | 39 | ( |
26 | <Layout | 40 | <ErrorBoundary> |
27 | navigation={navigation} | 41 | <Layout |
28 | closeSettings={closeSettings} | 42 | navigation={navigation} |
29 | > | 43 | closeSettings={closeSettings} |
30 | {children} | 44 | > |
31 | </Layout> | 45 | {children} |
32 | </ErrorBoundary> | 46 | </Layout> |
47 | </ErrorBoundary> | ||
48 | ), | ||
49 | this.el, | ||
33 | ); | 50 | ); |
34 | } | 51 | } |
35 | } | 52 | } |
diff --git a/src/containers/settings/TeamScreen.js b/src/containers/settings/TeamScreen.js index c69d5ad08..b7b1b78cb 100644 --- a/src/containers/settings/TeamScreen.js +++ b/src/containers/settings/TeamScreen.js | |||
@@ -14,7 +14,6 @@ export default @inject('stores', 'actions') @observer class TeamScreen extends C | |||
14 | const { actions, stores } = this.props; | 14 | const { actions, stores } = this.props; |
15 | 15 | ||
16 | const url = `${WEBSITE}${route}?authToken=${stores.user.authToken}&utm_source=app&utm_medium=account_dashboard`; | 16 | const url = `${WEBSITE}${route}?authToken=${stores.user.authToken}&utm_source=app&utm_medium=account_dashboard`; |
17 | console.log(url); | ||
18 | 17 | ||
19 | actions.app.openExternalUrl({ url }); | 18 | actions.app.openExternalUrl({ url }); |
20 | } | 19 | } |
diff --git a/src/containers/subscription/SubscriptionFormScreen.js b/src/containers/subscription/SubscriptionFormScreen.js index aa1166f5e..e9e457084 100644 --- a/src/containers/subscription/SubscriptionFormScreen.js +++ b/src/containers/subscription/SubscriptionFormScreen.js | |||
@@ -1,4 +1,3 @@ | |||
1 | import { remote } from 'electron'; | ||
2 | import React, { Component } from 'react'; | 1 | import React, { Component } from 'react'; |
3 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
4 | import { inject, observer } from 'mobx-react'; | 3 | import { inject, observer } from 'mobx-react'; |
@@ -6,96 +5,50 @@ import { inject, observer } from 'mobx-react'; | |||
6 | import PaymentStore from '../../stores/PaymentStore'; | 5 | import PaymentStore from '../../stores/PaymentStore'; |
7 | 6 | ||
8 | import SubscriptionForm from '../../components/subscription/SubscriptionForm'; | 7 | import SubscriptionForm from '../../components/subscription/SubscriptionForm'; |
9 | 8 | import TrialForm from '../../components/subscription/TrialForm'; | |
10 | const { BrowserWindow } = remote; | ||
11 | 9 | ||
12 | export default @inject('stores', 'actions') @observer class SubscriptionFormScreen extends Component { | 10 | export default @inject('stores', 'actions') @observer class SubscriptionFormScreen extends Component { |
13 | static propTypes = { | 11 | async openBrowser() { |
14 | onCloseWindow: PropTypes.func, | ||
15 | content: PropTypes.node, | ||
16 | showSkipOption: PropTypes.bool, | ||
17 | skipAction: PropTypes.func, | ||
18 | skipButtonLabel: PropTypes.string, | ||
19 | hideInfo: PropTypes.bool, | ||
20 | } | ||
21 | |||
22 | static defaultProps = { | ||
23 | onCloseWindow: () => null, | ||
24 | content: '', | ||
25 | showSkipOption: false, | ||
26 | skipAction: () => null, | ||
27 | skipButtonLabel: '', | ||
28 | hideInfo: false, | ||
29 | } | ||
30 | |||
31 | async handlePayment(plan) { | ||
32 | const { | 12 | const { |
33 | actions, | 13 | actions, |
34 | stores, | 14 | stores, |
35 | onCloseWindow, | ||
36 | } = this.props; | 15 | } = this.props; |
37 | 16 | ||
38 | const interval = plan; | 17 | const { |
39 | 18 | user, | |
40 | const { id } = stores.payment.plan[interval]; | 19 | features, |
41 | actions.payment.createHostedPage({ | 20 | } = stores; |
42 | planId: id, | ||
43 | }); | ||
44 | |||
45 | const hostedPage = await stores.payment.createHostedPageRequest; | ||
46 | 21 | ||
47 | if (hostedPage.url) { | 22 | let hostedPageURL = !user.data.hadSubscription ? features.features.planSelectionURL : features.features.subscribeURL; |
48 | if (hostedPage.legacyCheckoutFlow) { | 23 | hostedPageURL = user.getAuthURL(hostedPageURL); |
49 | const paymentWindow = new BrowserWindow({ | ||
50 | parent: remote.getCurrentWindow(), | ||
51 | modal: true, | ||
52 | title: '🔒 Franz Supporter License', | ||
53 | width: 600, | ||
54 | height: window.innerHeight - 100, | ||
55 | maxWidth: 600, | ||
56 | minWidth: 600, | ||
57 | webPreferences: { | ||
58 | nodeIntegration: true, | ||
59 | webviewTag: true, | ||
60 | }, | ||
61 | }); | ||
62 | paymentWindow.loadURL(`file://${__dirname}/../../index.html#/payment/${encodeURIComponent(hostedPage.url)}`); | ||
63 | 24 | ||
64 | paymentWindow.on('closed', () => { | 25 | actions.app.openExternalUrl({ url: hostedPageURL }); |
65 | onCloseWindow(); | ||
66 | }); | ||
67 | } else { | ||
68 | actions.app.openExternalUrl({ | ||
69 | url: hostedPage.url, | ||
70 | }); | ||
71 | } | ||
72 | } | ||
73 | } | 26 | } |
74 | 27 | ||
75 | render() { | 28 | render() { |
76 | const { | 29 | const { |
77 | content, | ||
78 | actions, | 30 | actions, |
79 | stores, | 31 | stores, |
80 | showSkipOption, | ||
81 | skipAction, | ||
82 | skipButtonLabel, | ||
83 | hideInfo, | ||
84 | } = this.props; | 32 | } = this.props; |
33 | |||
34 | const { data: user } = stores.user; | ||
35 | |||
36 | if (user.hadSubscription) { | ||
37 | return ( | ||
38 | <SubscriptionForm | ||
39 | plan={stores.payment.plan} | ||
40 | selectPlan={() => this.openBrowser()} | ||
41 | isActivatingTrial={stores.user.activateTrialRequest.isExecuting || stores.user.getUserInfoRequest.isExecuting} | ||
42 | /> | ||
43 | ); | ||
44 | } | ||
45 | |||
85 | return ( | 46 | return ( |
86 | <SubscriptionForm | 47 | <TrialForm |
87 | plan={stores.payment.plan} | 48 | plan={stores.payment.plan} |
88 | isLoading={stores.payment.plansRequest.isExecuting} | 49 | activateTrial={() => actions.user.activateTrial({ planId: stores.features.features.defaultTrialPlan })} |
89 | retryPlanRequest={() => stores.payment.plansRequest.reload()} | 50 | showAllOptions={() => this.openBrowser()} |
90 | isCreatingHostedPage={stores.payment.createHostedPageRequest.isExecuting} | 51 | isActivatingTrial={stores.user.activateTrialRequest.isExecuting || stores.user.getUserInfoRequest.isExecuting} |
91 | handlePayment={price => this.handlePayment(price)} | ||
92 | content={content} | ||
93 | error={stores.payment.plansRequest.isError} | ||
94 | showSkipOption={showSkipOption} | ||
95 | skipAction={skipAction} | ||
96 | skipButtonLabel={skipButtonLabel} | ||
97 | hideInfo={hideInfo} | ||
98 | openExternalUrl={actions.app.openExternalUrl} | ||
99 | /> | 52 | /> |
100 | ); | 53 | ); |
101 | } | 54 | } |
diff --git a/src/containers/subscription/SubscriptionPopupScreen.js b/src/containers/subscription/SubscriptionPopupScreen.js index f76d6c5a6..0de5a87c4 100644 --- a/src/containers/subscription/SubscriptionPopupScreen.js +++ b/src/containers/subscription/SubscriptionPopupScreen.js | |||
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; | |||
3 | import { inject, observer } from 'mobx-react'; | 3 | import { inject, observer } from 'mobx-react'; |
4 | 4 | ||
5 | import SubscriptionPopup from '../../components/subscription/SubscriptionPopup'; | 5 | import SubscriptionPopup from '../../components/subscription/SubscriptionPopup'; |
6 | import { isDevMode } from '../../environment'; | ||
6 | 7 | ||
7 | 8 | ||
8 | export default @inject('stores', 'actions') @observer class SubscriptionPopupScreen extends Component { | 9 | export default @inject('stores', 'actions') @observer class SubscriptionPopupScreen extends Component { |
@@ -13,7 +14,7 @@ export default @inject('stores', 'actions') @observer class SubscriptionPopupScr | |||
13 | completeCheck(event) { | 14 | completeCheck(event) { |
14 | const { url } = event; | 15 | const { url } = event; |
15 | 16 | ||
16 | if ((url.includes('recurly') && url.includes('confirmation')) || (url.includes('meetfranz') && url.includes('success'))) { | 17 | if ((url.includes('recurly') && url.includes('confirmation')) || ((url.includes('meetfranz') || isDevMode) && url.includes('success'))) { |
17 | this.setState({ | 18 | this.setState({ |
18 | complete: true, | 19 | complete: true, |
19 | }); | 20 | }); |
diff --git a/src/environment.js b/src/environment.js index ae7a67e4d..707449e09 100644 --- a/src/environment.js +++ b/src/environment.js | |||
@@ -10,6 +10,9 @@ import { | |||
10 | LIVE_WS_API, | 10 | LIVE_WS_API, |
11 | LOCAL_WS_API, | 11 | LOCAL_WS_API, |
12 | DEV_WS_API, | 12 | DEV_WS_API, |
13 | LOCAL_TODOS_FRONTEND_URL, | ||
14 | PRODUCTION_TODOS_FRONTEND_URL, | ||
15 | DEVELOPMENT_TODOS_FRONTEND_URL, | ||
13 | } from './config'; | 16 | } from './config'; |
14 | 17 | ||
15 | export const isDevMode = isDev; | 18 | export const isDevMode = isDev; |
@@ -31,21 +34,26 @@ export const cmdKey = isMac ? 'Cmd' : 'Ctrl'; | |||
31 | let api; | 34 | let api; |
32 | let wsApi; | 35 | let wsApi; |
33 | let web; | 36 | let web; |
37 | let todos; | ||
34 | if (!isDevMode || (isDevMode && useLiveAPI)) { | 38 | if (!isDevMode || (isDevMode && useLiveAPI)) { |
35 | api = LIVE_API; | 39 | api = LIVE_API; |
36 | wsApi = LIVE_WS_API; | 40 | wsApi = LIVE_WS_API; |
37 | web = LIVE_API_WEBSITE; | 41 | web = LIVE_API_WEBSITE; |
42 | todos = PRODUCTION_TODOS_FRONTEND_URL; | ||
38 | } else if (isDevMode && useLocalAPI) { | 43 | } else if (isDevMode && useLocalAPI) { |
39 | api = LOCAL_API; | 44 | api = LOCAL_API; |
40 | wsApi = LOCAL_WS_API; | 45 | wsApi = LOCAL_WS_API; |
41 | web = LOCAL_API_WEBSITE; | 46 | web = LOCAL_API_WEBSITE; |
47 | todos = LOCAL_TODOS_FRONTEND_URL; | ||
42 | } else { | 48 | } else { |
43 | api = DEV_API; | 49 | api = DEV_API; |
44 | wsApi = DEV_WS_API; | 50 | wsApi = DEV_WS_API; |
45 | web = DEV_API_WEBSITE; | 51 | web = DEV_API_WEBSITE; |
52 | todos = DEVELOPMENT_TODOS_FRONTEND_URL; | ||
46 | } | 53 | } |
47 | 54 | ||
48 | export const API = api; | 55 | export const API = api; |
49 | export const API_VERSION = 'v1'; | 56 | export const API_VERSION = 'v1'; |
50 | export const WS_API = wsApi; | 57 | export const WS_API = wsApi; |
51 | export const WEBSITE = web; | 58 | export const WEBSITE = web; |
59 | export const TODOS_FRONTEND = todos; | ||
diff --git a/src/features/announcements/components/AnnouncementScreen.js b/src/features/announcements/components/AnnouncementScreen.js index e7c5fe395..03bd5ba41 100644 --- a/src/features/announcements/components/AnnouncementScreen.js +++ b/src/features/announcements/components/AnnouncementScreen.js | |||
@@ -28,7 +28,7 @@ const smallScreen = '1000px'; | |||
28 | const styles = theme => ({ | 28 | const styles = theme => ({ |
29 | container: { | 29 | container: { |
30 | background: theme.colorBackground, | 30 | background: theme.colorBackground, |
31 | position: 'absolute', | 31 | position: 'relative', |
32 | top: 0, | 32 | top: 0, |
33 | zIndex: 140, | 33 | zIndex: 140, |
34 | width: '100%', | 34 | width: '100%', |
diff --git a/src/features/basicAuth/Component.js b/src/features/basicAuth/Component.js index a8252acb7..ba9ae2273 100644 --- a/src/features/basicAuth/Component.js +++ b/src/features/basicAuth/Component.js | |||
@@ -27,7 +27,6 @@ export default @injectSheet(styles) @observer class BasicAuthModal extends Compo | |||
27 | e.preventDefault(); | 27 | e.preventDefault(); |
28 | 28 | ||
29 | const values = Form.values(); | 29 | const values = Form.values(); |
30 | console.log('form submit', values); | ||
31 | 30 | ||
32 | sendCredentials(values.user, values.password); | 31 | sendCredentials(values.user, values.password); |
33 | resetState(); | 32 | resetState(); |
diff --git a/src/features/communityRecipes/index.js b/src/features/communityRecipes/index.js new file mode 100644 index 000000000..4d050f90e --- /dev/null +++ b/src/features/communityRecipes/index.js | |||
@@ -0,0 +1,28 @@ | |||
1 | import { reaction } from 'mobx'; | ||
2 | import { CommunityRecipesStore } from './store'; | ||
3 | |||
4 | const debug = require('debug')('Franz:feature:communityRecipes'); | ||
5 | |||
6 | export const DEFAULT_SERVICE_LIMIT = 3; | ||
7 | |||
8 | export const communityRecipesStore = new CommunityRecipesStore(); | ||
9 | |||
10 | export default function initCommunityRecipes(stores, actions) { | ||
11 | const { features } = stores; | ||
12 | |||
13 | communityRecipesStore.start(stores, actions); | ||
14 | |||
15 | // Toggle communityRecipe premium status | ||
16 | reaction( | ||
17 | () => ( | ||
18 | features.features.isCommunityRecipesIncludedInCurrentPlan | ||
19 | ), | ||
20 | (isPremiumFeature) => { | ||
21 | debug('Community recipes is premium feature: ', isPremiumFeature); | ||
22 | communityRecipesStore.isCommunityRecipesIncludedInCurrentPlan = isPremiumFeature; | ||
23 | }, | ||
24 | { | ||
25 | fireImmediately: true, | ||
26 | }, | ||
27 | ); | ||
28 | } | ||
diff --git a/src/features/communityRecipes/store.js b/src/features/communityRecipes/store.js new file mode 100644 index 000000000..4d45c3b33 --- /dev/null +++ b/src/features/communityRecipes/store.js | |||
@@ -0,0 +1,31 @@ | |||
1 | import { computed, observable } from 'mobx'; | ||
2 | import { FeatureStore } from '../utils/FeatureStore'; | ||
3 | |||
4 | const debug = require('debug')('Franz:feature:communityRecipes:store'); | ||
5 | |||
6 | export class CommunityRecipesStore extends FeatureStore { | ||
7 | @observable isCommunityRecipesIncludedInCurrentPlan = false; | ||
8 | |||
9 | start(stores, actions) { | ||
10 | debug('start'); | ||
11 | this.stores = stores; | ||
12 | this.actions = actions; | ||
13 | } | ||
14 | |||
15 | stop() { | ||
16 | debug('stop'); | ||
17 | super.stop(); | ||
18 | } | ||
19 | |||
20 | @computed get communityRecipes() { | ||
21 | if (!this.stores) return []; | ||
22 | |||
23 | return this.stores.recipePreviews.dev.map((r) => { | ||
24 | r.isDevRecipe = !!r.author.find(a => a.email === this.stores.user.data.email); | ||
25 | |||
26 | return r; | ||
27 | }); | ||
28 | } | ||
29 | } | ||
30 | |||
31 | export default CommunityRecipesStore; | ||
diff --git a/src/features/delayApp/Component.js b/src/features/delayApp/Component.js index ff0f1f2f8..de5653f04 100644 --- a/src/features/delayApp/Component.js +++ b/src/features/delayApp/Component.js | |||
@@ -4,29 +4,39 @@ import { inject, observer } from 'mobx-react'; | |||
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import injectSheet from 'react-jss'; | 5 | import injectSheet from 'react-jss'; |
6 | 6 | ||
7 | import { Button } from '@meetfranz/forms'; | ||
7 | import { gaEvent } from '../../lib/analytics'; | 8 | import { gaEvent } from '../../lib/analytics'; |
8 | 9 | ||
9 | import Button from '../../components/ui/Button'; | 10 | // import Button from '../../components/ui/Button'; |
10 | 11 | ||
11 | import { config } from '.'; | 12 | import { config } from '.'; |
12 | import styles from './styles'; | 13 | import styles from './styles'; |
14 | import UserStore from '../../stores/UserStore'; | ||
13 | 15 | ||
14 | const messages = defineMessages({ | 16 | const messages = defineMessages({ |
15 | headline: { | 17 | headline: { |
16 | id: 'feature.delayApp.headline', | 18 | id: 'feature.delayApp.headline', |
17 | defaultMessage: '!!!Please purchase license to skip waiting', | 19 | defaultMessage: '!!!Please purchase license to skip waiting', |
18 | }, | 20 | }, |
21 | headlineTrial: { | ||
22 | id: 'feature.delayApp.trial.headline', | ||
23 | defaultMessage: '!!!Get the free Franz Professional 14 day trial and skip the line', | ||
24 | }, | ||
19 | action: { | 25 | action: { |
20 | id: 'feature.delayApp.action', | 26 | id: 'feature.delayApp.upgrade.action', |
21 | defaultMessage: '!!!Get a Franz Supporter License', | 27 | defaultMessage: '!!!Get a Franz Supporter License', |
22 | }, | 28 | }, |
29 | actionTrial: { | ||
30 | id: 'feature.delayApp.trial.action', | ||
31 | defaultMessage: '!!!Yes, I want the free 14 day trial of Franz Professional', | ||
32 | }, | ||
23 | text: { | 33 | text: { |
24 | id: 'feature.delayApp.text', | 34 | id: 'feature.delayApp.text', |
25 | defaultMessage: '!!!Franz will continue in {seconds} seconds.', | 35 | defaultMessage: '!!!Franz will continue in {seconds} seconds.', |
26 | }, | 36 | }, |
27 | }); | 37 | }); |
28 | 38 | ||
29 | export default @inject('actions') @injectSheet(styles) @observer class DelayApp extends Component { | 39 | export default @inject('stores', 'actions') @injectSheet(styles) @observer class DelayApp extends Component { |
30 | static propTypes = { | 40 | static propTypes = { |
31 | // eslint-disable-next-line | 41 | // eslint-disable-next-line |
32 | classes: PropTypes.object.isRequired, | 42 | classes: PropTypes.object.isRequired, |
@@ -62,25 +72,37 @@ export default @inject('actions') @injectSheet(styles) @observer class DelayApp | |||
62 | } | 72 | } |
63 | 73 | ||
64 | handleCTAClick() { | 74 | handleCTAClick() { |
65 | const { actions } = this.props; | 75 | const { actions, stores } = this.props; |
76 | const { hadSubscription } = stores.user.data; | ||
77 | const { defaultTrialPlan } = stores.features.features; | ||
78 | |||
79 | if (!hadSubscription) { | ||
80 | console.log('directly activate trial'); | ||
81 | actions.user.activateTrial({ planId: defaultTrialPlan }); | ||
66 | 82 | ||
67 | actions.ui.openSettings({ path: 'user' }); | 83 | gaEvent('DelayApp', 'subscribe_click', 'Delay App Feature'); |
84 | } else { | ||
85 | actions.ui.openSettings({ path: 'user' }); | ||
68 | 86 | ||
69 | gaEvent('DelayApp', 'subscribe_click', 'Delay App Feature'); | 87 | gaEvent('DelayApp', 'subscribe_click', 'Delay App Feature'); |
88 | } | ||
70 | } | 89 | } |
71 | 90 | ||
72 | render() { | 91 | render() { |
73 | const { classes } = this.props; | 92 | const { classes, stores } = this.props; |
74 | const { intl } = this.context; | 93 | const { intl } = this.context; |
75 | 94 | ||
95 | const { hadSubscription } = stores.user.data; | ||
96 | |||
76 | return ( | 97 | return ( |
77 | <div className={`${classes.container}`}> | 98 | <div className={`${classes.container}`}> |
78 | <h1 className={classes.headline}>{intl.formatMessage(messages.headline)}</h1> | 99 | <h1 className={classes.headline}>{intl.formatMessage(hadSubscription ? messages.headline : messages.headlineTrial)}</h1> |
79 | <Button | 100 | <Button |
80 | label={intl.formatMessage(messages.action)} | 101 | label={intl.formatMessage(hadSubscription ? messages.action : messages.actionTrial)} |
81 | className={classes.button} | 102 | className={classes.button} |
82 | buttonType="inverted" | 103 | buttonType="inverted" |
83 | onClick={this.handleCTAClick.bind(this)} | 104 | onClick={this.handleCTAClick.bind(this)} |
105 | busy={stores.user.activateTrialRequest.isExecuting} | ||
84 | /> | 106 | /> |
85 | <p className="footnote"> | 107 | <p className="footnote"> |
86 | {intl.formatMessage(messages.text, { | 108 | {intl.formatMessage(messages.text, { |
@@ -93,6 +115,9 @@ export default @inject('actions') @injectSheet(styles) @observer class DelayApp | |||
93 | } | 115 | } |
94 | 116 | ||
95 | DelayApp.wrappedComponent.propTypes = { | 117 | DelayApp.wrappedComponent.propTypes = { |
118 | stores: PropTypes.shape({ | ||
119 | user: PropTypes.instanceOf(UserStore).isRequired, | ||
120 | }).isRequired, | ||
96 | actions: PropTypes.shape({ | 121 | actions: PropTypes.shape({ |
97 | ui: PropTypes.shape({ | 122 | ui: PropTypes.shape({ |
98 | openSettings: PropTypes.func.isRequired, | 123 | openSettings: PropTypes.func.isRequired, |
diff --git a/src/features/delayApp/index.js b/src/features/delayApp/index.js index 67f0fc5e6..627537de7 100644 --- a/src/features/delayApp/index.js +++ b/src/features/delayApp/index.js | |||
@@ -33,7 +33,7 @@ export default function init(stores) { | |||
33 | }; | 33 | }; |
34 | 34 | ||
35 | reaction( | 35 | reaction( |
36 | () => stores.user.isLoggedIn && stores.features.features.needToWaitToProceed && !stores.user.data.isPremium, | 36 | () => stores.user.isLoggedIn && stores.services.allServicesRequest.wasExecuted && stores.features.features.needToWaitToProceed && !stores.user.data.isPremium, |
37 | (isEnabled) => { | 37 | (isEnabled) => { |
38 | if (isEnabled) { | 38 | if (isEnabled) { |
39 | debug('Enabling `delayApp` feature'); | 39 | debug('Enabling `delayApp` feature'); |
@@ -44,7 +44,8 @@ export default function init(stores) { | |||
44 | config.delayDuration = globalConfig.wait !== undefined ? globalConfig.wait : DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.wait; | 44 | config.delayDuration = globalConfig.wait !== undefined ? globalConfig.wait : DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.wait; |
45 | 45 | ||
46 | autorun(() => { | 46 | autorun(() => { |
47 | if (stores.services.all.length === 0) { | 47 | if (stores.services.allDisplayed.length === 0) { |
48 | debug('seas', stores.services.all.length); | ||
48 | shownAfterLaunch = true; | 49 | shownAfterLaunch = true; |
49 | return; | 50 | return; |
50 | } | 51 | } |
@@ -64,7 +65,7 @@ export default function init(stores) { | |||
64 | debug('Resetting app delay'); | 65 | debug('Resetting app delay'); |
65 | 66 | ||
66 | setVisibility(false); | 67 | setVisibility(false); |
67 | }, DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.wait + 1000); // timer needs to be able to hit 0 | 68 | }, config.delayDuration + 1000); // timer needs to be able to hit 0 |
68 | } | 69 | } |
69 | }); | 70 | }); |
70 | } else { | 71 | } else { |
diff --git a/src/features/delayApp/styles.js b/src/features/delayApp/styles.js index 5c214cfdf..69c3c7a27 100644 --- a/src/features/delayApp/styles.js +++ b/src/features/delayApp/styles.js | |||
@@ -1,7 +1,6 @@ | |||
1 | export default theme => ({ | 1 | export default theme => ({ |
2 | container: { | 2 | container: { |
3 | background: theme.colorBackground, | 3 | background: theme.colorBackground, |
4 | position: 'absolute', | ||
5 | top: 0, | 4 | top: 0, |
6 | width: '100%', | 5 | width: '100%', |
7 | display: 'flex', | 6 | display: 'flex', |
diff --git a/src/features/serviceLimit/components/LimitReachedInfobox.js b/src/features/serviceLimit/components/LimitReachedInfobox.js new file mode 100644 index 000000000..fc54dcf85 --- /dev/null +++ b/src/features/serviceLimit/components/LimitReachedInfobox.js | |||
@@ -0,0 +1,78 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { inject, observer } from 'mobx-react'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | import injectSheet from 'react-jss'; | ||
6 | import { Infobox } from '@meetfranz/ui'; | ||
7 | |||
8 | import { gaEvent } from '../../../lib/analytics'; | ||
9 | |||
10 | const messages = defineMessages({ | ||
11 | limitReached: { | ||
12 | id: 'feature.serviceLimit.limitReached', | ||
13 | defaultMessage: '!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.', | ||
14 | }, | ||
15 | action: { | ||
16 | id: 'premiumFeature.button.upgradeAccount', | ||
17 | defaultMessage: '!!!Upgrade account', | ||
18 | }, | ||
19 | }); | ||
20 | |||
21 | const styles = theme => ({ | ||
22 | container: { | ||
23 | height: 'auto', | ||
24 | background: theme.styleTypes.primary.accent, | ||
25 | color: theme.styleTypes.primary.contrast, | ||
26 | borderRadius: 0, | ||
27 | marginBottom: 0, | ||
28 | |||
29 | '& > div': { | ||
30 | marginBottom: 0, | ||
31 | }, | ||
32 | |||
33 | '& button': { | ||
34 | color: theme.styleTypes.primary.contrast, | ||
35 | }, | ||
36 | }, | ||
37 | }); | ||
38 | |||
39 | |||
40 | @inject('stores', 'actions') @injectSheet(styles) @observer | ||
41 | class LimitReachedInfobox extends Component { | ||
42 | static propTypes = { | ||
43 | classes: PropTypes.object.isRequired, | ||
44 | stores: PropTypes.object.isRequired, | ||
45 | actions: PropTypes.object.isRequired, | ||
46 | }; | ||
47 | |||
48 | static contextTypes = { | ||
49 | intl: intlShape, | ||
50 | }; | ||
51 | |||
52 | render() { | ||
53 | const { classes, stores, actions } = this.props; | ||
54 | const { intl } = this.context; | ||
55 | |||
56 | const { | ||
57 | serviceLimit, | ||
58 | } = stores; | ||
59 | |||
60 | if (!serviceLimit.userHasReachedServiceLimit) return null; | ||
61 | |||
62 | return ( | ||
63 | <Infobox | ||
64 | icon="mdiInformation" | ||
65 | className={classes.container} | ||
66 | ctaLabel={intl.formatMessage(messages.action)} | ||
67 | ctaOnClick={() => { | ||
68 | actions.ui.openSettings({ path: 'user' }); | ||
69 | gaEvent('Service Limit', 'upgrade', 'Upgrade account'); | ||
70 | }} | ||
71 | > | ||
72 | {intl.formatMessage(messages.limitReached, { amount: serviceLimit.serviceCount, limit: serviceLimit.serviceLimit })} | ||
73 | </Infobox> | ||
74 | ); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | export default LimitReachedInfobox; | ||
diff --git a/src/features/serviceLimit/index.js b/src/features/serviceLimit/index.js new file mode 100644 index 000000000..92ad8bb98 --- /dev/null +++ b/src/features/serviceLimit/index.js | |||
@@ -0,0 +1,33 @@ | |||
1 | import { reaction } from 'mobx'; | ||
2 | import { ServiceLimitStore } from './store'; | ||
3 | |||
4 | const debug = require('debug')('Franz:feature:serviceLimit'); | ||
5 | |||
6 | export const DEFAULT_SERVICE_LIMIT = 3; | ||
7 | |||
8 | let store = null; | ||
9 | |||
10 | export const serviceLimitStore = new ServiceLimitStore(); | ||
11 | |||
12 | export default function initServiceLimit(stores, actions) { | ||
13 | const { features } = stores; | ||
14 | |||
15 | // Toggle serviceLimit feature | ||
16 | reaction( | ||
17 | () => ( | ||
18 | features.features.isServiceLimitEnabled | ||
19 | ), | ||
20 | (isEnabled) => { | ||
21 | if (isEnabled) { | ||
22 | debug('Initializing `serviceLimit` feature'); | ||
23 | store = serviceLimitStore.start(stores, actions); | ||
24 | } else if (store) { | ||
25 | debug('Disabling `serviceLimit` feature'); | ||
26 | serviceLimitStore.stop(); | ||
27 | } | ||
28 | }, | ||
29 | { | ||
30 | fireImmediately: true, | ||
31 | }, | ||
32 | ); | ||
33 | } | ||
diff --git a/src/features/serviceLimit/store.js b/src/features/serviceLimit/store.js new file mode 100644 index 000000000..9836c5f51 --- /dev/null +++ b/src/features/serviceLimit/store.js | |||
@@ -0,0 +1,41 @@ | |||
1 | import { computed, observable } from 'mobx'; | ||
2 | import { FeatureStore } from '../utils/FeatureStore'; | ||
3 | import { DEFAULT_SERVICE_LIMIT } from '.'; | ||
4 | |||
5 | const debug = require('debug')('Franz:feature:serviceLimit:store'); | ||
6 | |||
7 | export class ServiceLimitStore extends FeatureStore { | ||
8 | @observable isServiceLimitEnabled = false; | ||
9 | |||
10 | start(stores, actions) { | ||
11 | debug('start'); | ||
12 | this.stores = stores; | ||
13 | this.actions = actions; | ||
14 | |||
15 | this.isServiceLimitEnabled = true; | ||
16 | } | ||
17 | |||
18 | stop() { | ||
19 | super.stop(); | ||
20 | |||
21 | this.isServiceLimitEnabled = false; | ||
22 | } | ||
23 | |||
24 | @computed get userHasReachedServiceLimit() { | ||
25 | if (!this.isServiceLimitEnabled) return false; | ||
26 | |||
27 | return this.serviceLimit !== 0 && this.serviceCount >= this.serviceLimit; | ||
28 | } | ||
29 | |||
30 | @computed get serviceLimit() { | ||
31 | if (!this.isServiceLimitEnabled || this.stores.features.features.serviceLimitCount === 0) return 0; | ||
32 | |||
33 | return this.stores.features.features.serviceLimitCount || DEFAULT_SERVICE_LIMIT; | ||
34 | } | ||
35 | |||
36 | @computed get serviceCount() { | ||
37 | return this.stores.services.all.length; | ||
38 | } | ||
39 | } | ||
40 | |||
41 | export default ServiceLimitStore; | ||
diff --git a/src/features/serviceProxy/index.js b/src/features/serviceProxy/index.js index 4bea327ad..55c600de4 100644 --- a/src/features/serviceProxy/index.js +++ b/src/features/serviceProxy/index.js | |||
@@ -9,17 +9,17 @@ const debug = require('debug')('Franz:feature:serviceProxy'); | |||
9 | 9 | ||
10 | export const config = observable({ | 10 | export const config = observable({ |
11 | isEnabled: DEFAULT_FEATURES_CONFIG.isServiceProxyEnabled, | 11 | isEnabled: DEFAULT_FEATURES_CONFIG.isServiceProxyEnabled, |
12 | isPremium: DEFAULT_FEATURES_CONFIG.isServiceProxyPremiumFeature, | 12 | isPremium: DEFAULT_FEATURES_CONFIG.isServiceProxyIncludedInCurrentPlan, |
13 | }); | 13 | }); |
14 | 14 | ||
15 | export default function init(stores) { | 15 | export default function init(stores) { |
16 | debug('Initializing `serviceProxy` feature'); | 16 | debug('Initializing `serviceProxy` feature'); |
17 | 17 | ||
18 | autorun(() => { | 18 | autorun(() => { |
19 | const { isServiceProxyEnabled, isServiceProxyPremiumFeature } = stores.features.features; | 19 | const { isServiceProxyEnabled, isServiceProxyIncludedInCurrentPlan } = stores.features.features; |
20 | 20 | ||
21 | config.isEnabled = isServiceProxyEnabled !== undefined ? isServiceProxyEnabled : DEFAULT_FEATURES_CONFIG.isServiceProxyEnabled; | 21 | config.isEnabled = isServiceProxyEnabled !== undefined ? isServiceProxyEnabled : DEFAULT_FEATURES_CONFIG.isServiceProxyEnabled; |
22 | config.isPremium = isServiceProxyPremiumFeature !== undefined ? isServiceProxyPremiumFeature : DEFAULT_FEATURES_CONFIG.isServiceProxyPremiumFeature; | 22 | config.isIncludedInCurrentPlan = isServiceProxyIncludedInCurrentPlan !== undefined ? isServiceProxyIncludedInCurrentPlan : DEFAULT_FEATURES_CONFIG.isServiceProxyIncludedInCurrentPlan; |
23 | 23 | ||
24 | const services = stores.services.enabled; | 24 | const services = stores.services.enabled; |
25 | const isPremiumUser = stores.user.data.isPremium; | 25 | const isPremiumUser = stores.user.data.isPremium; |
@@ -30,7 +30,7 @@ export default function init(stores) { | |||
30 | services.forEach((service) => { | 30 | services.forEach((service) => { |
31 | const s = session.fromPartition(`persist:service-${service.id}`); | 31 | const s = session.fromPartition(`persist:service-${service.id}`); |
32 | 32 | ||
33 | if (config.isEnabled && (isPremiumUser || !config.isPremium)) { | 33 | if (config.isEnabled && (isPremiumUser || !config.isIncludedInCurrentPlan)) { |
34 | const serviceProxyConfig = proxySettings[service.id]; | 34 | const serviceProxyConfig = proxySettings[service.id]; |
35 | 35 | ||
36 | if (serviceProxyConfig && serviceProxyConfig.isEnabled && serviceProxyConfig.host) { | 36 | if (serviceProxyConfig && serviceProxyConfig.isEnabled && serviceProxyConfig.host) { |
diff --git a/src/features/shareFranz/Component.js b/src/features/shareFranz/Component.js index 8d1d595c5..859c0ebe9 100644 --- a/src/features/shareFranz/Component.js +++ b/src/features/shareFranz/Component.js | |||
@@ -6,6 +6,7 @@ import { defineMessages, intlShape } from 'react-intl'; | |||
6 | import { Button } from '@meetfranz/forms'; | 6 | import { Button } from '@meetfranz/forms'; |
7 | import { H1, Icon } from '@meetfranz/ui'; | 7 | import { H1, Icon } from '@meetfranz/ui'; |
8 | 8 | ||
9 | import { mdiHeart } from '@mdi/js'; | ||
9 | import Modal from '../../components/ui/Modal'; | 10 | import Modal from '../../components/ui/Modal'; |
10 | import { state } from '.'; | 11 | import { state } from '.'; |
11 | import { gaEvent } from '../../lib/analytics'; | 12 | import { gaEvent } from '../../lib/analytics'; |
@@ -116,7 +117,7 @@ export default @injectSheet(styles) @inject('stores') @observer class ShareFranz | |||
116 | close={this.close.bind(this)} | 117 | close={this.close.bind(this)} |
117 | > | 118 | > |
118 | <div className={classes.heartContainer}> | 119 | <div className={classes.heartContainer}> |
119 | <Icon icon="mdiHeart" className={classes.heart} size={4} /> | 120 | <Icon icon={mdiHeart} className={classes.heart} size={4} /> |
120 | </div> | 121 | </div> |
121 | <H1 className={classes.headline}> | 122 | <H1 className={classes.headline}> |
122 | {intl.formatMessage(messages.headline)} | 123 | {intl.formatMessage(messages.headline)} |
diff --git a/src/features/spellchecker/index.js b/src/features/spellchecker/index.js index 79a2172b4..a07f9f63a 100644 --- a/src/features/spellchecker/index.js +++ b/src/features/spellchecker/index.js | |||
@@ -5,18 +5,18 @@ import { DEFAULT_FEATURES_CONFIG } from '../../config'; | |||
5 | const debug = require('debug')('Franz:feature:spellchecker'); | 5 | const debug = require('debug')('Franz:feature:spellchecker'); |
6 | 6 | ||
7 | export const config = observable({ | 7 | export const config = observable({ |
8 | isPremium: DEFAULT_FEATURES_CONFIG.isSpellcheckerPremiumFeature, | 8 | isIncludedInCurrentPlan: DEFAULT_FEATURES_CONFIG.isSpellcheckerIncludedInCurrentPlan, |
9 | }); | 9 | }); |
10 | 10 | ||
11 | export default function init(stores) { | 11 | export default function init(stores) { |
12 | debug('Initializing `spellchecker` feature'); | 12 | debug('Initializing `spellchecker` feature'); |
13 | 13 | ||
14 | autorun(() => { | 14 | autorun(() => { |
15 | const { isSpellcheckerPremiumFeature } = stores.features.features; | 15 | const { isSpellcheckerIncludedInCurrentPlan } = stores.features.features; |
16 | 16 | ||
17 | config.isPremium = isSpellcheckerPremiumFeature !== undefined ? isSpellcheckerPremiumFeature : DEFAULT_FEATURES_CONFIG.isSpellcheckerPremiumFeature; | 17 | config.isIncludedInCurrentPlan = isSpellcheckerIncludedInCurrentPlan !== undefined ? isSpellcheckerIncludedInCurrentPlan : DEFAULT_FEATURES_CONFIG.isSpellcheckerIncludedInCurrentPlan; |
18 | 18 | ||
19 | if (!stores.user.data.isPremium && config.isPremium && stores.settings.app.enableSpellchecking) { | 19 | if (!stores.user.data.isPremium && config.isIncludedInCurrentPlan && stores.settings.app.enableSpellchecking) { |
20 | debug('Override settings.spellcheckerEnabled flag to false'); | 20 | debug('Override settings.spellcheckerEnabled flag to false'); |
21 | 21 | ||
22 | Object.assign(stores.settings.app, { | 22 | Object.assign(stores.settings.app, { |
diff --git a/src/features/todos/actions.js b/src/features/todos/actions.js new file mode 100644 index 000000000..dc63d5fcd --- /dev/null +++ b/src/features/todos/actions.js | |||
@@ -0,0 +1,22 @@ | |||
1 | import PropTypes from 'prop-types'; | ||
2 | import { createActionsFromDefinitions } from '../../actions/lib/actions'; | ||
3 | |||
4 | export const todoActions = createActionsFromDefinitions({ | ||
5 | resize: { | ||
6 | width: PropTypes.number.isRequired, | ||
7 | }, | ||
8 | toggleTodosPanel: {}, | ||
9 | setTodosWebview: { | ||
10 | webview: PropTypes.instanceOf(Element).isRequired, | ||
11 | }, | ||
12 | handleHostMessage: { | ||
13 | action: PropTypes.string.isRequired, | ||
14 | data: PropTypes.object, | ||
15 | }, | ||
16 | handleClientMessage: { | ||
17 | action: PropTypes.string.isRequired, | ||
18 | data: PropTypes.object, | ||
19 | }, | ||
20 | }, PropTypes.checkPropTypes); | ||
21 | |||
22 | export default todoActions; | ||
diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js new file mode 100644 index 000000000..288c1906f --- /dev/null +++ b/src/features/todos/components/TodosWebview.js | |||
@@ -0,0 +1,237 @@ | |||
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 Webview from 'react-electron-web-view'; | ||
6 | import { Icon } from '@meetfranz/ui'; | ||
7 | |||
8 | import * as environment from '../../../environment'; | ||
9 | |||
10 | const OPEN_TODOS_BUTTON_SIZE = 45; | ||
11 | const CLOSE_TODOS_BUTTON_SIZE = 35; | ||
12 | |||
13 | const styles = theme => ({ | ||
14 | root: { | ||
15 | background: theme.colorBackground, | ||
16 | position: 'relative', | ||
17 | borderLeft: [1, 'solid', theme.todos.todosLayer.borderLeftColor], | ||
18 | zIndex: 300, | ||
19 | |||
20 | transform: ({ isVisible, width }) => `translateX(${isVisible ? 0 : width}px)`, | ||
21 | |||
22 | '&:hover $closeTodosButton': { | ||
23 | opacity: 1, | ||
24 | }, | ||
25 | }, | ||
26 | webview: { | ||
27 | height: '100%', | ||
28 | |||
29 | '& webview': { | ||
30 | height: '100%', | ||
31 | }, | ||
32 | }, | ||
33 | resizeHandler: { | ||
34 | position: 'absolute', | ||
35 | left: 0, | ||
36 | marginLeft: -5, | ||
37 | width: 10, | ||
38 | zIndex: 400, | ||
39 | cursor: 'col-resize', | ||
40 | }, | ||
41 | dragIndicator: { | ||
42 | position: 'absolute', | ||
43 | left: 0, | ||
44 | width: 5, | ||
45 | zIndex: 400, | ||
46 | background: theme.todos.dragIndicator.background, | ||
47 | |||
48 | }, | ||
49 | openTodosButton: { | ||
50 | width: OPEN_TODOS_BUTTON_SIZE, | ||
51 | height: OPEN_TODOS_BUTTON_SIZE, | ||
52 | background: theme.todos.toggleButton.background, | ||
53 | position: 'absolute', | ||
54 | bottom: 80, | ||
55 | right: props => (props.width + (props.isVisible ? -OPEN_TODOS_BUTTON_SIZE / 2 : 0)), | ||
56 | borderRadius: OPEN_TODOS_BUTTON_SIZE / 2, | ||
57 | opacity: props => (props.isVisible ? 0 : 1), | ||
58 | transition: 'right 0.5s', | ||
59 | zIndex: 600, | ||
60 | display: 'flex', | ||
61 | alignItems: 'center', | ||
62 | justifyContent: 'center', | ||
63 | boxShadow: [0, 0, 10, theme.todos.toggleButton.shadowColor], | ||
64 | |||
65 | borderTopRightRadius: props => (props.isVisible ? null : 0), | ||
66 | borderBottomRightRadius: props => (props.isVisible ? null : 0), | ||
67 | |||
68 | '& svg': { | ||
69 | fill: theme.todos.toggleButton.textColor, | ||
70 | transition: 'all 0.5s', | ||
71 | }, | ||
72 | }, | ||
73 | closeTodosButton: { | ||
74 | width: CLOSE_TODOS_BUTTON_SIZE, | ||
75 | height: CLOSE_TODOS_BUTTON_SIZE, | ||
76 | background: theme.todos.toggleButton.background, | ||
77 | position: 'absolute', | ||
78 | bottom: 80, | ||
79 | right: ({ width }) => (width + -CLOSE_TODOS_BUTTON_SIZE / 2), | ||
80 | borderRadius: CLOSE_TODOS_BUTTON_SIZE / 2, | ||
81 | opacity: 0, | ||
82 | transition: 'opacity 0.5s', | ||
83 | zIndex: 600, | ||
84 | display: 'flex', | ||
85 | alignItems: 'center', | ||
86 | justifyContent: 'center', | ||
87 | boxShadow: [0, 0, 10, theme.todos.toggleButton.shadowColor], | ||
88 | |||
89 | '& svg': { | ||
90 | fill: theme.todos.toggleButton.textColor, | ||
91 | }, | ||
92 | }, | ||
93 | }); | ||
94 | |||
95 | @injectSheet(styles) @observer | ||
96 | class TodosWebview extends Component { | ||
97 | static propTypes = { | ||
98 | classes: PropTypes.object.isRequired, | ||
99 | isVisible: PropTypes.bool.isRequired, | ||
100 | togglePanel: PropTypes.func.isRequired, | ||
101 | handleClientMessage: PropTypes.func.isRequired, | ||
102 | setTodosWebview: PropTypes.func.isRequired, | ||
103 | resize: PropTypes.func.isRequired, | ||
104 | width: PropTypes.number.isRequired, | ||
105 | minWidth: PropTypes.number.isRequired, | ||
106 | }; | ||
107 | |||
108 | state = { | ||
109 | isDragging: false, | ||
110 | width: 300, | ||
111 | }; | ||
112 | |||
113 | componentWillMount() { | ||
114 | const { width } = this.props; | ||
115 | |||
116 | this.setState({ | ||
117 | width, | ||
118 | }); | ||
119 | } | ||
120 | |||
121 | componentDidMount() { | ||
122 | this.node.addEventListener('mousemove', this.resizePanel.bind(this)); | ||
123 | this.node.addEventListener('mouseup', this.stopResize.bind(this)); | ||
124 | this.node.addEventListener('mouseleave', this.stopResize.bind(this)); | ||
125 | } | ||
126 | |||
127 | startResize = (event) => { | ||
128 | this.setState({ | ||
129 | isDragging: true, | ||
130 | initialPos: event.clientX, | ||
131 | delta: 0, | ||
132 | }); | ||
133 | }; | ||
134 | |||
135 | resizePanel(e) { | ||
136 | const { minWidth } = this.props; | ||
137 | |||
138 | const { | ||
139 | isDragging, | ||
140 | initialPos, | ||
141 | } = this.state; | ||
142 | |||
143 | if (isDragging && Math.abs(e.clientX - window.innerWidth) > minWidth) { | ||
144 | const delta = e.clientX - initialPos; | ||
145 | |||
146 | this.setState({ | ||
147 | delta, | ||
148 | }); | ||
149 | } | ||
150 | } | ||
151 | |||
152 | stopResize() { | ||
153 | const { | ||
154 | resize, | ||
155 | minWidth, | ||
156 | } = this.props; | ||
157 | |||
158 | const { | ||
159 | isDragging, | ||
160 | delta, | ||
161 | width, | ||
162 | } = this.state; | ||
163 | |||
164 | if (isDragging) { | ||
165 | let newWidth = width + (delta < 0 ? Math.abs(delta) : -Math.abs(delta)); | ||
166 | |||
167 | if (newWidth < minWidth) { | ||
168 | newWidth = minWidth; | ||
169 | } | ||
170 | |||
171 | this.setState({ | ||
172 | isDragging: false, | ||
173 | delta: 0, | ||
174 | width: newWidth, | ||
175 | }); | ||
176 | |||
177 | resize(newWidth); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | startListeningToIpcMessages() { | ||
182 | const { handleClientMessage } = this.props; | ||
183 | if (!this.webview) return; | ||
184 | this.webview.addEventListener('ipc-message', e => handleClientMessage(e.args[0])); | ||
185 | } | ||
186 | |||
187 | render() { | ||
188 | const { | ||
189 | classes, isVisible, togglePanel, | ||
190 | } = this.props; | ||
191 | const { width, delta, isDragging } = this.state; | ||
192 | |||
193 | return ( | ||
194 | <> | ||
195 | <div | ||
196 | className={classes.root} | ||
197 | style={{ width: isVisible ? width : 0 }} | ||
198 | onMouseUp={() => this.stopResize()} | ||
199 | ref={(node) => { this.node = node; }} | ||
200 | > | ||
201 | <button | ||
202 | onClick={() => togglePanel()} | ||
203 | className={isVisible ? classes.closeTodosButton : classes.openTodosButton} | ||
204 | type="button" | ||
205 | > | ||
206 | <Icon icon={isVisible ? 'mdiChevronRight' : 'mdiCheckAll'} size={2} /> | ||
207 | </button> | ||
208 | <div | ||
209 | className={classes.resizeHandler} | ||
210 | style={Object.assign({ left: delta }, isDragging ? { width: 600, marginLeft: -200 } : {})} // This hack is required as resizing with webviews beneath behaves quite bad | ||
211 | onMouseDown={e => this.startResize(e)} | ||
212 | /> | ||
213 | {isDragging && ( | ||
214 | <div | ||
215 | className={classes.dragIndicator} | ||
216 | style={{ left: delta }} // This hack is required as resizing with webviews beneath behaves quite bad | ||
217 | /> | ||
218 | )} | ||
219 | <Webview | ||
220 | className={classes.webview} | ||
221 | onDidAttach={() => { | ||
222 | const { setTodosWebview } = this.props; | ||
223 | setTodosWebview(this.webview); | ||
224 | this.startListeningToIpcMessages(); | ||
225 | }} | ||
226 | partition="persist:todos" | ||
227 | preload="./features/todos/preload.js" | ||
228 | ref={(webview) => { this.webview = webview ? webview.view : null; }} | ||
229 | src={environment.TODOS_FRONTEND} | ||
230 | /> | ||
231 | </div> | ||
232 | </> | ||
233 | ); | ||
234 | } | ||
235 | } | ||
236 | |||
237 | export default TodosWebview; | ||
diff --git a/src/features/todos/constants.js b/src/features/todos/constants.js new file mode 100644 index 000000000..2e8a431cc --- /dev/null +++ b/src/features/todos/constants.js | |||
@@ -0,0 +1,4 @@ | |||
1 | export const IPC = { | ||
2 | TODOS_HOST_CHANNEL: 'TODOS_HOST_CHANNEL', | ||
3 | TODOS_CLIENT_CHANNEL: 'TODOS_CLIENT_CHANNEL', | ||
4 | }; | ||
diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js new file mode 100644 index 000000000..d071d0677 --- /dev/null +++ b/src/features/todos/containers/TodosScreen.js | |||
@@ -0,0 +1,32 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import { observer } from 'mobx-react'; | ||
3 | |||
4 | import TodosWebview from '../components/TodosWebview'; | ||
5 | import ErrorBoundary from '../../../components/util/ErrorBoundary'; | ||
6 | import { TODOS_MIN_WIDTH, todosStore } from '..'; | ||
7 | import { todoActions } from '../actions'; | ||
8 | |||
9 | @observer | ||
10 | class TodosScreen extends Component { | ||
11 | render() { | ||
12 | if (!todosStore || !todosStore.isFeatureActive) { | ||
13 | return null; | ||
14 | } | ||
15 | |||
16 | return ( | ||
17 | <ErrorBoundary> | ||
18 | <TodosWebview | ||
19 | isVisible={todosStore.isTodosPanelVisible} | ||
20 | togglePanel={todoActions.toggleTodosPanel} | ||
21 | handleClientMessage={todoActions.handleClientMessage} | ||
22 | setTodosWebview={webview => todoActions.setTodosWebview({ webview })} | ||
23 | width={todosStore.width} | ||
24 | minWidth={TODOS_MIN_WIDTH} | ||
25 | resize={width => todoActions.resize({ width })} | ||
26 | /> | ||
27 | </ErrorBoundary> | ||
28 | ); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | export default TodosScreen; | ||
diff --git a/src/features/todos/index.js b/src/features/todos/index.js new file mode 100644 index 000000000..00b165cc5 --- /dev/null +++ b/src/features/todos/index.js | |||
@@ -0,0 +1,34 @@ | |||
1 | import { reaction } from 'mobx'; | ||
2 | import TodoStore from './store'; | ||
3 | |||
4 | const debug = require('debug')('Franz:feature:todos'); | ||
5 | |||
6 | export const GA_CATEGORY_TODOS = 'Todos'; | ||
7 | |||
8 | export const DEFAULT_TODOS_WIDTH = 300; | ||
9 | export const TODOS_MIN_WIDTH = 200; | ||
10 | export const DEFAULT_TODOS_VISIBLE = true; | ||
11 | |||
12 | export const todosStore = new TodoStore(); | ||
13 | |||
14 | export default function initTodos(stores, actions) { | ||
15 | stores.todos = todosStore; | ||
16 | const { features } = stores; | ||
17 | |||
18 | // Toggle todos feature | ||
19 | reaction( | ||
20 | () => features.features.isTodosEnabled, | ||
21 | (isEnabled) => { | ||
22 | if (isEnabled) { | ||
23 | debug('Initializing `todos` feature'); | ||
24 | todosStore.start(stores, actions); | ||
25 | } else if (todosStore.isFeatureActive) { | ||
26 | debug('Disabling `todos` feature'); | ||
27 | todosStore.stop(); | ||
28 | } | ||
29 | }, | ||
30 | { | ||
31 | fireImmediately: true, | ||
32 | }, | ||
33 | ); | ||
34 | } | ||
diff --git a/src/features/todos/preload.js b/src/features/todos/preload.js new file mode 100644 index 000000000..6e38a2ef3 --- /dev/null +++ b/src/features/todos/preload.js | |||
@@ -0,0 +1,23 @@ | |||
1 | import { ipcRenderer } from 'electron'; | ||
2 | import { IPC } from './constants'; | ||
3 | |||
4 | const debug = require('debug')('Franz:feature:todos:preload'); | ||
5 | |||
6 | debug('Preloading Todos Webview'); | ||
7 | |||
8 | let hostMessageListener = () => {}; | ||
9 | |||
10 | window.franz = { | ||
11 | onInitialize(ipcHostMessageListener) { | ||
12 | hostMessageListener = ipcHostMessageListener; | ||
13 | ipcRenderer.sendToHost(IPC.TODOS_CLIENT_CHANNEL, { action: 'todos:initialized' }); | ||
14 | }, | ||
15 | sendToHost(message) { | ||
16 | ipcRenderer.sendToHost(IPC.TODOS_CLIENT_CHANNEL, message); | ||
17 | }, | ||
18 | }; | ||
19 | |||
20 | ipcRenderer.on(IPC.TODOS_HOST_CHANNEL, (event, message) => { | ||
21 | debug('Received host message', event, message); | ||
22 | hostMessageListener(message); | ||
23 | }); | ||
diff --git a/src/features/todos/store.js b/src/features/todos/store.js new file mode 100644 index 000000000..acf95df0d --- /dev/null +++ b/src/features/todos/store.js | |||
@@ -0,0 +1,147 @@ | |||
1 | import { ThemeType } from '@meetfranz/theme'; | ||
2 | import { | ||
3 | computed, | ||
4 | action, | ||
5 | observable, | ||
6 | } from 'mobx'; | ||
7 | import localStorage from 'mobx-localstorage'; | ||
8 | |||
9 | import { todoActions } from './actions'; | ||
10 | import { FeatureStore } from '../utils/FeatureStore'; | ||
11 | import { createReactions } from '../../stores/lib/Reaction'; | ||
12 | import { createActionBindings } from '../utils/ActionBinding'; | ||
13 | import { DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH, DEFAULT_TODOS_VISIBLE } from '.'; | ||
14 | import { IPC } from './constants'; | ||
15 | |||
16 | const debug = require('debug')('Franz:feature:todos:store'); | ||
17 | |||
18 | export default class TodoStore extends FeatureStore { | ||
19 | @observable isFeatureEnabled = false; | ||
20 | |||
21 | @observable isFeatureActive = false; | ||
22 | |||
23 | webview = null; | ||
24 | |||
25 | @computed get width() { | ||
26 | const width = this.settings.width || DEFAULT_TODOS_WIDTH; | ||
27 | |||
28 | return width < TODOS_MIN_WIDTH ? TODOS_MIN_WIDTH : width; | ||
29 | } | ||
30 | |||
31 | @computed get isTodosPanelVisible() { | ||
32 | if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; | ||
33 | |||
34 | return this.settings.isTodosPanelVisible; | ||
35 | } | ||
36 | |||
37 | @computed get settings() { | ||
38 | return localStorage.getItem('todos') || {}; | ||
39 | } | ||
40 | |||
41 | // ========== PUBLIC API ========= // | ||
42 | |||
43 | @action start(stores, actions) { | ||
44 | debug('TodoStore::start'); | ||
45 | this.stores = stores; | ||
46 | this.actions = actions; | ||
47 | |||
48 | // ACTIONS | ||
49 | |||
50 | this._registerActions(createActionBindings([ | ||
51 | [todoActions.resize, this._resize], | ||
52 | [todoActions.toggleTodosPanel, this._toggleTodosPanel], | ||
53 | [todoActions.setTodosWebview, this._setTodosWebview], | ||
54 | [todoActions.handleHostMessage, this._handleHostMessage], | ||
55 | [todoActions.handleClientMessage, this._handleClientMessage], | ||
56 | ])); | ||
57 | |||
58 | // REACTIONS | ||
59 | |||
60 | this._allReactions = createReactions([ | ||
61 | this._setFeatureEnabledReaction, | ||
62 | ]); | ||
63 | |||
64 | this._registerReactions(this._allReactions); | ||
65 | |||
66 | this.isFeatureActive = true; | ||
67 | } | ||
68 | |||
69 | @action stop() { | ||
70 | super.stop(); | ||
71 | debug('TodoStore::stop'); | ||
72 | this.reset(); | ||
73 | this.isFeatureActive = false; | ||
74 | } | ||
75 | |||
76 | // ========== PRIVATE METHODS ========= // | ||
77 | |||
78 | _updateSettings = (changes) => { | ||
79 | localStorage.setItem('todos', { | ||
80 | ...this.settings, | ||
81 | ...changes, | ||
82 | }); | ||
83 | }; | ||
84 | |||
85 | // Actions | ||
86 | |||
87 | @action _resize = ({ width }) => { | ||
88 | this._updateSettings({ | ||
89 | width, | ||
90 | }); | ||
91 | }; | ||
92 | |||
93 | @action _toggleTodosPanel = () => { | ||
94 | this._updateSettings({ | ||
95 | isTodosPanelVisible: !this.isTodosPanelVisible, | ||
96 | }); | ||
97 | }; | ||
98 | |||
99 | @action _setTodosWebview = ({ webview }) => { | ||
100 | debug('_setTodosWebview', webview); | ||
101 | this.webview = webview; | ||
102 | }; | ||
103 | |||
104 | @action _handleHostMessage = (message) => { | ||
105 | debug('_handleHostMessage', message); | ||
106 | if (message.action === 'todos:create') { | ||
107 | this.webview.send(IPC.TODOS_HOST_CHANNEL, message); | ||
108 | } | ||
109 | }; | ||
110 | |||
111 | @action _handleClientMessage = (message) => { | ||
112 | debug('_handleClientMessage', message); | ||
113 | switch (message.action) { | ||
114 | case 'todos:initialized': this._onTodosClientInitialized(); break; | ||
115 | case 'todos:goToService': this._goToService(message.data); break; | ||
116 | default: | ||
117 | debug('Unknown client message reiceived', message); | ||
118 | } | ||
119 | }; | ||
120 | |||
121 | // Todos client message handlers | ||
122 | |||
123 | _onTodosClientInitialized = () => { | ||
124 | this.webview.send(IPC.TODOS_HOST_CHANNEL, { | ||
125 | action: 'todos:configure', | ||
126 | data: { | ||
127 | authToken: this.stores.user.authToken, | ||
128 | theme: this.stores.ui.isDarkThemeActive ? ThemeType.dark : ThemeType.default, | ||
129 | }, | ||
130 | }); | ||
131 | }; | ||
132 | |||
133 | _goToService = ({ url, serviceId }) => { | ||
134 | if (url) { | ||
135 | this.stores.services.one(serviceId).webview.loadURL(url); | ||
136 | } | ||
137 | this.actions.service.setActive({ serviceId }); | ||
138 | }; | ||
139 | |||
140 | // Reactions | ||
141 | |||
142 | _setFeatureEnabledReaction = () => { | ||
143 | const { isTodosEnabled } = this.stores.features.features; | ||
144 | |||
145 | this.isFeatureEnabled = isTodosEnabled; | ||
146 | }; | ||
147 | } | ||
diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js index 07b16ff23..e44569be9 100644 --- a/src/features/workspaces/store.js +++ b/src/features/workspaces/store.js | |||
@@ -79,7 +79,7 @@ export default class WorkspacesStore extends FeatureStore { | |||
79 | 79 | ||
80 | // ========== PUBLIC API ========= // | 80 | // ========== PUBLIC API ========= // |
81 | 81 | ||
82 | start(stores, actions) { | 82 | @action start(stores, actions) { |
83 | debug('WorkspacesStore::start'); | 83 | debug('WorkspacesStore::start'); |
84 | this.stores = stores; | 84 | this.stores = stores; |
85 | this.actions = actions; | 85 | this.actions = actions; |
@@ -104,7 +104,7 @@ export default class WorkspacesStore extends FeatureStore { | |||
104 | // REACTIONS | 104 | // REACTIONS |
105 | 105 | ||
106 | this._freeUserReactions = createReactions([ | 106 | this._freeUserReactions = createReactions([ |
107 | this._stopPremiumActionsAndReactions, | 107 | this._disablePremiumFeatures, |
108 | this._openDrawerWithSettingsReaction, | 108 | this._openDrawerWithSettingsReaction, |
109 | this._setFeatureEnabledReaction, | 109 | this._setFeatureEnabledReaction, |
110 | this._setIsPremiumFeatureReaction, | 110 | this._setIsPremiumFeatureReaction, |
@@ -123,10 +123,7 @@ export default class WorkspacesStore extends FeatureStore { | |||
123 | this.isFeatureActive = true; | 123 | this.isFeatureActive = true; |
124 | } | 124 | } |
125 | 125 | ||
126 | stop() { | 126 | @action reset() { |
127 | super.stop(); | ||
128 | debug('WorkspacesStore::stop'); | ||
129 | this.isFeatureActive = false; | ||
130 | this.activeWorkspace = null; | 127 | this.activeWorkspace = null; |
131 | this.nextWorkspace = null; | 128 | this.nextWorkspace = null; |
132 | this.workspaceBeingEdited = null; | 129 | this.workspaceBeingEdited = null; |
@@ -134,6 +131,13 @@ export default class WorkspacesStore extends FeatureStore { | |||
134 | this.isWorkspaceDrawerOpen = false; | 131 | this.isWorkspaceDrawerOpen = false; |
135 | } | 132 | } |
136 | 133 | ||
134 | @action stop() { | ||
135 | super.stop(); | ||
136 | debug('WorkspacesStore::stop'); | ||
137 | this.reset(); | ||
138 | this.isFeatureActive = false; | ||
139 | } | ||
140 | |||
137 | filterServicesByActiveWorkspace = (services) => { | 141 | filterServicesByActiveWorkspace = (services) => { |
138 | const { activeWorkspace, isFeatureActive } = this; | 142 | const { activeWorkspace, isFeatureActive } = this; |
139 | if (isFeatureActive && activeWorkspace) { | 143 | if (isFeatureActive && activeWorkspace) { |
@@ -251,9 +255,9 @@ export default class WorkspacesStore extends FeatureStore { | |||
251 | _setIsPremiumFeatureReaction = () => { | 255 | _setIsPremiumFeatureReaction = () => { |
252 | const { features, user } = this.stores; | 256 | const { features, user } = this.stores; |
253 | const { isPremium } = user.data; | 257 | const { isPremium } = user.data; |
254 | const { isWorkspacePremiumFeature } = features.features; | 258 | const { isWorkspaceIncludedInCurrentPlan } = features.features; |
255 | this.isPremiumFeature = isWorkspacePremiumFeature; | 259 | this.isPremiumFeature = !isWorkspaceIncludedInCurrentPlan; |
256 | this.isPremiumUpgradeRequired = isWorkspacePremiumFeature && !isPremium; | 260 | this.isPremiumUpgradeRequired = !isWorkspaceIncludedInCurrentPlan && !isPremium; |
257 | }; | 261 | }; |
258 | 262 | ||
259 | _setWorkspaceBeingEditedReaction = () => { | 263 | _setWorkspaceBeingEditedReaction = () => { |
@@ -281,6 +285,7 @@ export default class WorkspacesStore extends FeatureStore { | |||
281 | }; | 285 | }; |
282 | 286 | ||
283 | _activateLastUsedWorkspaceReaction = () => { | 287 | _activateLastUsedWorkspaceReaction = () => { |
288 | debug('_activateLastUsedWorkspaceReaction'); | ||
284 | if (!this.activeWorkspace && this.userHasWorkspaces) { | 289 | if (!this.activeWorkspace && this.userHasWorkspaces) { |
285 | const { lastActiveWorkspace } = this.settings; | 290 | const { lastActiveWorkspace } = this.settings; |
286 | if (lastActiveWorkspace) { | 291 | if (lastActiveWorkspace) { |
@@ -324,10 +329,12 @@ export default class WorkspacesStore extends FeatureStore { | |||
324 | }); | 329 | }); |
325 | }; | 330 | }; |
326 | 331 | ||
327 | _stopPremiumActionsAndReactions = () => { | 332 | _disablePremiumFeatures = () => { |
328 | if (!this.isUserAllowedToUseFeature) { | 333 | if (!this.isUserAllowedToUseFeature) { |
334 | debug('_disablePremiumFeatures'); | ||
329 | this._stopActions(this._premiumUserActions); | 335 | this._stopActions(this._premiumUserActions); |
330 | this._stopReactions(this._premiumUserReactions); | 336 | this._stopReactions(this._premiumUserReactions); |
337 | this.reset(); | ||
331 | } else { | 338 | } else { |
332 | this._startActions(this._premiumUserActions); | 339 | this._startActions(this._premiumUserActions); |
333 | this._startReactions(this._premiumUserReactions); | 340 | this._startReactions(this._premiumUserReactions); |
diff --git a/src/helpers/plan-helpers.js b/src/helpers/plan-helpers.js new file mode 100644 index 000000000..19392585e --- /dev/null +++ b/src/helpers/plan-helpers.js | |||
@@ -0,0 +1,35 @@ | |||
1 | import { defineMessages } from 'react-intl'; | ||
2 | import { PLANS_MAPPING, PLANS } from '../config'; | ||
3 | |||
4 | const messages = defineMessages({ | ||
5 | [PLANS.PRO]: { | ||
6 | id: 'pricing.plan.pro', | ||
7 | defaultMessage: '!!!Franz Professional', | ||
8 | }, | ||
9 | [PLANS.PERSONAL]: { | ||
10 | id: 'pricing.plan.personal', | ||
11 | defaultMessage: '!!!Franz Personal', | ||
12 | }, | ||
13 | [PLANS.FREE]: { | ||
14 | id: 'pricing.plan.free', | ||
15 | defaultMessage: '!!!Franz Free', | ||
16 | }, | ||
17 | [PLANS.LEGACY]: { | ||
18 | id: 'pricing.plan.legacy', | ||
19 | defaultMessage: '!!!Franz Premium', | ||
20 | }, | ||
21 | }); | ||
22 | |||
23 | export function i18nPlanName(planId, intl) { | ||
24 | if (!planId) { | ||
25 | throw new Error('planId is required'); | ||
26 | } | ||
27 | |||
28 | if (!intl) { | ||
29 | throw new Error('intl context is required'); | ||
30 | } | ||
31 | |||
32 | const plan = PLANS_MAPPING[planId]; | ||
33 | |||
34 | return intl.formatMessage(messages[plan]); | ||
35 | } | ||
diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index d517b456b..62d56ad1f 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json | |||
@@ -417,55 +417,120 @@ | |||
417 | { | 417 | { |
418 | "descriptors": [ | 418 | "descriptors": [ |
419 | { | 419 | { |
420 | "defaultMessage": "!!!Support Franz", | 420 | "defaultMessage": "!!!Franz Professional", |
421 | "end": { | 421 | "end": { |
422 | "column": 3, | 422 | "column": 3, |
423 | "line": 16 | 423 | "line": 18 |
424 | }, | 424 | }, |
425 | "file": "src/components/auth/Pricing.js", | 425 | "file": "src/components/auth/Pricing.js", |
426 | "id": "pricing.headline", | 426 | "id": "pricing.trial.headline", |
427 | "start": { | 427 | "start": { |
428 | "column": 12, | 428 | "column": 12, |
429 | "line": 13 | 429 | "line": 15 |
430 | } | 430 | } |
431 | }, | 431 | }, |
432 | { | 432 | { |
433 | "defaultMessage": "!!!Select your support plan", | 433 | "defaultMessage": "!!!Your personal welcome offer:", |
434 | "end": { | 434 | "end": { |
435 | "column": 3, | 435 | "column": 3, |
436 | "line": 20 | 436 | "line": 22 |
437 | }, | 437 | }, |
438 | "file": "src/components/auth/Pricing.js", | 438 | "file": "src/components/auth/Pricing.js", |
439 | "id": "pricing.support.label", | 439 | "id": "pricing.trial.subheadline", |
440 | "start": { | 440 | "start": { |
441 | "column": 23, | 441 | "column": 17, |
442 | "line": 17 | 442 | "line": 19 |
443 | } | 443 | } |
444 | }, | 444 | }, |
445 | { | 445 | { |
446 | "defaultMessage": "!!!Support the development of Franz", | 446 | "defaultMessage": "!!!No strings attached", |
447 | "end": { | 447 | "end": { |
448 | "column": 3, | 448 | "column": 3, |
449 | "line": 24 | 449 | "line": 26 |
450 | }, | ||
451 | "file": "src/components/auth/Pricing.js", | ||
452 | "id": "pricing.trial.terms.headline", | ||
453 | "start": { | ||
454 | "column": 29, | ||
455 | "line": 23 | ||
456 | } | ||
457 | }, | ||
458 | { | ||
459 | "defaultMessage": "!!!No credit card required", | ||
460 | "end": { | ||
461 | "column": 3, | ||
462 | "line": 30 | ||
450 | }, | 463 | }, |
451 | "file": "src/components/auth/Pricing.js", | 464 | "file": "src/components/auth/Pricing.js", |
452 | "id": "pricing.submit.label", | 465 | "id": "pricing.trial.terms.noCreditCard", |
466 | "start": { | ||
467 | "column": 16, | ||
468 | "line": 27 | ||
469 | } | ||
470 | }, | ||
471 | { | ||
472 | "defaultMessage": "!!!Your free trial ends automatically after 14 days", | ||
473 | "end": { | ||
474 | "column": 3, | ||
475 | "line": 34 | ||
476 | }, | ||
477 | "file": "src/components/auth/Pricing.js", | ||
478 | "id": "pricing.trial.terms.automaticTrialEnd", | ||
453 | "start": { | 479 | "start": { |
454 | "column": 21, | 480 | "column": 21, |
455 | "line": 21 | 481 | "line": 31 |
456 | } | 482 | } |
457 | }, | 483 | }, |
458 | { | 484 | { |
459 | "defaultMessage": "!!!I don't want to support the development of Franz.", | 485 | "defaultMessage": "!!!Sorry, we could not activate your trial!", |
460 | "end": { | 486 | "end": { |
461 | "column": 3, | 487 | "column": 3, |
462 | "line": 28 | 488 | "line": 38 |
463 | }, | 489 | }, |
464 | "file": "src/components/auth/Pricing.js", | 490 | "file": "src/components/auth/Pricing.js", |
465 | "id": "pricing.link.skipPayment", | 491 | "id": "pricing.trial.error", |
466 | "start": { | 492 | "start": { |
467 | "column": 15, | 493 | "column": 19, |
468 | "line": 25 | 494 | "line": 35 |
495 | } | ||
496 | }, | ||
497 | { | ||
498 | "defaultMessage": "!!!Yes, upgrade my account to Franz Professional", | ||
499 | "end": { | ||
500 | "column": 3, | ||
501 | "line": 42 | ||
502 | }, | ||
503 | "file": "src/components/auth/Pricing.js", | ||
504 | "id": "pricing.trial.cta.accept", | ||
505 | "start": { | ||
506 | "column": 13, | ||
507 | "line": 39 | ||
508 | } | ||
509 | }, | ||
510 | { | ||
511 | "defaultMessage": "!!!Continue to Franz", | ||
512 | "end": { | ||
513 | "column": 3, | ||
514 | "line": 46 | ||
515 | }, | ||
516 | "file": "src/components/auth/Pricing.js", | ||
517 | "id": "pricing.trial.cta.skip", | ||
518 | "start": { | ||
519 | "column": 11, | ||
520 | "line": 43 | ||
521 | } | ||
522 | }, | ||
523 | { | ||
524 | "defaultMessage": "!!!Franz Professional includes:", | ||
525 | "end": { | ||
526 | "column": 3, | ||
527 | "line": 50 | ||
528 | }, | ||
529 | "file": "src/components/auth/Pricing.js", | ||
530 | "id": "pricing.trial.features.headline", | ||
531 | "start": { | ||
532 | "column": 20, | ||
533 | "line": 47 | ||
469 | } | 534 | } |
470 | } | 535 | } |
471 | ], | 536 | ], |
@@ -477,156 +542,143 @@ | |||
477 | "defaultMessage": "!!!Sign up", | 542 | "defaultMessage": "!!!Sign up", |
478 | "end": { | 543 | "end": { |
479 | "column": 3, | 544 | "column": 3, |
480 | "line": 21 | 545 | "line": 20 |
481 | }, | 546 | }, |
482 | "file": "src/components/auth/Signup.js", | 547 | "file": "src/components/auth/Signup.js", |
483 | "id": "signup.headline", | 548 | "id": "signup.headline", |
484 | "start": { | 549 | "start": { |
485 | "column": 12, | 550 | "column": 12, |
486 | "line": 18 | 551 | "line": 17 |
487 | } | 552 | } |
488 | }, | 553 | }, |
489 | { | 554 | { |
490 | "defaultMessage": "!!!Firstname", | 555 | "defaultMessage": "!!!Firstname", |
491 | "end": { | 556 | "end": { |
492 | "column": 3, | 557 | "column": 3, |
493 | "line": 25 | 558 | "line": 24 |
494 | }, | 559 | }, |
495 | "file": "src/components/auth/Signup.js", | 560 | "file": "src/components/auth/Signup.js", |
496 | "id": "signup.firstname.label", | 561 | "id": "signup.firstname.label", |
497 | "start": { | 562 | "start": { |
498 | "column": 18, | 563 | "column": 18, |
499 | "line": 22 | 564 | "line": 21 |
500 | } | 565 | } |
501 | }, | 566 | }, |
502 | { | 567 | { |
503 | "defaultMessage": "!!!Lastname", | 568 | "defaultMessage": "!!!Lastname", |
504 | "end": { | 569 | "end": { |
505 | "column": 3, | 570 | "column": 3, |
506 | "line": 29 | 571 | "line": 28 |
507 | }, | 572 | }, |
508 | "file": "src/components/auth/Signup.js", | 573 | "file": "src/components/auth/Signup.js", |
509 | "id": "signup.lastname.label", | 574 | "id": "signup.lastname.label", |
510 | "start": { | 575 | "start": { |
511 | "column": 17, | 576 | "column": 17, |
512 | "line": 26 | 577 | "line": 25 |
513 | } | 578 | } |
514 | }, | 579 | }, |
515 | { | 580 | { |
516 | "defaultMessage": "!!!Email address", | 581 | "defaultMessage": "!!!Email address", |
517 | "end": { | 582 | "end": { |
518 | "column": 3, | 583 | "column": 3, |
519 | "line": 33 | 584 | "line": 32 |
520 | }, | 585 | }, |
521 | "file": "src/components/auth/Signup.js", | 586 | "file": "src/components/auth/Signup.js", |
522 | "id": "signup.email.label", | 587 | "id": "signup.email.label", |
523 | "start": { | 588 | "start": { |
524 | "column": 14, | 589 | "column": 14, |
525 | "line": 30 | 590 | "line": 29 |
526 | } | ||
527 | }, | ||
528 | { | ||
529 | "defaultMessage": "!!!Company", | ||
530 | "end": { | ||
531 | "column": 3, | ||
532 | "line": 37 | ||
533 | }, | ||
534 | "file": "src/components/auth/Signup.js", | ||
535 | "id": "signup.company.label", | ||
536 | "start": { | ||
537 | "column": 16, | ||
538 | "line": 34 | ||
539 | } | 591 | } |
540 | }, | 592 | }, |
541 | { | 593 | { |
542 | "defaultMessage": "!!!Password", | 594 | "defaultMessage": "!!!Password", |
543 | "end": { | 595 | "end": { |
544 | "column": 3, | 596 | "column": 3, |
545 | "line": 41 | 597 | "line": 40 |
546 | }, | 598 | }, |
547 | "file": "src/components/auth/Signup.js", | 599 | "file": "src/components/auth/Signup.js", |
548 | "id": "signup.password.label", | 600 | "id": "signup.password.label", |
549 | "start": { | 601 | "start": { |
550 | "column": 17, | 602 | "column": 17, |
551 | "line": 38 | 603 | "line": 37 |
552 | } | 604 | } |
553 | }, | 605 | }, |
554 | { | 606 | { |
555 | "defaultMessage": "!!!By creating a Franz account you accept the", | 607 | "defaultMessage": "!!!By creating a Franz account you accept the", |
556 | "end": { | 608 | "end": { |
557 | "column": 3, | 609 | "column": 3, |
558 | "line": 45 | 610 | "line": 44 |
559 | }, | 611 | }, |
560 | "file": "src/components/auth/Signup.js", | 612 | "file": "src/components/auth/Signup.js", |
561 | "id": "signup.legal.info", | 613 | "id": "signup.legal.info", |
562 | "start": { | 614 | "start": { |
563 | "column": 13, | 615 | "column": 13, |
564 | "line": 42 | 616 | "line": 41 |
565 | } | 617 | } |
566 | }, | 618 | }, |
567 | { | 619 | { |
568 | "defaultMessage": "!!!Terms of service", | 620 | "defaultMessage": "!!!Terms of service", |
569 | "end": { | 621 | "end": { |
570 | "column": 3, | 622 | "column": 3, |
571 | "line": 49 | 623 | "line": 48 |
572 | }, | 624 | }, |
573 | "file": "src/components/auth/Signup.js", | 625 | "file": "src/components/auth/Signup.js", |
574 | "id": "signup.legal.terms", | 626 | "id": "signup.legal.terms", |
575 | "start": { | 627 | "start": { |
576 | "column": 9, | 628 | "column": 9, |
577 | "line": 46 | 629 | "line": 45 |
578 | } | 630 | } |
579 | }, | 631 | }, |
580 | { | 632 | { |
581 | "defaultMessage": "!!!Privacy Statement", | 633 | "defaultMessage": "!!!Privacy Statement", |
582 | "end": { | 634 | "end": { |
583 | "column": 3, | 635 | "column": 3, |
584 | "line": 53 | 636 | "line": 52 |
585 | }, | 637 | }, |
586 | "file": "src/components/auth/Signup.js", | 638 | "file": "src/components/auth/Signup.js", |
587 | "id": "signup.legal.privacy", | 639 | "id": "signup.legal.privacy", |
588 | "start": { | 640 | "start": { |
589 | "column": 11, | 641 | "column": 11, |
590 | "line": 50 | 642 | "line": 49 |
591 | } | 643 | } |
592 | }, | 644 | }, |
593 | { | 645 | { |
594 | "defaultMessage": "!!!Create account", | 646 | "defaultMessage": "!!!Create account", |
595 | "end": { | 647 | "end": { |
596 | "column": 3, | 648 | "column": 3, |
597 | "line": 57 | 649 | "line": 56 |
598 | }, | 650 | }, |
599 | "file": "src/components/auth/Signup.js", | 651 | "file": "src/components/auth/Signup.js", |
600 | "id": "signup.submit.label", | 652 | "id": "signup.submit.label", |
601 | "start": { | 653 | "start": { |
602 | "column": 21, | 654 | "column": 21, |
603 | "line": 54 | 655 | "line": 53 |
604 | } | 656 | } |
605 | }, | 657 | }, |
606 | { | 658 | { |
607 | "defaultMessage": "!!!Already have an account, sign in?", | 659 | "defaultMessage": "!!!Already have an account, sign in?", |
608 | "end": { | 660 | "end": { |
609 | "column": 3, | 661 | "column": 3, |
610 | "line": 61 | 662 | "line": 60 |
611 | }, | 663 | }, |
612 | "file": "src/components/auth/Signup.js", | 664 | "file": "src/components/auth/Signup.js", |
613 | "id": "signup.link.login", | 665 | "id": "signup.link.login", |
614 | "start": { | 666 | "start": { |
615 | "column": 13, | 667 | "column": 13, |
616 | "line": 58 | 668 | "line": 57 |
617 | } | 669 | } |
618 | }, | 670 | }, |
619 | { | 671 | { |
620 | "defaultMessage": "!!!A user with that email address already exists", | 672 | "defaultMessage": "!!!A user with that email address already exists", |
621 | "end": { | 673 | "end": { |
622 | "column": 3, | 674 | "column": 3, |
623 | "line": 65 | 675 | "line": 64 |
624 | }, | 676 | }, |
625 | "file": "src/components/auth/Signup.js", | 677 | "file": "src/components/auth/Signup.js", |
626 | "id": "signup.emailDuplicate", | 678 | "id": "signup.emailDuplicate", |
627 | "start": { | 679 | "start": { |
628 | "column": 18, | 680 | "column": 18, |
629 | "line": 62 | 681 | "line": 61 |
630 | } | 682 | } |
631 | } | 683 | } |
632 | ], | 684 | ], |
@@ -669,39 +721,39 @@ | |||
669 | "defaultMessage": "!!!Your services have been updated.", | 721 | "defaultMessage": "!!!Your services have been updated.", |
670 | "end": { | 722 | "end": { |
671 | "column": 3, | 723 | "column": 3, |
672 | "line": 29 | 724 | "line": 31 |
673 | }, | 725 | }, |
674 | "file": "src/components/layout/AppLayout.js", | 726 | "file": "src/components/layout/AppLayout.js", |
675 | "id": "infobar.servicesUpdated", | 727 | "id": "infobar.servicesUpdated", |
676 | "start": { | 728 | "start": { |
677 | "column": 19, | 729 | "column": 19, |
678 | "line": 26 | 730 | "line": 28 |
679 | } | 731 | } |
680 | }, | 732 | }, |
681 | { | 733 | { |
682 | "defaultMessage": "!!!Reload services", | 734 | "defaultMessage": "!!!Reload services", |
683 | "end": { | 735 | "end": { |
684 | "column": 3, | 736 | "column": 3, |
685 | "line": 33 | 737 | "line": 35 |
686 | }, | 738 | }, |
687 | "file": "src/components/layout/AppLayout.js", | 739 | "file": "src/components/layout/AppLayout.js", |
688 | "id": "infobar.buttonReloadServices", | 740 | "id": "infobar.buttonReloadServices", |
689 | "start": { | 741 | "start": { |
690 | "column": 24, | 742 | "column": 24, |
691 | "line": 30 | 743 | "line": 32 |
692 | } | 744 | } |
693 | }, | 745 | }, |
694 | { | 746 | { |
695 | "defaultMessage": "!!!Could not load services and user information", | 747 | "defaultMessage": "!!!Could not load services and user information", |
696 | "end": { | 748 | "end": { |
697 | "column": 3, | 749 | "column": 3, |
698 | "line": 37 | 750 | "line": 39 |
699 | }, | 751 | }, |
700 | "file": "src/components/layout/AppLayout.js", | 752 | "file": "src/components/layout/AppLayout.js", |
701 | "id": "infobar.requiredRequestsFailed", | 753 | "id": "infobar.requiredRequestsFailed", |
702 | "start": { | 754 | "start": { |
703 | "column": 26, | 755 | "column": 26, |
704 | "line": 34 | 756 | "line": 36 |
705 | } | 757 | } |
706 | } | 758 | } |
707 | ], | 759 | ], |
@@ -894,29 +946,99 @@ | |||
894 | { | 946 | { |
895 | "descriptors": [ | 947 | "descriptors": [ |
896 | { | 948 | { |
897 | "defaultMessage": "!!!Welcome to Franz", | 949 | "defaultMessage": "!!!You have reached your service limit.", |
898 | "end": { | 950 | "end": { |
899 | "column": 3, | 951 | "column": 3, |
900 | "line": 14 | 952 | "line": 14 |
901 | }, | 953 | }, |
954 | "file": "src/components/services/content/ServiceRestricted.js", | ||
955 | "id": "service.restrictedHandler.serviceLimit.headline", | ||
956 | "start": { | ||
957 | "column": 24, | ||
958 | "line": 11 | ||
959 | } | ||
960 | }, | ||
961 | { | ||
962 | "defaultMessage": "!!!Please upgrade your account to use more than {count} services.", | ||
963 | "end": { | ||
964 | "column": 3, | ||
965 | "line": 18 | ||
966 | }, | ||
967 | "file": "src/components/services/content/ServiceRestricted.js", | ||
968 | "id": "service.restrictedHandler.serviceLimit.text", | ||
969 | "start": { | ||
970 | "column": 20, | ||
971 | "line": 15 | ||
972 | } | ||
973 | }, | ||
974 | { | ||
975 | "defaultMessage": "!!!Franz Professional Plan required", | ||
976 | "end": { | ||
977 | "column": 3, | ||
978 | "line": 22 | ||
979 | }, | ||
980 | "file": "src/components/services/content/ServiceRestricted.js", | ||
981 | "id": "service.restrictedHandler.customUrl.headline", | ||
982 | "start": { | ||
983 | "column": 21, | ||
984 | "line": 19 | ||
985 | } | ||
986 | }, | ||
987 | { | ||
988 | "defaultMessage": "!!!Please upgrade to the Franz Professional plan to use custom urls & self hosted services.", | ||
989 | "end": { | ||
990 | "column": 3, | ||
991 | "line": 26 | ||
992 | }, | ||
993 | "file": "src/components/services/content/ServiceRestricted.js", | ||
994 | "id": "service.restrictedHandler.customUrl.text", | ||
995 | "start": { | ||
996 | "column": 17, | ||
997 | "line": 23 | ||
998 | } | ||
999 | }, | ||
1000 | { | ||
1001 | "defaultMessage": "!!!Upgrade Account", | ||
1002 | "end": { | ||
1003 | "column": 3, | ||
1004 | "line": 30 | ||
1005 | }, | ||
1006 | "file": "src/components/services/content/ServiceRestricted.js", | ||
1007 | "id": "service.restrictedHandler.action", | ||
1008 | "start": { | ||
1009 | "column": 10, | ||
1010 | "line": 27 | ||
1011 | } | ||
1012 | } | ||
1013 | ], | ||
1014 | "path": "src/components/services/content/ServiceRestricted.json" | ||
1015 | }, | ||
1016 | { | ||
1017 | "descriptors": [ | ||
1018 | { | ||
1019 | "defaultMessage": "!!!Welcome to Franz", | ||
1020 | "end": { | ||
1021 | "column": 3, | ||
1022 | "line": 17 | ||
1023 | }, | ||
902 | "file": "src/components/services/content/Services.js", | 1024 | "file": "src/components/services/content/Services.js", |
903 | "id": "services.welcome", | 1025 | "id": "services.welcome", |
904 | "start": { | 1026 | "start": { |
905 | "column": 11, | 1027 | "column": 11, |
906 | "line": 11 | 1028 | "line": 14 |
907 | } | 1029 | } |
908 | }, | 1030 | }, |
909 | { | 1031 | { |
910 | "defaultMessage": "!!!Get started", | 1032 | "defaultMessage": "!!!Get started", |
911 | "end": { | 1033 | "end": { |
912 | "column": 3, | 1034 | "column": 3, |
913 | "line": 18 | 1035 | "line": 21 |
914 | }, | 1036 | }, |
915 | "file": "src/components/services/content/Services.js", | 1037 | "file": "src/components/services/content/Services.js", |
916 | "id": "services.getStarted", | 1038 | "id": "services.getStarted", |
917 | "start": { | 1039 | "start": { |
918 | "column": 14, | 1040 | "column": 14, |
919 | "line": 15 | 1041 | "line": 18 |
920 | } | 1042 | } |
921 | } | 1043 | } |
922 | ], | 1044 | ], |
@@ -1107,38 +1229,25 @@ | |||
1107 | "defaultMessage": "!!!Account", | 1229 | "defaultMessage": "!!!Account", |
1108 | "end": { | 1230 | "end": { |
1109 | "column": 3, | 1231 | "column": 3, |
1110 | "line": 17 | 1232 | "line": 21 |
1111 | }, | 1233 | }, |
1112 | "file": "src/components/settings/account/AccountDashboard.js", | 1234 | "file": "src/components/settings/account/AccountDashboard.js", |
1113 | "id": "settings.account.headline", | 1235 | "id": "settings.account.headline", |
1114 | "start": { | 1236 | "start": { |
1115 | "column": 12, | 1237 | "column": 12, |
1116 | "line": 14 | 1238 | "line": 18 |
1117 | } | 1239 | } |
1118 | }, | 1240 | }, |
1119 | { | 1241 | { |
1120 | "defaultMessage": "!!!Your Subscription", | 1242 | "defaultMessage": "!!!Your Subscription", |
1121 | "end": { | 1243 | "end": { |
1122 | "column": 3, | 1244 | "column": 3, |
1123 | "line": 21 | 1245 | "line": 25 |
1124 | }, | 1246 | }, |
1125 | "file": "src/components/settings/account/AccountDashboard.js", | 1247 | "file": "src/components/settings/account/AccountDashboard.js", |
1126 | "id": "settings.account.headlineSubscription", | 1248 | "id": "settings.account.headlineSubscription", |
1127 | "start": { | 1249 | "start": { |
1128 | "column": 24, | 1250 | "column": 24, |
1129 | "line": 18 | ||
1130 | } | ||
1131 | }, | ||
1132 | { | ||
1133 | "defaultMessage": "!!!Upgrade your Account", | ||
1134 | "end": { | ||
1135 | "column": 3, | ||
1136 | "line": 25 | ||
1137 | }, | ||
1138 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1139 | "id": "settings.account.headlineUpgrade", | ||
1140 | "start": { | ||
1141 | "column": 19, | ||
1142 | "line": 22 | 1251 | "line": 22 |
1143 | } | 1252 | } |
1144 | }, | 1253 | }, |
@@ -1169,133 +1278,198 @@ | |||
1169 | } | 1278 | } |
1170 | }, | 1279 | }, |
1171 | { | 1280 | { |
1172 | "defaultMessage": "!!!Basic Account", | 1281 | "defaultMessage": "!!!Upgrade to Franz Professional", |
1173 | "end": { | 1282 | "end": { |
1174 | "column": 3, | 1283 | "column": 3, |
1175 | "line": 37 | 1284 | "line": 37 |
1176 | }, | 1285 | }, |
1177 | "file": "src/components/settings/account/AccountDashboard.js", | 1286 | "file": "src/components/settings/account/AccountDashboard.js", |
1287 | "id": "settings.account.upgradeToPro.label", | ||
1288 | "start": { | ||
1289 | "column": 23, | ||
1290 | "line": 34 | ||
1291 | } | ||
1292 | }, | ||
1293 | { | ||
1294 | "defaultMessage": "!!!Basic Account", | ||
1295 | "end": { | ||
1296 | "column": 3, | ||
1297 | "line": 41 | ||
1298 | }, | ||
1299 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1178 | "id": "settings.account.accountType.basic", | 1300 | "id": "settings.account.accountType.basic", |
1179 | "start": { | 1301 | "start": { |
1180 | "column": 20, | 1302 | "column": 20, |
1181 | "line": 34 | 1303 | "line": 38 |
1182 | } | 1304 | } |
1183 | }, | 1305 | }, |
1184 | { | 1306 | { |
1185 | "defaultMessage": "!!!Premium Supporter Account", | 1307 | "defaultMessage": "!!!Premium Supporter Account", |
1186 | "end": { | 1308 | "end": { |
1187 | "column": 3, | 1309 | "column": 3, |
1188 | "line": 41 | 1310 | "line": 45 |
1189 | }, | 1311 | }, |
1190 | "file": "src/components/settings/account/AccountDashboard.js", | 1312 | "file": "src/components/settings/account/AccountDashboard.js", |
1191 | "id": "settings.account.accountType.premium", | 1313 | "id": "settings.account.accountType.premium", |
1192 | "start": { | 1314 | "start": { |
1193 | "column": 22, | 1315 | "column": 22, |
1194 | "line": 38 | 1316 | "line": 42 |
1195 | } | 1317 | } |
1196 | }, | 1318 | }, |
1197 | { | 1319 | { |
1198 | "defaultMessage": "!!!Edit Account", | 1320 | "defaultMessage": "!!!Edit Account", |
1199 | "end": { | 1321 | "end": { |
1200 | "column": 3, | 1322 | "column": 3, |
1201 | "line": 45 | 1323 | "line": 49 |
1202 | }, | 1324 | }, |
1203 | "file": "src/components/settings/account/AccountDashboard.js", | 1325 | "file": "src/components/settings/account/AccountDashboard.js", |
1204 | "id": "settings.account.account.editButton", | 1326 | "id": "settings.account.account.editButton", |
1205 | "start": { | 1327 | "start": { |
1206 | "column": 21, | 1328 | "column": 21, |
1207 | "line": 42 | 1329 | "line": 46 |
1208 | } | 1330 | } |
1209 | }, | 1331 | }, |
1210 | { | 1332 | { |
1211 | "defaultMessage": "!!Invoices", | 1333 | "defaultMessage": "!!Invoices", |
1212 | "end": { | 1334 | "end": { |
1213 | "column": 3, | 1335 | "column": 3, |
1214 | "line": 49 | 1336 | "line": 53 |
1215 | }, | 1337 | }, |
1216 | "file": "src/components/settings/account/AccountDashboard.js", | 1338 | "file": "src/components/settings/account/AccountDashboard.js", |
1217 | "id": "settings.account.headlineInvoices", | 1339 | "id": "settings.account.headlineInvoices", |
1218 | "start": { | 1340 | "start": { |
1219 | "column": 18, | 1341 | "column": 18, |
1220 | "line": 46 | 1342 | "line": 50 |
1221 | } | 1343 | } |
1222 | }, | 1344 | }, |
1223 | { | 1345 | { |
1224 | "defaultMessage": "!!!Download", | 1346 | "defaultMessage": "!!!Download", |
1225 | "end": { | 1347 | "end": { |
1226 | "column": 3, | 1348 | "column": 3, |
1227 | "line": 53 | 1349 | "line": 57 |
1228 | }, | 1350 | }, |
1229 | "file": "src/components/settings/account/AccountDashboard.js", | 1351 | "file": "src/components/settings/account/AccountDashboard.js", |
1230 | "id": "settings.account.invoiceDownload", | 1352 | "id": "settings.account.invoiceDownload", |
1231 | "start": { | 1353 | "start": { |
1232 | "column": 19, | 1354 | "column": 19, |
1233 | "line": 50 | 1355 | "line": 54 |
1234 | } | 1356 | } |
1235 | }, | 1357 | }, |
1236 | { | 1358 | { |
1237 | "defaultMessage": "!!!Could not load user information", | 1359 | "defaultMessage": "!!!Could not load user information", |
1238 | "end": { | 1360 | "end": { |
1239 | "column": 3, | 1361 | "column": 3, |
1240 | "line": 57 | 1362 | "line": 61 |
1241 | }, | 1363 | }, |
1242 | "file": "src/components/settings/account/AccountDashboard.js", | 1364 | "file": "src/components/settings/account/AccountDashboard.js", |
1243 | "id": "settings.account.userInfoRequestFailed", | 1365 | "id": "settings.account.userInfoRequestFailed", |
1244 | "start": { | 1366 | "start": { |
1245 | "column": 25, | 1367 | "column": 25, |
1246 | "line": 54 | 1368 | "line": 58 |
1247 | } | 1369 | } |
1248 | }, | 1370 | }, |
1249 | { | 1371 | { |
1250 | "defaultMessage": "!!!Try again", | 1372 | "defaultMessage": "!!!Try again", |
1251 | "end": { | 1373 | "end": { |
1252 | "column": 3, | 1374 | "column": 3, |
1253 | "line": 61 | 1375 | "line": 65 |
1254 | }, | 1376 | }, |
1255 | "file": "src/components/settings/account/AccountDashboard.js", | 1377 | "file": "src/components/settings/account/AccountDashboard.js", |
1256 | "id": "settings.account.tryReloadUserInfoRequest", | 1378 | "id": "settings.account.tryReloadUserInfoRequest", |
1257 | "start": { | 1379 | "start": { |
1258 | "column": 28, | 1380 | "column": 28, |
1259 | "line": 58 | 1381 | "line": 62 |
1260 | } | 1382 | } |
1261 | }, | 1383 | }, |
1262 | { | 1384 | { |
1263 | "defaultMessage": "!!!Delete account", | 1385 | "defaultMessage": "!!!Delete account", |
1264 | "end": { | 1386 | "end": { |
1265 | "column": 3, | 1387 | "column": 3, |
1266 | "line": 65 | 1388 | "line": 69 |
1267 | }, | 1389 | }, |
1268 | "file": "src/components/settings/account/AccountDashboard.js", | 1390 | "file": "src/components/settings/account/AccountDashboard.js", |
1269 | "id": "settings.account.deleteAccount", | 1391 | "id": "settings.account.deleteAccount", |
1270 | "start": { | 1392 | "start": { |
1271 | "column": 17, | 1393 | "column": 17, |
1272 | "line": 62 | 1394 | "line": 66 |
1273 | } | 1395 | } |
1274 | }, | 1396 | }, |
1275 | { | 1397 | { |
1276 | "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", | 1398 | "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", |
1277 | "end": { | 1399 | "end": { |
1278 | "column": 3, | 1400 | "column": 3, |
1279 | "line": 69 | 1401 | "line": 73 |
1280 | }, | 1402 | }, |
1281 | "file": "src/components/settings/account/AccountDashboard.js", | 1403 | "file": "src/components/settings/account/AccountDashboard.js", |
1282 | "id": "settings.account.deleteInfo", | 1404 | "id": "settings.account.deleteInfo", |
1283 | "start": { | 1405 | "start": { |
1284 | "column": 14, | 1406 | "column": 14, |
1285 | "line": 66 | 1407 | "line": 70 |
1286 | } | 1408 | } |
1287 | }, | 1409 | }, |
1288 | { | 1410 | { |
1289 | "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", | 1411 | "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", |
1290 | "end": { | 1412 | "end": { |
1291 | "column": 3, | 1413 | "column": 3, |
1292 | "line": 73 | 1414 | "line": 77 |
1293 | }, | 1415 | }, |
1294 | "file": "src/components/settings/account/AccountDashboard.js", | 1416 | "file": "src/components/settings/account/AccountDashboard.js", |
1295 | "id": "settings.account.deleteEmailSent", | 1417 | "id": "settings.account.deleteEmailSent", |
1296 | "start": { | 1418 | "start": { |
1297 | "column": 19, | 1419 | "column": 19, |
1298 | "line": 70 | 1420 | "line": 74 |
1421 | } | ||
1422 | }, | ||
1423 | { | ||
1424 | "defaultMessage": "!!!Free Trial", | ||
1425 | "end": { | ||
1426 | "column": 3, | ||
1427 | "line": 81 | ||
1428 | }, | ||
1429 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1430 | "id": "settings.account.trial", | ||
1431 | "start": { | ||
1432 | "column": 9, | ||
1433 | "line": 78 | ||
1434 | } | ||
1435 | }, | ||
1436 | { | ||
1437 | "defaultMessage": "!!!Your Franz License:", | ||
1438 | "end": { | ||
1439 | "column": 3, | ||
1440 | "line": 85 | ||
1441 | }, | ||
1442 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1443 | "id": "settings.account.yourLicense", | ||
1444 | "start": { | ||
1445 | "column": 15, | ||
1446 | "line": 82 | ||
1447 | } | ||
1448 | }, | ||
1449 | { | ||
1450 | "defaultMessage": "!!!Your free trial ends in {duration}.", | ||
1451 | "end": { | ||
1452 | "column": 3, | ||
1453 | "line": 89 | ||
1454 | }, | ||
1455 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1456 | "id": "settings.account.trialEndsIn", | ||
1457 | "start": { | ||
1458 | "column": 15, | ||
1459 | "line": 86 | ||
1460 | } | ||
1461 | }, | ||
1462 | { | ||
1463 | "defaultMessage": "!!!Please update your billing info to continue using {license} after your trial period.", | ||
1464 | "end": { | ||
1465 | "column": 3, | ||
1466 | "line": 93 | ||
1467 | }, | ||
1468 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1469 | "id": "settings.account.trialUpdateBillingInfo", | ||
1470 | "start": { | ||
1471 | "column": 33, | ||
1472 | "line": 90 | ||
1299 | } | 1473 | } |
1300 | } | 1474 | } |
1301 | ], | 1475 | ], |
@@ -1307,104 +1481,104 @@ | |||
1307 | "defaultMessage": "!!!Available services", | 1481 | "defaultMessage": "!!!Available services", |
1308 | "end": { | 1482 | "end": { |
1309 | "column": 3, | 1483 | "column": 3, |
1310 | "line": 16 | 1484 | "line": 17 |
1311 | }, | 1485 | }, |
1312 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1486 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1313 | "id": "settings.navigation.availableServices", | 1487 | "id": "settings.navigation.availableServices", |
1314 | "start": { | 1488 | "start": { |
1315 | "column": 21, | 1489 | "column": 21, |
1316 | "line": 13 | 1490 | "line": 14 |
1317 | } | 1491 | } |
1318 | }, | 1492 | }, |
1319 | { | 1493 | { |
1320 | "defaultMessage": "!!!Your services", | 1494 | "defaultMessage": "!!!Your services", |
1321 | "end": { | 1495 | "end": { |
1322 | "column": 3, | 1496 | "column": 3, |
1323 | "line": 20 | 1497 | "line": 21 |
1324 | }, | 1498 | }, |
1325 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1499 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1326 | "id": "settings.navigation.yourServices", | 1500 | "id": "settings.navigation.yourServices", |
1327 | "start": { | 1501 | "start": { |
1328 | "column": 16, | 1502 | "column": 16, |
1329 | "line": 17 | 1503 | "line": 18 |
1330 | } | 1504 | } |
1331 | }, | 1505 | }, |
1332 | { | 1506 | { |
1333 | "defaultMessage": "!!!Your workspaces", | 1507 | "defaultMessage": "!!!Your workspaces", |
1334 | "end": { | 1508 | "end": { |
1335 | "column": 3, | 1509 | "column": 3, |
1336 | "line": 24 | 1510 | "line": 25 |
1337 | }, | 1511 | }, |
1338 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1512 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1339 | "id": "settings.navigation.yourWorkspaces", | 1513 | "id": "settings.navigation.yourWorkspaces", |
1340 | "start": { | 1514 | "start": { |
1341 | "column": 18, | 1515 | "column": 18, |
1342 | "line": 21 | 1516 | "line": 22 |
1343 | } | 1517 | } |
1344 | }, | 1518 | }, |
1345 | { | 1519 | { |
1346 | "defaultMessage": "!!!Account", | 1520 | "defaultMessage": "!!!Account", |
1347 | "end": { | 1521 | "end": { |
1348 | "column": 3, | 1522 | "column": 3, |
1349 | "line": 28 | 1523 | "line": 29 |
1350 | }, | 1524 | }, |
1351 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1525 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1352 | "id": "settings.navigation.account", | 1526 | "id": "settings.navigation.account", |
1353 | "start": { | 1527 | "start": { |
1354 | "column": 11, | 1528 | "column": 11, |
1355 | "line": 25 | 1529 | "line": 26 |
1356 | } | 1530 | } |
1357 | }, | 1531 | }, |
1358 | { | 1532 | { |
1359 | "defaultMessage": "!!!Manage Team", | 1533 | "defaultMessage": "!!!Manage Team", |
1360 | "end": { | 1534 | "end": { |
1361 | "column": 3, | 1535 | "column": 3, |
1362 | "line": 32 | 1536 | "line": 33 |
1363 | }, | 1537 | }, |
1364 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1538 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1365 | "id": "settings.navigation.team", | 1539 | "id": "settings.navigation.team", |
1366 | "start": { | 1540 | "start": { |
1367 | "column": 8, | 1541 | "column": 8, |
1368 | "line": 29 | 1542 | "line": 30 |
1369 | } | 1543 | } |
1370 | }, | 1544 | }, |
1371 | { | 1545 | { |
1372 | "defaultMessage": "!!!Settings", | 1546 | "defaultMessage": "!!!Settings", |
1373 | "end": { | 1547 | "end": { |
1374 | "column": 3, | 1548 | "column": 3, |
1375 | "line": 36 | 1549 | "line": 37 |
1376 | }, | 1550 | }, |
1377 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1551 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1378 | "id": "settings.navigation.settings", | 1552 | "id": "settings.navigation.settings", |
1379 | "start": { | 1553 | "start": { |
1380 | "column": 12, | 1554 | "column": 12, |
1381 | "line": 33 | 1555 | "line": 34 |
1382 | } | 1556 | } |
1383 | }, | 1557 | }, |
1384 | { | 1558 | { |
1385 | "defaultMessage": "!!!Invite Friends", | 1559 | "defaultMessage": "!!!Invite Friends", |
1386 | "end": { | 1560 | "end": { |
1387 | "column": 3, | 1561 | "column": 3, |
1388 | "line": 40 | 1562 | "line": 41 |
1389 | }, | 1563 | }, |
1390 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1564 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1391 | "id": "settings.navigation.inviteFriends", | 1565 | "id": "settings.navigation.inviteFriends", |
1392 | "start": { | 1566 | "start": { |
1393 | "column": 17, | 1567 | "column": 17, |
1394 | "line": 37 | 1568 | "line": 38 |
1395 | } | 1569 | } |
1396 | }, | 1570 | }, |
1397 | { | 1571 | { |
1398 | "defaultMessage": "!!!Logout", | 1572 | "defaultMessage": "!!!Logout", |
1399 | "end": { | 1573 | "end": { |
1400 | "column": 3, | 1574 | "column": 3, |
1401 | "line": 44 | 1575 | "line": 45 |
1402 | }, | 1576 | }, |
1403 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1577 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1404 | "id": "settings.navigation.logout", | 1578 | "id": "settings.navigation.logout", |
1405 | "start": { | 1579 | "start": { |
1406 | "column": 10, | 1580 | "column": 10, |
1407 | "line": 41 | 1581 | "line": 42 |
1408 | } | 1582 | } |
1409 | } | 1583 | } |
1410 | ], | 1584 | ], |
@@ -1416,104 +1590,182 @@ | |||
1416 | "defaultMessage": "!!!Available Services", | 1590 | "defaultMessage": "!!!Available Services", |
1417 | "end": { | 1591 | "end": { |
1418 | "column": 3, | 1592 | "column": 3, |
1419 | "line": 18 | 1593 | "line": 23 |
1420 | }, | 1594 | }, |
1421 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1595 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1422 | "id": "settings.recipes.headline", | 1596 | "id": "settings.recipes.headline", |
1423 | "start": { | 1597 | "start": { |
1424 | "column": 12, | 1598 | "column": 12, |
1425 | "line": 15 | 1599 | "line": 20 |
1426 | } | 1600 | } |
1427 | }, | 1601 | }, |
1428 | { | 1602 | { |
1429 | "defaultMessage": "!!!Search service", | 1603 | "defaultMessage": "!!!Search service", |
1430 | "end": { | 1604 | "end": { |
1431 | "column": 3, | 1605 | "column": 3, |
1432 | "line": 22 | 1606 | "line": 27 |
1433 | }, | 1607 | }, |
1434 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1608 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1435 | "id": "settings.searchService", | 1609 | "id": "settings.searchService", |
1436 | "start": { | 1610 | "start": { |
1437 | "column": 17, | 1611 | "column": 17, |
1438 | "line": 19 | 1612 | "line": 24 |
1439 | } | 1613 | } |
1440 | }, | 1614 | }, |
1441 | { | 1615 | { |
1442 | "defaultMessage": "!!!Most popular", | 1616 | "defaultMessage": "!!!Most popular", |
1443 | "end": { | 1617 | "end": { |
1444 | "column": 3, | 1618 | "column": 3, |
1445 | "line": 26 | 1619 | "line": 31 |
1446 | }, | 1620 | }, |
1447 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1621 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1448 | "id": "settings.recipes.mostPopular", | 1622 | "id": "settings.recipes.mostPopular", |
1449 | "start": { | 1623 | "start": { |
1450 | "column": 22, | 1624 | "column": 22, |
1451 | "line": 23 | 1625 | "line": 28 |
1452 | } | 1626 | } |
1453 | }, | 1627 | }, |
1454 | { | 1628 | { |
1455 | "defaultMessage": "!!!All services", | 1629 | "defaultMessage": "!!!All services", |
1456 | "end": { | 1630 | "end": { |
1457 | "column": 3, | 1631 | "column": 3, |
1458 | "line": 30 | 1632 | "line": 35 |
1459 | }, | 1633 | }, |
1460 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1634 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1461 | "id": "settings.recipes.all", | 1635 | "id": "settings.recipes.all", |
1462 | "start": { | 1636 | "start": { |
1463 | "column": 14, | 1637 | "column": 14, |
1464 | "line": 27 | 1638 | "line": 32 |
1465 | } | 1639 | } |
1466 | }, | 1640 | }, |
1467 | { | 1641 | { |
1468 | "defaultMessage": "!!!Development", | 1642 | "defaultMessage": "!!!Custom Services", |
1469 | "end": { | 1643 | "end": { |
1470 | "column": 3, | 1644 | "column": 3, |
1471 | "line": 34 | 1645 | "line": 39 |
1472 | }, | 1646 | }, |
1473 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1647 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1474 | "id": "settings.recipes.dev", | 1648 | "id": "settings.recipes.custom", |
1475 | "start": { | 1649 | "start": { |
1476 | "column": 14, | 1650 | "column": 17, |
1477 | "line": 31 | 1651 | "line": 36 |
1478 | } | 1652 | } |
1479 | }, | 1653 | }, |
1480 | { | 1654 | { |
1481 | "defaultMessage": "!!!Sorry, but no service matched your search term.", | 1655 | "defaultMessage": "!!!Sorry, but no service matched your search term.", |
1482 | "end": { | 1656 | "end": { |
1483 | "column": 3, | 1657 | "column": 3, |
1484 | "line": 38 | 1658 | "line": 43 |
1485 | }, | 1659 | }, |
1486 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1660 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1487 | "id": "settings.recipes.nothingFound", | 1661 | "id": "settings.recipes.nothingFound", |
1488 | "start": { | 1662 | "start": { |
1489 | "column": 16, | 1663 | "column": 16, |
1490 | "line": 35 | 1664 | "line": 40 |
1491 | } | 1665 | } |
1492 | }, | 1666 | }, |
1493 | { | 1667 | { |
1494 | "defaultMessage": "!!!Service successfully added", | 1668 | "defaultMessage": "!!!Service successfully added", |
1495 | "end": { | 1669 | "end": { |
1496 | "column": 3, | 1670 | "column": 3, |
1497 | "line": 42 | 1671 | "line": 47 |
1498 | }, | 1672 | }, |
1499 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1673 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1500 | "id": "settings.recipes.servicesSuccessfulAddedInfo", | 1674 | "id": "settings.recipes.servicesSuccessfulAddedInfo", |
1501 | "start": { | 1675 | "start": { |
1502 | "column": 31, | 1676 | "column": 31, |
1503 | "line": 39 | 1677 | "line": 44 |
1504 | } | 1678 | } |
1505 | }, | 1679 | }, |
1506 | { | 1680 | { |
1507 | "defaultMessage": "!!!Missing a service?", | 1681 | "defaultMessage": "!!!Missing a service?", |
1508 | "end": { | 1682 | "end": { |
1509 | "column": 3, | 1683 | "column": 3, |
1510 | "line": 46 | 1684 | "line": 51 |
1511 | }, | 1685 | }, |
1512 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1686 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1513 | "id": "settings.recipes.missingService", | 1687 | "id": "settings.recipes.missingService", |
1514 | "start": { | 1688 | "start": { |
1515 | "column": 18, | 1689 | "column": 18, |
1516 | "line": 43 | 1690 | "line": 48 |
1691 | } | ||
1692 | }, | ||
1693 | { | ||
1694 | "defaultMessage": "!!!To add a custom service, copy the recipe folder into:", | ||
1695 | "end": { | ||
1696 | "column": 3, | ||
1697 | "line": 55 | ||
1698 | }, | ||
1699 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1700 | "id": "settings.recipes.customService.intro", | ||
1701 | "start": { | ||
1702 | "column": 21, | ||
1703 | "line": 52 | ||
1704 | } | ||
1705 | }, | ||
1706 | { | ||
1707 | "defaultMessage": "!!!Open directory", | ||
1708 | "end": { | ||
1709 | "column": 3, | ||
1710 | "line": 59 | ||
1711 | }, | ||
1712 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1713 | "id": "settings.recipes.customService.openFolder", | ||
1714 | "start": { | ||
1715 | "column": 14, | ||
1716 | "line": 56 | ||
1717 | } | ||
1718 | }, | ||
1719 | { | ||
1720 | "defaultMessage": "!!!Developer Documentation", | ||
1721 | "end": { | ||
1722 | "column": 3, | ||
1723 | "line": 63 | ||
1724 | }, | ||
1725 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1726 | "id": "settings.recipes.customService.openDevDocs", | ||
1727 | "start": { | ||
1728 | "column": 15, | ||
1729 | "line": 60 | ||
1730 | } | ||
1731 | }, | ||
1732 | { | ||
1733 | "defaultMessage": "!!!Custom Service Recipes", | ||
1734 | "end": { | ||
1735 | "column": 3, | ||
1736 | "line": 67 | ||
1737 | }, | ||
1738 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1739 | "id": "settings.recipes.customService.headline.customRecipes", | ||
1740 | "start": { | ||
1741 | "column": 25, | ||
1742 | "line": 64 | ||
1743 | } | ||
1744 | }, | ||
1745 | { | ||
1746 | "defaultMessage": "!!!Community Services", | ||
1747 | "end": { | ||
1748 | "column": 3, | ||
1749 | "line": 71 | ||
1750 | }, | ||
1751 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1752 | "id": "settings.recipes.customService.headline.communityRecipes", | ||
1753 | "start": { | ||
1754 | "column": 28, | ||
1755 | "line": 68 | ||
1756 | } | ||
1757 | }, | ||
1758 | { | ||
1759 | "defaultMessage": "!!!Your Development Service Recipes", | ||
1760 | "end": { | ||
1761 | "column": 3, | ||
1762 | "line": 75 | ||
1763 | }, | ||
1764 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1765 | "id": "settings.recipes.customService.headline.devRecipes", | ||
1766 | "start": { | ||
1767 | "column": 22, | ||
1768 | "line": 72 | ||
1517 | } | 1769 | } |
1518 | } | 1770 | } |
1519 | ], | 1771 | ], |
@@ -1525,286 +1777,286 @@ | |||
1525 | "defaultMessage": "!!!Save service", | 1777 | "defaultMessage": "!!!Save service", |
1526 | "end": { | 1778 | "end": { |
1527 | "column": 3, | 1779 | "column": 3, |
1528 | "line": 25 | 1780 | "line": 27 |
1529 | }, | 1781 | }, |
1530 | "file": "src/components/settings/services/EditServiceForm.js", | 1782 | "file": "src/components/settings/services/EditServiceForm.js", |
1531 | "id": "settings.service.form.saveButton", | 1783 | "id": "settings.service.form.saveButton", |
1532 | "start": { | 1784 | "start": { |
1533 | "column": 15, | 1785 | "column": 15, |
1534 | "line": 22 | 1786 | "line": 24 |
1535 | } | 1787 | } |
1536 | }, | 1788 | }, |
1537 | { | 1789 | { |
1538 | "defaultMessage": "!!!Delete Service", | 1790 | "defaultMessage": "!!!Delete Service", |
1539 | "end": { | 1791 | "end": { |
1540 | "column": 3, | 1792 | "column": 3, |
1541 | "line": 29 | 1793 | "line": 31 |
1542 | }, | 1794 | }, |
1543 | "file": "src/components/settings/services/EditServiceForm.js", | 1795 | "file": "src/components/settings/services/EditServiceForm.js", |
1544 | "id": "settings.service.form.deleteButton", | 1796 | "id": "settings.service.form.deleteButton", |
1545 | "start": { | 1797 | "start": { |
1546 | "column": 17, | 1798 | "column": 17, |
1547 | "line": 26 | 1799 | "line": 28 |
1548 | } | 1800 | } |
1549 | }, | 1801 | }, |
1550 | { | 1802 | { |
1551 | "defaultMessage": "!!!Available services", | 1803 | "defaultMessage": "!!!Available services", |
1552 | "end": { | 1804 | "end": { |
1553 | "column": 3, | 1805 | "column": 3, |
1554 | "line": 33 | 1806 | "line": 35 |
1555 | }, | 1807 | }, |
1556 | "file": "src/components/settings/services/EditServiceForm.js", | 1808 | "file": "src/components/settings/services/EditServiceForm.js", |
1557 | "id": "settings.service.form.availableServices", | 1809 | "id": "settings.service.form.availableServices", |
1558 | "start": { | 1810 | "start": { |
1559 | "column": 21, | 1811 | "column": 21, |
1560 | "line": 30 | 1812 | "line": 32 |
1561 | } | 1813 | } |
1562 | }, | 1814 | }, |
1563 | { | 1815 | { |
1564 | "defaultMessage": "!!!Your services", | 1816 | "defaultMessage": "!!!Your services", |
1565 | "end": { | 1817 | "end": { |
1566 | "column": 3, | 1818 | "column": 3, |
1567 | "line": 37 | 1819 | "line": 39 |
1568 | }, | 1820 | }, |
1569 | "file": "src/components/settings/services/EditServiceForm.js", | 1821 | "file": "src/components/settings/services/EditServiceForm.js", |
1570 | "id": "settings.service.form.yourServices", | 1822 | "id": "settings.service.form.yourServices", |
1571 | "start": { | 1823 | "start": { |
1572 | "column": 16, | 1824 | "column": 16, |
1573 | "line": 34 | 1825 | "line": 36 |
1574 | } | 1826 | } |
1575 | }, | 1827 | }, |
1576 | { | 1828 | { |
1577 | "defaultMessage": "!!!Add {name}", | 1829 | "defaultMessage": "!!!Add {name}", |
1578 | "end": { | 1830 | "end": { |
1579 | "column": 3, | 1831 | "column": 3, |
1580 | "line": 41 | 1832 | "line": 43 |
1581 | }, | 1833 | }, |
1582 | "file": "src/components/settings/services/EditServiceForm.js", | 1834 | "file": "src/components/settings/services/EditServiceForm.js", |
1583 | "id": "settings.service.form.addServiceHeadline", | 1835 | "id": "settings.service.form.addServiceHeadline", |
1584 | "start": { | 1836 | "start": { |
1585 | "column": 22, | 1837 | "column": 22, |
1586 | "line": 38 | 1838 | "line": 40 |
1587 | } | 1839 | } |
1588 | }, | 1840 | }, |
1589 | { | 1841 | { |
1590 | "defaultMessage": "!!!Edit {name}", | 1842 | "defaultMessage": "!!!Edit {name}", |
1591 | "end": { | 1843 | "end": { |
1592 | "column": 3, | 1844 | "column": 3, |
1593 | "line": 45 | 1845 | "line": 47 |
1594 | }, | 1846 | }, |
1595 | "file": "src/components/settings/services/EditServiceForm.js", | 1847 | "file": "src/components/settings/services/EditServiceForm.js", |
1596 | "id": "settings.service.form.editServiceHeadline", | 1848 | "id": "settings.service.form.editServiceHeadline", |
1597 | "start": { | 1849 | "start": { |
1598 | "column": 23, | 1850 | "column": 23, |
1599 | "line": 42 | 1851 | "line": 44 |
1600 | } | 1852 | } |
1601 | }, | 1853 | }, |
1602 | { | 1854 | { |
1603 | "defaultMessage": "!!!Hosted", | 1855 | "defaultMessage": "!!!Hosted", |
1604 | "end": { | 1856 | "end": { |
1605 | "column": 3, | 1857 | "column": 3, |
1606 | "line": 49 | 1858 | "line": 51 |
1607 | }, | 1859 | }, |
1608 | "file": "src/components/settings/services/EditServiceForm.js", | 1860 | "file": "src/components/settings/services/EditServiceForm.js", |
1609 | "id": "settings.service.form.tabHosted", | 1861 | "id": "settings.service.form.tabHosted", |
1610 | "start": { | 1862 | "start": { |
1611 | "column": 13, | 1863 | "column": 13, |
1612 | "line": 46 | 1864 | "line": 48 |
1613 | } | 1865 | } |
1614 | }, | 1866 | }, |
1615 | { | 1867 | { |
1616 | "defaultMessage": "!!!Self hosted ⭐️", | 1868 | "defaultMessage": "!!!Self hosted ⭐️", |
1617 | "end": { | 1869 | "end": { |
1618 | "column": 3, | 1870 | "column": 3, |
1619 | "line": 53 | 1871 | "line": 55 |
1620 | }, | 1872 | }, |
1621 | "file": "src/components/settings/services/EditServiceForm.js", | 1873 | "file": "src/components/settings/services/EditServiceForm.js", |
1622 | "id": "settings.service.form.tabOnPremise", | 1874 | "id": "settings.service.form.tabOnPremise", |
1623 | "start": { | 1875 | "start": { |
1624 | "column": 16, | 1876 | "column": 16, |
1625 | "line": 50 | 1877 | "line": 52 |
1626 | } | 1878 | } |
1627 | }, | 1879 | }, |
1628 | { | 1880 | { |
1629 | "defaultMessage": "!!!Use the hosted {name} service.", | 1881 | "defaultMessage": "!!!Use the hosted {name} service.", |
1630 | "end": { | 1882 | "end": { |
1631 | "column": 3, | 1883 | "column": 3, |
1632 | "line": 57 | 1884 | "line": 59 |
1633 | }, | 1885 | }, |
1634 | "file": "src/components/settings/services/EditServiceForm.js", | 1886 | "file": "src/components/settings/services/EditServiceForm.js", |
1635 | "id": "settings.service.form.useHostedService", | 1887 | "id": "settings.service.form.useHostedService", |
1636 | "start": { | 1888 | "start": { |
1637 | "column": 20, | 1889 | "column": 20, |
1638 | "line": 54 | 1890 | "line": 56 |
1639 | } | 1891 | } |
1640 | }, | 1892 | }, |
1641 | { | 1893 | { |
1642 | "defaultMessage": "!!!Could not validate custom {name} server.", | 1894 | "defaultMessage": "!!!Could not validate custom {name} server.", |
1643 | "end": { | 1895 | "end": { |
1644 | "column": 3, | 1896 | "column": 3, |
1645 | "line": 61 | 1897 | "line": 63 |
1646 | }, | 1898 | }, |
1647 | "file": "src/components/settings/services/EditServiceForm.js", | 1899 | "file": "src/components/settings/services/EditServiceForm.js", |
1648 | "id": "settings.service.form.customUrlValidationError", | 1900 | "id": "settings.service.form.customUrlValidationError", |
1649 | "start": { | 1901 | "start": { |
1650 | "column": 28, | 1902 | "column": 28, |
1651 | "line": 58 | 1903 | "line": 60 |
1652 | } | 1904 | } |
1653 | }, | 1905 | }, |
1654 | { | 1906 | { |
1655 | "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", | 1907 | "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", |
1656 | "end": { | 1908 | "end": { |
1657 | "column": 3, | 1909 | "column": 3, |
1658 | "line": 65 | 1910 | "line": 67 |
1659 | }, | 1911 | }, |
1660 | "file": "src/components/settings/services/EditServiceForm.js", | 1912 | "file": "src/components/settings/services/EditServiceForm.js", |
1661 | "id": "settings.service.form.customUrlPremiumInfo", | 1913 | "id": "settings.service.form.customUrlPremiumInfo", |
1662 | "start": { | 1914 | "start": { |
1663 | "column": 24, | 1915 | "column": 24, |
1664 | "line": 62 | 1916 | "line": 64 |
1665 | } | 1917 | } |
1666 | }, | 1918 | }, |
1667 | { | 1919 | { |
1668 | "defaultMessage": "!!!Upgrade your account", | 1920 | "defaultMessage": "!!!Upgrade your account", |
1669 | "end": { | 1921 | "end": { |
1670 | "column": 3, | 1922 | "column": 3, |
1671 | "line": 69 | 1923 | "line": 71 |
1672 | }, | 1924 | }, |
1673 | "file": "src/components/settings/services/EditServiceForm.js", | 1925 | "file": "src/components/settings/services/EditServiceForm.js", |
1674 | "id": "settings.service.form.customUrlUpgradeAccount", | 1926 | "id": "settings.service.form.customUrlUpgradeAccount", |
1675 | "start": { | 1927 | "start": { |
1676 | "column": 27, | 1928 | "column": 27, |
1677 | "line": 66 | 1929 | "line": 68 |
1678 | } | 1930 | } |
1679 | }, | 1931 | }, |
1680 | { | 1932 | { |
1681 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", | 1933 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", |
1682 | "end": { | 1934 | "end": { |
1683 | "column": 3, | 1935 | "column": 3, |
1684 | "line": 73 | 1936 | "line": 75 |
1685 | }, | 1937 | }, |
1686 | "file": "src/components/settings/services/EditServiceForm.js", | 1938 | "file": "src/components/settings/services/EditServiceForm.js", |
1687 | "id": "settings.service.form.indirectMessageInfo", | 1939 | "id": "settings.service.form.indirectMessageInfo", |
1688 | "start": { | 1940 | "start": { |
1689 | "column": 23, | 1941 | "column": 23, |
1690 | "line": 70 | 1942 | "line": 72 |
1691 | } | 1943 | } |
1692 | }, | 1944 | }, |
1693 | { | 1945 | { |
1694 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", | 1946 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", |
1695 | "end": { | 1947 | "end": { |
1696 | "column": 3, | 1948 | "column": 3, |
1697 | "line": 77 | 1949 | "line": 79 |
1698 | }, | 1950 | }, |
1699 | "file": "src/components/settings/services/EditServiceForm.js", | 1951 | "file": "src/components/settings/services/EditServiceForm.js", |
1700 | "id": "settings.service.form.isMutedInfo", | 1952 | "id": "settings.service.form.isMutedInfo", |
1701 | "start": { | 1953 | "start": { |
1702 | "column": 15, | 1954 | "column": 15, |
1703 | "line": 74 | 1955 | "line": 76 |
1704 | } | 1956 | } |
1705 | }, | 1957 | }, |
1706 | { | 1958 | { |
1707 | "defaultMessage": "!!!Notifications", | 1959 | "defaultMessage": "!!!Notifications", |
1708 | "end": { | 1960 | "end": { |
1709 | "column": 3, | 1961 | "column": 3, |
1710 | "line": 81 | 1962 | "line": 83 |
1711 | }, | 1963 | }, |
1712 | "file": "src/components/settings/services/EditServiceForm.js", | 1964 | "file": "src/components/settings/services/EditServiceForm.js", |
1713 | "id": "settings.service.form.headlineNotifications", | 1965 | "id": "settings.service.form.headlineNotifications", |
1714 | "start": { | 1966 | "start": { |
1715 | "column": 25, | 1967 | "column": 25, |
1716 | "line": 78 | 1968 | "line": 80 |
1717 | } | 1969 | } |
1718 | }, | 1970 | }, |
1719 | { | 1971 | { |
1720 | "defaultMessage": "!!!Unread message badges", | 1972 | "defaultMessage": "!!!Unread message badges", |
1721 | "end": { | 1973 | "end": { |
1722 | "column": 3, | 1974 | "column": 3, |
1723 | "line": 85 | 1975 | "line": 87 |
1724 | }, | 1976 | }, |
1725 | "file": "src/components/settings/services/EditServiceForm.js", | 1977 | "file": "src/components/settings/services/EditServiceForm.js", |
1726 | "id": "settings.service.form.headlineBadges", | 1978 | "id": "settings.service.form.headlineBadges", |
1727 | "start": { | 1979 | "start": { |
1728 | "column": 18, | 1980 | "column": 18, |
1729 | "line": 82 | 1981 | "line": 84 |
1730 | } | 1982 | } |
1731 | }, | 1983 | }, |
1732 | { | 1984 | { |
1733 | "defaultMessage": "!!!General", | 1985 | "defaultMessage": "!!!General", |
1734 | "end": { | 1986 | "end": { |
1735 | "column": 3, | 1987 | "column": 3, |
1736 | "line": 89 | 1988 | "line": 91 |
1737 | }, | 1989 | }, |
1738 | "file": "src/components/settings/services/EditServiceForm.js", | 1990 | "file": "src/components/settings/services/EditServiceForm.js", |
1739 | "id": "settings.service.form.headlineGeneral", | 1991 | "id": "settings.service.form.headlineGeneral", |
1740 | "start": { | 1992 | "start": { |
1741 | "column": 19, | 1993 | "column": 19, |
1742 | "line": 86 | 1994 | "line": 88 |
1743 | } | 1995 | } |
1744 | }, | 1996 | }, |
1745 | { | 1997 | { |
1746 | "defaultMessage": "!!!Delete", | 1998 | "defaultMessage": "!!!Delete", |
1747 | "end": { | 1999 | "end": { |
1748 | "column": 3, | 2000 | "column": 3, |
1749 | "line": 93 | 2001 | "line": 95 |
1750 | }, | 2002 | }, |
1751 | "file": "src/components/settings/services/EditServiceForm.js", | 2003 | "file": "src/components/settings/services/EditServiceForm.js", |
1752 | "id": "settings.service.form.iconDelete", | 2004 | "id": "settings.service.form.iconDelete", |
1753 | "start": { | 2005 | "start": { |
1754 | "column": 14, | 2006 | "column": 14, |
1755 | "line": 90 | 2007 | "line": 92 |
1756 | } | 2008 | } |
1757 | }, | 2009 | }, |
1758 | { | 2010 | { |
1759 | "defaultMessage": "!!!Drop your image, or click here", | 2011 | "defaultMessage": "!!!Drop your image, or click here", |
1760 | "end": { | 2012 | "end": { |
1761 | "column": 3, | 2013 | "column": 3, |
1762 | "line": 97 | 2014 | "line": 99 |
1763 | }, | 2015 | }, |
1764 | "file": "src/components/settings/services/EditServiceForm.js", | 2016 | "file": "src/components/settings/services/EditServiceForm.js", |
1765 | "id": "settings.service.form.iconUpload", | 2017 | "id": "settings.service.form.iconUpload", |
1766 | "start": { | 2018 | "start": { |
1767 | "column": 14, | 2019 | "column": 14, |
1768 | "line": 94 | 2020 | "line": 96 |
1769 | } | 2021 | } |
1770 | }, | 2022 | }, |
1771 | { | 2023 | { |
1772 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", | 2024 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", |
1773 | "end": { | 2025 | "end": { |
1774 | "column": 3, | 2026 | "column": 3, |
1775 | "line": 101 | 2027 | "line": 103 |
1776 | }, | 2028 | }, |
1777 | "file": "src/components/settings/services/EditServiceForm.js", | 2029 | "file": "src/components/settings/services/EditServiceForm.js", |
1778 | "id": "settings.service.form.proxy.headline", | 2030 | "id": "settings.service.form.proxy.headline", |
1779 | "start": { | 2031 | "start": { |
1780 | "column": 17, | 2032 | "column": 17, |
1781 | "line": 98 | 2033 | "line": 100 |
1782 | } | 2034 | } |
1783 | }, | 2035 | }, |
1784 | { | 2036 | { |
1785 | "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", | 2037 | "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", |
1786 | "end": { | 2038 | "end": { |
1787 | "column": 3, | 2039 | "column": 3, |
1788 | "line": 105 | 2040 | "line": 107 |
1789 | }, | 2041 | }, |
1790 | "file": "src/components/settings/services/EditServiceForm.js", | 2042 | "file": "src/components/settings/services/EditServiceForm.js", |
1791 | "id": "settings.service.form.proxy.restartInfo", | 2043 | "id": "settings.service.form.proxy.restartInfo", |
1792 | "start": { | 2044 | "start": { |
1793 | "column": 20, | 2045 | "column": 20, |
1794 | "line": 102 | 2046 | "line": 104 |
1795 | } | 2047 | } |
1796 | }, | 2048 | }, |
1797 | { | 2049 | { |
1798 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", | 2050 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", |
1799 | "end": { | 2051 | "end": { |
1800 | "column": 3, | 2052 | "column": 3, |
1801 | "line": 109 | 2053 | "line": 111 |
1802 | }, | 2054 | }, |
1803 | "file": "src/components/settings/services/EditServiceForm.js", | 2055 | "file": "src/components/settings/services/EditServiceForm.js", |
1804 | "id": "settings.service.form.proxy.info", | 2056 | "id": "settings.service.form.proxy.info", |
1805 | "start": { | 2057 | "start": { |
1806 | "column": 13, | 2058 | "column": 13, |
1807 | "line": 106 | 2059 | "line": 108 |
1808 | } | 2060 | } |
1809 | } | 2061 | } |
1810 | ], | 2062 | ], |
@@ -1917,117 +2169,117 @@ | |||
1917 | "defaultMessage": "!!!Your services", | 2169 | "defaultMessage": "!!!Your services", |
1918 | "end": { | 2170 | "end": { |
1919 | "column": 3, | 2171 | "column": 3, |
1920 | "line": 17 | 2172 | "line": 18 |
1921 | }, | 2173 | }, |
1922 | "file": "src/components/settings/services/ServicesDashboard.js", | 2174 | "file": "src/components/settings/services/ServicesDashboard.js", |
1923 | "id": "settings.services.headline", | 2175 | "id": "settings.services.headline", |
1924 | "start": { | 2176 | "start": { |
1925 | "column": 12, | 2177 | "column": 12, |
1926 | "line": 14 | 2178 | "line": 15 |
1927 | } | 2179 | } |
1928 | }, | 2180 | }, |
1929 | { | 2181 | { |
1930 | "defaultMessage": "!!!Search service", | 2182 | "defaultMessage": "!!!Search service", |
1931 | "end": { | 2183 | "end": { |
1932 | "column": 3, | 2184 | "column": 3, |
1933 | "line": 21 | 2185 | "line": 22 |
1934 | }, | 2186 | }, |
1935 | "file": "src/components/settings/services/ServicesDashboard.js", | 2187 | "file": "src/components/settings/services/ServicesDashboard.js", |
1936 | "id": "settings.searchService", | 2188 | "id": "settings.searchService", |
1937 | "start": { | 2189 | "start": { |
1938 | "column": 17, | 2190 | "column": 17, |
1939 | "line": 18 | 2191 | "line": 19 |
1940 | } | 2192 | } |
1941 | }, | 2193 | }, |
1942 | { | 2194 | { |
1943 | "defaultMessage": "!!!You haven't added any services yet.", | 2195 | "defaultMessage": "!!!You haven't added any services yet.", |
1944 | "end": { | 2196 | "end": { |
1945 | "column": 3, | 2197 | "column": 3, |
1946 | "line": 25 | 2198 | "line": 26 |
1947 | }, | 2199 | }, |
1948 | "file": "src/components/settings/services/ServicesDashboard.js", | 2200 | "file": "src/components/settings/services/ServicesDashboard.js", |
1949 | "id": "settings.services.noServicesAdded", | 2201 | "id": "settings.services.noServicesAdded", |
1950 | "start": { | 2202 | "start": { |
1951 | "column": 19, | 2203 | "column": 19, |
1952 | "line": 22 | 2204 | "line": 23 |
1953 | } | 2205 | } |
1954 | }, | 2206 | }, |
1955 | { | 2207 | { |
1956 | "defaultMessage": "!!!Sorry, but no service matched your search term.", | 2208 | "defaultMessage": "!!!Sorry, but no service matched your search term.", |
1957 | "end": { | 2209 | "end": { |
1958 | "column": 3, | 2210 | "column": 3, |
1959 | "line": 29 | 2211 | "line": 30 |
1960 | }, | 2212 | }, |
1961 | "file": "src/components/settings/services/ServicesDashboard.js", | 2213 | "file": "src/components/settings/services/ServicesDashboard.js", |
1962 | "id": "settings.recipes.nothingFound", | 2214 | "id": "settings.recipes.nothingFound", |
1963 | "start": { | 2215 | "start": { |
1964 | "column": 18, | 2216 | "column": 18, |
1965 | "line": 26 | 2217 | "line": 27 |
1966 | } | 2218 | } |
1967 | }, | 2219 | }, |
1968 | { | 2220 | { |
1969 | "defaultMessage": "!!!Discover services", | 2221 | "defaultMessage": "!!!Discover services", |
1970 | "end": { | 2222 | "end": { |
1971 | "column": 3, | 2223 | "column": 3, |
1972 | "line": 33 | 2224 | "line": 34 |
1973 | }, | 2225 | }, |
1974 | "file": "src/components/settings/services/ServicesDashboard.js", | 2226 | "file": "src/components/settings/services/ServicesDashboard.js", |
1975 | "id": "settings.services.discoverServices", | 2227 | "id": "settings.services.discoverServices", |
1976 | "start": { | 2228 | "start": { |
1977 | "column": 20, | 2229 | "column": 20, |
1978 | "line": 30 | 2230 | "line": 31 |
1979 | } | 2231 | } |
1980 | }, | 2232 | }, |
1981 | { | 2233 | { |
1982 | "defaultMessage": "!!!Could not load your services", | 2234 | "defaultMessage": "!!!Could not load your services", |
1983 | "end": { | 2235 | "end": { |
1984 | "column": 3, | 2236 | "column": 3, |
1985 | "line": 37 | 2237 | "line": 38 |
1986 | }, | 2238 | }, |
1987 | "file": "src/components/settings/services/ServicesDashboard.js", | 2239 | "file": "src/components/settings/services/ServicesDashboard.js", |
1988 | "id": "settings.services.servicesRequestFailed", | 2240 | "id": "settings.services.servicesRequestFailed", |
1989 | "start": { | 2241 | "start": { |
1990 | "column": 25, | 2242 | "column": 25, |
1991 | "line": 34 | 2243 | "line": 35 |
1992 | } | 2244 | } |
1993 | }, | 2245 | }, |
1994 | { | 2246 | { |
1995 | "defaultMessage": "!!!Try again", | 2247 | "defaultMessage": "!!!Try again", |
1996 | "end": { | 2248 | "end": { |
1997 | "column": 3, | 2249 | "column": 3, |
1998 | "line": 41 | 2250 | "line": 42 |
1999 | }, | 2251 | }, |
2000 | "file": "src/components/settings/services/ServicesDashboard.js", | 2252 | "file": "src/components/settings/services/ServicesDashboard.js", |
2001 | "id": "settings.account.tryReloadServices", | 2253 | "id": "settings.account.tryReloadServices", |
2002 | "start": { | 2254 | "start": { |
2003 | "column": 21, | 2255 | "column": 21, |
2004 | "line": 38 | 2256 | "line": 39 |
2005 | } | 2257 | } |
2006 | }, | 2258 | }, |
2007 | { | 2259 | { |
2008 | "defaultMessage": "!!!Your changes have been saved", | 2260 | "defaultMessage": "!!!Your changes have been saved", |
2009 | "end": { | 2261 | "end": { |
2010 | "column": 3, | 2262 | "column": 3, |
2011 | "line": 45 | 2263 | "line": 46 |
2012 | }, | 2264 | }, |
2013 | "file": "src/components/settings/services/ServicesDashboard.js", | 2265 | "file": "src/components/settings/services/ServicesDashboard.js", |
2014 | "id": "settings.services.updatedInfo", | 2266 | "id": "settings.services.updatedInfo", |
2015 | "start": { | 2267 | "start": { |
2016 | "column": 15, | 2268 | "column": 15, |
2017 | "line": 42 | 2269 | "line": 43 |
2018 | } | 2270 | } |
2019 | }, | 2271 | }, |
2020 | { | 2272 | { |
2021 | "defaultMessage": "!!!Service has been deleted", | 2273 | "defaultMessage": "!!!Service has been deleted", |
2022 | "end": { | 2274 | "end": { |
2023 | "column": 3, | 2275 | "column": 3, |
2024 | "line": 49 | 2276 | "line": 50 |
2025 | }, | 2277 | }, |
2026 | "file": "src/components/settings/services/ServicesDashboard.js", | 2278 | "file": "src/components/settings/services/ServicesDashboard.js", |
2027 | "id": "settings.services.deletedInfo", | 2279 | "id": "settings.services.deletedInfo", |
2028 | "start": { | 2280 | "start": { |
2029 | "column": 15, | 2281 | "column": 15, |
2030 | "line": 46 | 2282 | "line": 47 |
2031 | } | 2283 | } |
2032 | } | 2284 | } |
2033 | ], | 2285 | ], |
@@ -2441,220 +2693,339 @@ | |||
2441 | { | 2693 | { |
2442 | "descriptors": [ | 2694 | "descriptors": [ |
2443 | { | 2695 | { |
2444 | "defaultMessage": "!!!Support the development of Franz", | 2696 | "defaultMessage": "!!!Choose your plan", |
2445 | "end": { | 2697 | "end": { |
2446 | "column": 3, | 2698 | "column": 3, |
2699 | "line": 16 | ||
2700 | }, | ||
2701 | "file": "src/components/subscription/SubscriptionForm.js", | ||
2702 | "id": "subscription.cta.choosePlan", | ||
2703 | "start": { | ||
2704 | "column": 21, | ||
2705 | "line": 13 | ||
2706 | } | ||
2707 | }, | ||
2708 | { | ||
2709 | "defaultMessage": "!!!Upgrade your account and get the full Franz experience", | ||
2710 | "end": { | ||
2711 | "column": 3, | ||
2712 | "line": 20 | ||
2713 | }, | ||
2714 | "file": "src/components/subscription/SubscriptionForm.js", | ||
2715 | "id": "settings.account.headlineUpgradeAccount", | ||
2716 | "start": { | ||
2717 | "column": 18, | ||
2447 | "line": 17 | 2718 | "line": 17 |
2719 | } | ||
2720 | }, | ||
2721 | { | ||
2722 | "defaultMessage": "!!!Franz 5 comes with a wide range of new features to boost up your everyday communication - batteries included. Check out our new plans and find out which one suits you most!", | ||
2723 | "end": { | ||
2724 | "column": 3, | ||
2725 | "line": 24 | ||
2726 | }, | ||
2727 | "file": "src/components/subscription/SubscriptionForm.js", | ||
2728 | "id": "subscription.teaser.intro", | ||
2729 | "start": { | ||
2730 | "column": 14, | ||
2731 | "line": 21 | ||
2732 | } | ||
2733 | }, | ||
2734 | { | ||
2735 | "defaultMessage": "!!!Paid Franz Plans include:", | ||
2736 | "end": { | ||
2737 | "column": 3, | ||
2738 | "line": 28 | ||
2448 | }, | 2739 | }, |
2449 | "file": "src/components/subscription/SubscriptionForm.js", | 2740 | "file": "src/components/subscription/SubscriptionForm.js", |
2450 | "id": "subscription.submit.label", | 2741 | "id": "subscription.teaser.includedFeatures", |
2742 | "start": { | ||
2743 | "column": 20, | ||
2744 | "line": 25 | ||
2745 | } | ||
2746 | } | ||
2747 | ], | ||
2748 | "path": "src/components/subscription/SubscriptionForm.json" | ||
2749 | }, | ||
2750 | { | ||
2751 | "descriptors": [ | ||
2752 | { | ||
2753 | "defaultMessage": "!!!Cancel", | ||
2754 | "end": { | ||
2755 | "column": 3, | ||
2756 | "line": 14 | ||
2757 | }, | ||
2758 | "file": "src/components/subscription/SubscriptionPopup.js", | ||
2759 | "id": "subscriptionPopup.buttonCancel", | ||
2760 | "start": { | ||
2761 | "column": 16, | ||
2762 | "line": 11 | ||
2763 | } | ||
2764 | }, | ||
2765 | { | ||
2766 | "defaultMessage": "!!!Done", | ||
2767 | "end": { | ||
2768 | "column": 3, | ||
2769 | "line": 18 | ||
2770 | }, | ||
2771 | "file": "src/components/subscription/SubscriptionPopup.js", | ||
2772 | "id": "subscriptionPopup.buttonDone", | ||
2773 | "start": { | ||
2774 | "column": 14, | ||
2775 | "line": 15 | ||
2776 | } | ||
2777 | } | ||
2778 | ], | ||
2779 | "path": "src/components/subscription/SubscriptionPopup.json" | ||
2780 | }, | ||
2781 | { | ||
2782 | "descriptors": [ | ||
2783 | { | ||
2784 | "defaultMessage": "!!!Yes, start the free Franz Professional trial", | ||
2785 | "end": { | ||
2786 | "column": 3, | ||
2787 | "line": 17 | ||
2788 | }, | ||
2789 | "file": "src/components/subscription/TrialForm.js", | ||
2790 | "id": "subscription.cta.activateTrial", | ||
2451 | "start": { | 2791 | "start": { |
2452 | "column": 21, | 2792 | "column": 21, |
2453 | "line": 14 | 2793 | "line": 14 |
2454 | } | 2794 | } |
2455 | }, | 2795 | }, |
2456 | { | 2796 | { |
2457 | "defaultMessage": "!!!Could not initialize payment form", | 2797 | "defaultMessage": "!!!See all options", |
2458 | "end": { | 2798 | "end": { |
2459 | "column": 3, | 2799 | "column": 3, |
2460 | "line": 21 | 2800 | "line": 21 |
2461 | }, | 2801 | }, |
2462 | "file": "src/components/subscription/SubscriptionForm.js", | 2802 | "file": "src/components/subscription/TrialForm.js", |
2463 | "id": "subscription.paymentSessionError", | 2803 | "id": "subscription.cta.allOptions", |
2464 | "start": { | 2804 | "start": { |
2465 | "column": 23, | 2805 | "column": 20, |
2466 | "line": 18 | 2806 | "line": 18 |
2467 | } | 2807 | } |
2468 | }, | 2808 | }, |
2469 | { | 2809 | { |
2470 | "defaultMessage": "!!!free", | 2810 | "defaultMessage": "!!!Get the free 14 day Franz Professional Trial", |
2471 | "end": { | 2811 | "end": { |
2472 | "column": 3, | 2812 | "column": 3, |
2473 | "line": 25 | 2813 | "line": 25 |
2474 | }, | 2814 | }, |
2475 | "file": "src/components/subscription/SubscriptionForm.js", | 2815 | "file": "src/components/subscription/TrialForm.js", |
2476 | "id": "subscription.type.free", | 2816 | "id": "settings.account.headlineTrialUpgrade", |
2477 | "start": { | 2817 | "start": { |
2478 | "column": 12, | 2818 | "column": 18, |
2479 | "line": 22 | 2819 | "line": 22 |
2480 | } | 2820 | } |
2481 | }, | 2821 | }, |
2482 | { | 2822 | { |
2483 | "defaultMessage": "!!!month", | 2823 | "defaultMessage": "!!!The Franz Professional Plan includes:", |
2484 | "end": { | 2824 | "end": { |
2485 | "column": 3, | 2825 | "column": 3, |
2486 | "line": 29 | 2826 | "line": 29 |
2487 | }, | 2827 | }, |
2488 | "file": "src/components/subscription/SubscriptionForm.js", | 2828 | "file": "src/components/subscription/TrialForm.js", |
2489 | "id": "subscription.type.month", | 2829 | "id": "subscription.includedProFeatures", |
2490 | "start": { | 2830 | "start": { |
2491 | "column": 15, | 2831 | "column": 20, |
2492 | "line": 26 | 2832 | "line": 26 |
2493 | } | 2833 | } |
2494 | }, | 2834 | }, |
2495 | { | 2835 | { |
2496 | "defaultMessage": "!!!year", | 2836 | "defaultMessage": "!!!No strings attached", |
2497 | "end": { | 2837 | "end": { |
2498 | "column": 3, | 2838 | "column": 3, |
2499 | "line": 33 | 2839 | "line": 33 |
2500 | }, | 2840 | }, |
2501 | "file": "src/components/subscription/SubscriptionForm.js", | 2841 | "file": "src/components/subscription/TrialForm.js", |
2502 | "id": "subscription.type.year", | 2842 | "id": "pricing.trial.terms.headline", |
2503 | "start": { | 2843 | "start": { |
2504 | "column": 14, | 2844 | "column": 29, |
2505 | "line": 30 | 2845 | "line": 30 |
2506 | } | 2846 | } |
2507 | }, | 2847 | }, |
2508 | { | 2848 | { |
2509 | "defaultMessage": "!!!The Franz Premium Supporter Account includes", | 2849 | "defaultMessage": "!!!No credit card required", |
2510 | "end": { | 2850 | "end": { |
2511 | "column": 3, | 2851 | "column": 3, |
2512 | "line": 37 | 2852 | "line": 37 |
2513 | }, | 2853 | }, |
2514 | "file": "src/components/subscription/SubscriptionForm.js", | 2854 | "file": "src/components/subscription/TrialForm.js", |
2515 | "id": "subscription.includedFeatures", | 2855 | "id": "pricing.trial.terms.noCreditCard", |
2516 | "start": { | 2856 | "start": { |
2517 | "column": 20, | 2857 | "column": 16, |
2518 | "line": 34 | 2858 | "line": 34 |
2519 | } | 2859 | } |
2520 | }, | 2860 | }, |
2521 | { | 2861 | { |
2522 | "defaultMessage": "!!!Add on-premise/hosted services like Mattermost", | 2862 | "defaultMessage": "!!!Your free trial ends automatically after 14 days", |
2523 | "end": { | 2863 | "end": { |
2524 | "column": 3, | 2864 | "column": 3, |
2525 | "line": 41 | 2865 | "line": 41 |
2526 | }, | 2866 | }, |
2527 | "file": "src/components/subscription/SubscriptionForm.js", | 2867 | "file": "src/components/subscription/TrialForm.js", |
2528 | "id": "subscription.features.onpremise.mattermost", | 2868 | "id": "pricing.trial.terms.automaticTrialEnd", |
2529 | "start": { | 2869 | "start": { |
2530 | "column": 13, | 2870 | "column": 21, |
2531 | "line": 38 | 2871 | "line": 38 |
2532 | } | 2872 | } |
2533 | }, | 2873 | } |
2874 | ], | ||
2875 | "path": "src/components/subscription/TrialForm.json" | ||
2876 | }, | ||
2877 | { | ||
2878 | "descriptors": [ | ||
2534 | { | 2879 | { |
2535 | "defaultMessage": "!!!No app delays & nagging to upgrade license", | 2880 | "defaultMessage": "!!!Your trial was successfully activated. Happy messaging!", |
2536 | "end": { | 2881 | "end": { |
2537 | "column": 3, | 2882 | "column": 3, |
2538 | "line": 45 | 2883 | "line": 14 |
2539 | }, | 2884 | }, |
2540 | "file": "src/components/subscription/SubscriptionForm.js", | 2885 | "file": "src/components/TrialActivationInfoBar.js", |
2541 | "id": "subscription.features.noInterruptions", | 2886 | "id": "infobar.trialActivated", |
2542 | "start": { | 2887 | "start": { |
2543 | "column": 19, | 2888 | "column": 11, |
2544 | "line": 42 | 2889 | "line": 11 |
2545 | } | 2890 | } |
2546 | }, | 2891 | } |
2892 | ], | ||
2893 | "path": "src/components/TrialActivationInfoBar.json" | ||
2894 | }, | ||
2895 | { | ||
2896 | "descriptors": [ | ||
2547 | { | 2897 | { |
2548 | "defaultMessage": "!!!Proxy support for services", | 2898 | "defaultMessage": "!!!Add unlimited services", |
2549 | "end": { | 2899 | "end": { |
2550 | "column": 3, | 2900 | "column": 3, |
2551 | "line": 49 | 2901 | "line": 11 |
2552 | }, | 2902 | }, |
2553 | "file": "src/components/subscription/SubscriptionForm.js", | 2903 | "file": "src/components/ui/FeatureList.js", |
2554 | "id": "subscription.features.proxy", | 2904 | "id": "pricing.features.unlimitedServices", |
2555 | "start": { | 2905 | "start": { |
2556 | "column": 9, | 2906 | "column": 21, |
2557 | "line": 46 | 2907 | "line": 8 |
2558 | } | 2908 | } |
2559 | }, | 2909 | }, |
2560 | { | 2910 | { |
2561 | "defaultMessage": "!!!Support for Spellchecker", | 2911 | "defaultMessage": "!!!Spellchecker support", |
2562 | "end": { | 2912 | "end": { |
2563 | "column": 3, | 2913 | "column": 3, |
2564 | "line": 53 | 2914 | "line": 15 |
2565 | }, | 2915 | }, |
2566 | "file": "src/components/subscription/SubscriptionForm.js", | 2916 | "file": "src/components/ui/FeatureList.js", |
2567 | "id": "subscription.features.spellchecker", | 2917 | "id": "pricing.features.spellchecker", |
2568 | "start": { | 2918 | "start": { |
2569 | "column": 16, | 2919 | "column": 16, |
2570 | "line": 50 | 2920 | "line": 12 |
2571 | } | 2921 | } |
2572 | }, | 2922 | }, |
2573 | { | 2923 | { |
2574 | "defaultMessage": "!!!Organize your services in workspaces", | 2924 | "defaultMessage": "!!!Workspaces", |
2575 | "end": { | 2925 | "end": { |
2576 | "column": 3, | 2926 | "column": 3, |
2577 | "line": 57 | 2927 | "line": 19 |
2578 | }, | 2928 | }, |
2579 | "file": "src/components/subscription/SubscriptionForm.js", | 2929 | "file": "src/components/ui/FeatureList.js", |
2580 | "id": "subscription.features.workspaces", | 2930 | "id": "pricing.features.workspaces", |
2581 | "start": { | 2931 | "start": { |
2582 | "column": 14, | 2932 | "column": 14, |
2583 | "line": 54 | 2933 | "line": 16 |
2584 | } | 2934 | } |
2585 | }, | 2935 | }, |
2586 | { | 2936 | { |
2587 | "defaultMessage": "!!!No ads, ever!", | 2937 | "defaultMessage": "!!!Add Custom Websites", |
2588 | "end": { | 2938 | "end": { |
2589 | "column": 3, | 2939 | "column": 3, |
2590 | "line": 61 | 2940 | "line": 23 |
2591 | }, | 2941 | }, |
2592 | "file": "src/components/subscription/SubscriptionForm.js", | 2942 | "file": "src/components/ui/FeatureList.js", |
2593 | "id": "subscription.features.ads", | 2943 | "id": "pricing.features.customWebsites", |
2594 | "start": { | 2944 | "start": { |
2595 | "column": 7, | 2945 | "column": 18, |
2596 | "line": 58 | 2946 | "line": 20 |
2597 | } | 2947 | } |
2598 | }, | 2948 | }, |
2599 | { | 2949 | { |
2600 | "defaultMessage": "!!!coming soon", | 2950 | "defaultMessage": "!!!On-premise & other Hosted Services", |
2601 | "end": { | 2951 | "end": { |
2602 | "column": 3, | 2952 | "column": 3, |
2603 | "line": 65 | 2953 | "line": 27 |
2604 | }, | 2954 | }, |
2605 | "file": "src/components/subscription/SubscriptionForm.js", | 2955 | "file": "src/components/ui/FeatureList.js", |
2606 | "id": "subscription.features.comingSoon", | 2956 | "id": "pricing.features.onPremise", |
2607 | "start": { | 2957 | "start": { |
2608 | "column": 14, | 2958 | "column": 13, |
2609 | "line": 62 | 2959 | "line": 24 |
2610 | } | 2960 | } |
2611 | }, | 2961 | }, |
2612 | { | 2962 | { |
2613 | "defaultMessage": "!!!EU residents: local sales tax may apply", | 2963 | "defaultMessage": "!!!Install 3rd party services", |
2614 | "end": { | 2964 | "end": { |
2615 | "column": 3, | 2965 | "column": 3, |
2616 | "line": 69 | 2966 | "line": 31 |
2617 | }, | 2967 | }, |
2618 | "file": "src/components/subscription/SubscriptionForm.js", | 2968 | "file": "src/components/ui/FeatureList.js", |
2619 | "id": "subscription.euTaxInfo", | 2969 | "id": "pricing.features.thirdPartyServices", |
2620 | "start": { | 2970 | "start": { |
2621 | "column": 13, | 2971 | "column": 22, |
2622 | "line": 66 | 2972 | "line": 28 |
2623 | } | 2973 | } |
2624 | } | 2974 | }, |
2625 | ], | ||
2626 | "path": "src/components/subscription/SubscriptionForm.json" | ||
2627 | }, | ||
2628 | { | ||
2629 | "descriptors": [ | ||
2630 | { | 2975 | { |
2631 | "defaultMessage": "!!!Cancel", | 2976 | "defaultMessage": "!!!Service Proxies", |
2632 | "end": { | 2977 | "end": { |
2633 | "column": 3, | 2978 | "column": 3, |
2634 | "line": 14 | 2979 | "line": 35 |
2635 | }, | 2980 | }, |
2636 | "file": "src/components/subscription/SubscriptionPopup.js", | 2981 | "file": "src/components/ui/FeatureList.js", |
2637 | "id": "subscriptionPopup.buttonCancel", | 2982 | "id": "pricing.features.serviceProxies", |
2638 | "start": { | 2983 | "start": { |
2639 | "column": 16, | 2984 | "column": 18, |
2640 | "line": 11 | 2985 | "line": 32 |
2641 | } | 2986 | } |
2642 | }, | 2987 | }, |
2643 | { | 2988 | { |
2644 | "defaultMessage": "!!!Done", | 2989 | "defaultMessage": "!!!Team Management", |
2645 | "end": { | 2990 | "end": { |
2646 | "column": 3, | 2991 | "column": 3, |
2647 | "line": 18 | 2992 | "line": 39 |
2648 | }, | 2993 | }, |
2649 | "file": "src/components/subscription/SubscriptionPopup.js", | 2994 | "file": "src/components/ui/FeatureList.js", |
2650 | "id": "subscriptionPopup.buttonDone", | 2995 | "id": "pricing.features.teamManagement", |
2651 | "start": { | 2996 | "start": { |
2652 | "column": 14, | 2997 | "column": 18, |
2653 | "line": 15 | 2998 | "line": 36 |
2999 | } | ||
3000 | }, | ||
3001 | { | ||
3002 | "defaultMessage": "!!!No Waiting Screens", | ||
3003 | "end": { | ||
3004 | "column": 3, | ||
3005 | "line": 43 | ||
3006 | }, | ||
3007 | "file": "src/components/ui/FeatureList.js", | ||
3008 | "id": "pricing.features.appDelays", | ||
3009 | "start": { | ||
3010 | "column": 13, | ||
3011 | "line": 40 | ||
3012 | } | ||
3013 | }, | ||
3014 | { | ||
3015 | "defaultMessage": "!!!Forever ad-free", | ||
3016 | "end": { | ||
3017 | "column": 3, | ||
3018 | "line": 47 | ||
3019 | }, | ||
3020 | "file": "src/components/ui/FeatureList.js", | ||
3021 | "id": "pricing.features.adFree", | ||
3022 | "start": { | ||
3023 | "column": 10, | ||
3024 | "line": 44 | ||
2654 | } | 3025 | } |
2655 | } | 3026 | } |
2656 | ], | 3027 | ], |
2657 | "path": "src/components/subscription/SubscriptionPopup.json" | 3028 | "path": "src/components/ui/FeatureList.json" |
2658 | }, | 3029 | }, |
2659 | { | 3030 | { |
2660 | "descriptors": [ | 3031 | "descriptors": [ |
@@ -3230,39 +3601,65 @@ | |||
3230 | "defaultMessage": "!!!Please purchase license to skip waiting", | 3601 | "defaultMessage": "!!!Please purchase license to skip waiting", |
3231 | "end": { | 3602 | "end": { |
3232 | "column": 3, | 3603 | "column": 3, |
3233 | "line": 18 | 3604 | "line": 20 |
3234 | }, | 3605 | }, |
3235 | "file": "src/features/delayApp/Component.js", | 3606 | "file": "src/features/delayApp/Component.js", |
3236 | "id": "feature.delayApp.headline", | 3607 | "id": "feature.delayApp.headline", |
3237 | "start": { | 3608 | "start": { |
3238 | "column": 12, | 3609 | "column": 12, |
3239 | "line": 15 | 3610 | "line": 17 |
3611 | } | ||
3612 | }, | ||
3613 | { | ||
3614 | "defaultMessage": "!!!Get the free Franz Professional 14 day trial and skip the line", | ||
3615 | "end": { | ||
3616 | "column": 3, | ||
3617 | "line": 24 | ||
3618 | }, | ||
3619 | "file": "src/features/delayApp/Component.js", | ||
3620 | "id": "feature.delayApp.trial.headline", | ||
3621 | "start": { | ||
3622 | "column": 17, | ||
3623 | "line": 21 | ||
3240 | } | 3624 | } |
3241 | }, | 3625 | }, |
3242 | { | 3626 | { |
3243 | "defaultMessage": "!!!Get a Franz Supporter License", | 3627 | "defaultMessage": "!!!Get a Franz Supporter License", |
3244 | "end": { | 3628 | "end": { |
3245 | "column": 3, | 3629 | "column": 3, |
3246 | "line": 22 | 3630 | "line": 28 |
3247 | }, | 3631 | }, |
3248 | "file": "src/features/delayApp/Component.js", | 3632 | "file": "src/features/delayApp/Component.js", |
3249 | "id": "feature.delayApp.action", | 3633 | "id": "feature.delayApp.upgrade.action", |
3250 | "start": { | 3634 | "start": { |
3251 | "column": 10, | 3635 | "column": 10, |
3252 | "line": 19 | 3636 | "line": 25 |
3637 | } | ||
3638 | }, | ||
3639 | { | ||
3640 | "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", | ||
3641 | "end": { | ||
3642 | "column": 3, | ||
3643 | "line": 32 | ||
3644 | }, | ||
3645 | "file": "src/features/delayApp/Component.js", | ||
3646 | "id": "feature.delayApp.trial.action", | ||
3647 | "start": { | ||
3648 | "column": 15, | ||
3649 | "line": 29 | ||
3253 | } | 3650 | } |
3254 | }, | 3651 | }, |
3255 | { | 3652 | { |
3256 | "defaultMessage": "!!!Franz will continue in {seconds} seconds.", | 3653 | "defaultMessage": "!!!Franz will continue in {seconds} seconds.", |
3257 | "end": { | 3654 | "end": { |
3258 | "column": 3, | 3655 | "column": 3, |
3259 | "line": 26 | 3656 | "line": 36 |
3260 | }, | 3657 | }, |
3261 | "file": "src/features/delayApp/Component.js", | 3658 | "file": "src/features/delayApp/Component.js", |
3262 | "id": "feature.delayApp.text", | 3659 | "id": "feature.delayApp.text", |
3263 | "start": { | 3660 | "start": { |
3264 | "column": 8, | 3661 | "column": 8, |
3265 | "line": 23 | 3662 | "line": 33 |
3266 | } | 3663 | } |
3267 | } | 3664 | } |
3268 | ], | 3665 | ], |
@@ -3271,94 +3668,143 @@ | |||
3271 | { | 3668 | { |
3272 | "descriptors": [ | 3669 | "descriptors": [ |
3273 | { | 3670 | { |
3274 | "defaultMessage": "!!!Franz is better together!", | 3671 | "defaultMessage": "!!!Changes in Franz {version}", |
3672 | "end": { | ||
3673 | "column": 3, | ||
3674 | "line": 23 | ||
3675 | }, | ||
3676 | "file": "src/features/serviceLimit/components/AnnouncementScreen.js", | ||
3677 | "id": "feature.announcements.changelog.headline", | ||
3678 | "start": { | ||
3679 | "column": 12, | ||
3680 | "line": 20 | ||
3681 | } | ||
3682 | } | ||
3683 | ], | ||
3684 | "path": "src/features/serviceLimit/components/AnnouncementScreen.json" | ||
3685 | }, | ||
3686 | { | ||
3687 | "descriptors": [ | ||
3688 | { | ||
3689 | "defaultMessage": "!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.", | ||
3690 | "end": { | ||
3691 | "column": 3, | ||
3692 | "line": 14 | ||
3693 | }, | ||
3694 | "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", | ||
3695 | "id": "feature.serviceLimit.limitReached", | ||
3696 | "start": { | ||
3697 | "column": 16, | ||
3698 | "line": 11 | ||
3699 | } | ||
3700 | }, | ||
3701 | { | ||
3702 | "defaultMessage": "!!!Upgrade account", | ||
3275 | "end": { | 3703 | "end": { |
3276 | "column": 3, | 3704 | "column": 3, |
3277 | "line": 18 | 3705 | "line": 18 |
3278 | }, | 3706 | }, |
3707 | "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", | ||
3708 | "id": "premiumFeature.button.upgradeAccount", | ||
3709 | "start": { | ||
3710 | "column": 10, | ||
3711 | "line": 15 | ||
3712 | } | ||
3713 | } | ||
3714 | ], | ||
3715 | "path": "src/features/serviceLimit/components/LimitReachedInfobox.json" | ||
3716 | }, | ||
3717 | { | ||
3718 | "descriptors": [ | ||
3719 | { | ||
3720 | "defaultMessage": "!!!Franz is better together!", | ||
3721 | "end": { | ||
3722 | "column": 3, | ||
3723 | "line": 19 | ||
3724 | }, | ||
3279 | "file": "src/features/shareFranz/Component.js", | 3725 | "file": "src/features/shareFranz/Component.js", |
3280 | "id": "feature.shareFranz.headline", | 3726 | "id": "feature.shareFranz.headline", |
3281 | "start": { | 3727 | "start": { |
3282 | "column": 12, | 3728 | "column": 12, |
3283 | "line": 15 | 3729 | "line": 16 |
3284 | } | 3730 | } |
3285 | }, | 3731 | }, |
3286 | { | 3732 | { |
3287 | "defaultMessage": "!!!Tell your friends and colleagues how awesome Franz is and help us to spread the word.", | 3733 | "defaultMessage": "!!!Tell your friends and colleagues how awesome Franz is and help us to spread the word.", |
3288 | "end": { | 3734 | "end": { |
3289 | "column": 3, | 3735 | "column": 3, |
3290 | "line": 22 | 3736 | "line": 23 |
3291 | }, | 3737 | }, |
3292 | "file": "src/features/shareFranz/Component.js", | 3738 | "file": "src/features/shareFranz/Component.js", |
3293 | "id": "feature.shareFranz.text", | 3739 | "id": "feature.shareFranz.text", |
3294 | "start": { | 3740 | "start": { |
3295 | "column": 8, | 3741 | "column": 8, |
3296 | "line": 19 | 3742 | "line": 20 |
3297 | } | 3743 | } |
3298 | }, | 3744 | }, |
3299 | { | 3745 | { |
3300 | "defaultMessage": "!!!Share as email", | 3746 | "defaultMessage": "!!!Share as email", |
3301 | "end": { | 3747 | "end": { |
3302 | "column": 3, | 3748 | "column": 3, |
3303 | "line": 26 | 3749 | "line": 27 |
3304 | }, | 3750 | }, |
3305 | "file": "src/features/shareFranz/Component.js", | 3751 | "file": "src/features/shareFranz/Component.js", |
3306 | "id": "feature.shareFranz.action.email", | 3752 | "id": "feature.shareFranz.action.email", |
3307 | "start": { | 3753 | "start": { |
3308 | "column": 16, | 3754 | "column": 16, |
3309 | "line": 23 | 3755 | "line": 24 |
3310 | } | 3756 | } |
3311 | }, | 3757 | }, |
3312 | { | 3758 | { |
3313 | "defaultMessage": "!!!Share on Facebook", | 3759 | "defaultMessage": "!!!Share on Facebook", |
3314 | "end": { | 3760 | "end": { |
3315 | "column": 3, | 3761 | "column": 3, |
3316 | "line": 30 | 3762 | "line": 31 |
3317 | }, | 3763 | }, |
3318 | "file": "src/features/shareFranz/Component.js", | 3764 | "file": "src/features/shareFranz/Component.js", |
3319 | "id": "feature.shareFranz.action.facebook", | 3765 | "id": "feature.shareFranz.action.facebook", |
3320 | "start": { | 3766 | "start": { |
3321 | "column": 19, | 3767 | "column": 19, |
3322 | "line": 27 | 3768 | "line": 28 |
3323 | } | 3769 | } |
3324 | }, | 3770 | }, |
3325 | { | 3771 | { |
3326 | "defaultMessage": "!!!Share on Twitter", | 3772 | "defaultMessage": "!!!Share on Twitter", |
3327 | "end": { | 3773 | "end": { |
3328 | "column": 3, | 3774 | "column": 3, |
3329 | "line": 34 | 3775 | "line": 35 |
3330 | }, | 3776 | }, |
3331 | "file": "src/features/shareFranz/Component.js", | 3777 | "file": "src/features/shareFranz/Component.js", |
3332 | "id": "feature.shareFranz.action.twitter", | 3778 | "id": "feature.shareFranz.action.twitter", |
3333 | "start": { | 3779 | "start": { |
3334 | "column": 18, | 3780 | "column": 18, |
3335 | "line": 31 | 3781 | "line": 32 |
3336 | } | 3782 | } |
3337 | }, | 3783 | }, |
3338 | { | 3784 | { |
3339 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", | 3785 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", |
3340 | "end": { | 3786 | "end": { |
3341 | "column": 3, | 3787 | "column": 3, |
3342 | "line": 38 | 3788 | "line": 39 |
3343 | }, | 3789 | }, |
3344 | "file": "src/features/shareFranz/Component.js", | 3790 | "file": "src/features/shareFranz/Component.js", |
3345 | "id": "feature.shareFranz.shareText.email", | 3791 | "id": "feature.shareFranz.shareText.email", |
3346 | "start": { | 3792 | "start": { |
3347 | "column": 18, | 3793 | "column": 18, |
3348 | "line": 35 | 3794 | "line": 36 |
3349 | } | 3795 | } |
3350 | }, | 3796 | }, |
3351 | { | 3797 | { |
3352 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", | 3798 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", |
3353 | "end": { | 3799 | "end": { |
3354 | "column": 3, | 3800 | "column": 3, |
3355 | "line": 42 | 3801 | "line": 43 |
3356 | }, | 3802 | }, |
3357 | "file": "src/features/shareFranz/Component.js", | 3803 | "file": "src/features/shareFranz/Component.js", |
3358 | "id": "feature.shareFranz.shareText.twitter", | 3804 | "id": "feature.shareFranz.shareText.twitter", |
3359 | "start": { | 3805 | "start": { |
3360 | "column": 20, | 3806 | "column": 20, |
3361 | "line": 39 | 3807 | "line": 40 |
3362 | } | 3808 | } |
3363 | } | 3809 | } |
3364 | ], | 3810 | ], |
@@ -3761,6 +4207,146 @@ | |||
3761 | { | 4207 | { |
3762 | "descriptors": [ | 4208 | "descriptors": [ |
3763 | { | 4209 | { |
4210 | "defaultMessage": "!!!Franz Professional", | ||
4211 | "end": { | ||
4212 | "column": 3, | ||
4213 | "line": 8 | ||
4214 | }, | ||
4215 | "file": "src/helpers/plan-helpers.js", | ||
4216 | "id": "pricing.plan.pro", | ||
4217 | "start": { | ||
4218 | "column": 15, | ||
4219 | "line": 5 | ||
4220 | } | ||
4221 | }, | ||
4222 | { | ||
4223 | "defaultMessage": "!!!Franz Personal", | ||
4224 | "end": { | ||
4225 | "column": 3, | ||
4226 | "line": 12 | ||
4227 | }, | ||
4228 | "file": "src/helpers/plan-helpers.js", | ||
4229 | "id": "pricing.plan.personal", | ||
4230 | "start": { | ||
4231 | "column": 20, | ||
4232 | "line": 9 | ||
4233 | } | ||
4234 | }, | ||
4235 | { | ||
4236 | "defaultMessage": "!!!Franz Free", | ||
4237 | "end": { | ||
4238 | "column": 3, | ||
4239 | "line": 16 | ||
4240 | }, | ||
4241 | "file": "src/helpers/plan-helpers.js", | ||
4242 | "id": "pricing.plan.free", | ||
4243 | "start": { | ||
4244 | "column": 16, | ||
4245 | "line": 13 | ||
4246 | } | ||
4247 | }, | ||
4248 | { | ||
4249 | "defaultMessage": "!!!Franz Premium", | ||
4250 | "end": { | ||
4251 | "column": 3, | ||
4252 | "line": 20 | ||
4253 | }, | ||
4254 | "file": "src/helpers/plan-helpers.js", | ||
4255 | "id": "pricing.plan.legacy", | ||
4256 | "start": { | ||
4257 | "column": 18, | ||
4258 | "line": 17 | ||
4259 | } | ||
4260 | } | ||
4261 | ], | ||
4262 | "path": "src/helpers/plan-helpers.json" | ||
4263 | }, | ||
4264 | { | ||
4265 | "descriptors": [ | ||
4266 | { | ||
4267 | "defaultMessage": "!!!Franz Professional Yearly", | ||
4268 | "end": { | ||
4269 | "column": 3, | ||
4270 | "line": 8 | ||
4271 | }, | ||
4272 | "file": "src/helpers/pricing-helpers.js", | ||
4273 | "id": "pricing.plan.pro-yearly", | ||
4274 | "start": { | ||
4275 | "column": 22, | ||
4276 | "line": 5 | ||
4277 | } | ||
4278 | }, | ||
4279 | { | ||
4280 | "defaultMessage": "!!!Franz Professional Monthly", | ||
4281 | "end": { | ||
4282 | "column": 3, | ||
4283 | "line": 12 | ||
4284 | }, | ||
4285 | "file": "src/helpers/pricing-helpers.js", | ||
4286 | "id": "pricing.plan.pro-monthly", | ||
4287 | "start": { | ||
4288 | "column": 23, | ||
4289 | "line": 9 | ||
4290 | } | ||
4291 | }, | ||
4292 | { | ||
4293 | "defaultMessage": "!!!Franz Personal Yearly", | ||
4294 | "end": { | ||
4295 | "column": 3, | ||
4296 | "line": 16 | ||
4297 | }, | ||
4298 | "file": "src/helpers/pricing-helpers.js", | ||
4299 | "id": "pricing.plan.personal-yearly", | ||
4300 | "start": { | ||
4301 | "column": 27, | ||
4302 | "line": 13 | ||
4303 | } | ||
4304 | }, | ||
4305 | { | ||
4306 | "defaultMessage": "!!!Franz Personal Monthly", | ||
4307 | "end": { | ||
4308 | "column": 3, | ||
4309 | "line": 20 | ||
4310 | }, | ||
4311 | "file": "src/helpers/pricing-helpers.js", | ||
4312 | "id": "pricing.plan.personal-monthly", | ||
4313 | "start": { | ||
4314 | "column": 28, | ||
4315 | "line": 17 | ||
4316 | } | ||
4317 | }, | ||
4318 | { | ||
4319 | "defaultMessage": "!!!Franz Free", | ||
4320 | "end": { | ||
4321 | "column": 3, | ||
4322 | "line": 24 | ||
4323 | }, | ||
4324 | "file": "src/helpers/pricing-helpers.js", | ||
4325 | "id": "pricing.plan.free", | ||
4326 | "start": { | ||
4327 | "column": 16, | ||
4328 | "line": 21 | ||
4329 | } | ||
4330 | }, | ||
4331 | { | ||
4332 | "defaultMessage": "!!!Franz Premium", | ||
4333 | "end": { | ||
4334 | "column": 3, | ||
4335 | "line": 28 | ||
4336 | }, | ||
4337 | "file": "src/helpers/pricing-helpers.js", | ||
4338 | "id": "pricing.plan.legacy", | ||
4339 | "start": { | ||
4340 | "column": 18, | ||
4341 | "line": 25 | ||
4342 | } | ||
4343 | } | ||
4344 | ], | ||
4345 | "path": "src/helpers/pricing-helpers.json" | ||
4346 | }, | ||
4347 | { | ||
4348 | "descriptors": [ | ||
4349 | { | ||
3764 | "defaultMessage": "!!!Field is required", | 4350 | "defaultMessage": "!!!Field is required", |
3765 | "end": { | 4351 | "end": { |
3766 | "column": 3, | 4352 | "column": 3, |
@@ -3917,702 +4503,793 @@ | |||
3917 | "defaultMessage": "!!!Edit", | 4503 | "defaultMessage": "!!!Edit", |
3918 | "end": { | 4504 | "end": { |
3919 | "column": 3, | 4505 | "column": 3, |
3920 | "line": 18 | 4506 | "line": 21 |
3921 | }, | 4507 | }, |
3922 | "file": "src/lib/Menu.js", | 4508 | "file": "src/lib/Menu.js", |
3923 | "id": "menu.edit", | 4509 | "id": "menu.edit", |
3924 | "start": { | 4510 | "start": { |
3925 | "column": 8, | 4511 | "column": 8, |
3926 | "line": 15 | 4512 | "line": 18 |
3927 | } | 4513 | } |
3928 | }, | 4514 | }, |
3929 | { | 4515 | { |
3930 | "defaultMessage": "!!!Undo", | 4516 | "defaultMessage": "!!!Undo", |
3931 | "end": { | 4517 | "end": { |
3932 | "column": 3, | 4518 | "column": 3, |
3933 | "line": 22 | 4519 | "line": 25 |
3934 | }, | 4520 | }, |
3935 | "file": "src/lib/Menu.js", | 4521 | "file": "src/lib/Menu.js", |
3936 | "id": "menu.edit.undo", | 4522 | "id": "menu.edit.undo", |
3937 | "start": { | 4523 | "start": { |
3938 | "column": 8, | 4524 | "column": 8, |
3939 | "line": 19 | 4525 | "line": 22 |
3940 | } | 4526 | } |
3941 | }, | 4527 | }, |
3942 | { | 4528 | { |
3943 | "defaultMessage": "!!!Redo", | 4529 | "defaultMessage": "!!!Redo", |
3944 | "end": { | 4530 | "end": { |
3945 | "column": 3, | 4531 | "column": 3, |
3946 | "line": 26 | 4532 | "line": 29 |
3947 | }, | 4533 | }, |
3948 | "file": "src/lib/Menu.js", | 4534 | "file": "src/lib/Menu.js", |
3949 | "id": "menu.edit.redo", | 4535 | "id": "menu.edit.redo", |
3950 | "start": { | 4536 | "start": { |
3951 | "column": 8, | 4537 | "column": 8, |
3952 | "line": 23 | 4538 | "line": 26 |
3953 | } | 4539 | } |
3954 | }, | 4540 | }, |
3955 | { | 4541 | { |
3956 | "defaultMessage": "!!!Cut", | 4542 | "defaultMessage": "!!!Cut", |
3957 | "end": { | 4543 | "end": { |
3958 | "column": 3, | 4544 | "column": 3, |
3959 | "line": 30 | 4545 | "line": 33 |
3960 | }, | 4546 | }, |
3961 | "file": "src/lib/Menu.js", | 4547 | "file": "src/lib/Menu.js", |
3962 | "id": "menu.edit.cut", | 4548 | "id": "menu.edit.cut", |
3963 | "start": { | 4549 | "start": { |
3964 | "column": 7, | 4550 | "column": 7, |
3965 | "line": 27 | 4551 | "line": 30 |
3966 | } | 4552 | } |
3967 | }, | 4553 | }, |
3968 | { | 4554 | { |
3969 | "defaultMessage": "!!!Copy", | 4555 | "defaultMessage": "!!!Copy", |
3970 | "end": { | 4556 | "end": { |
3971 | "column": 3, | 4557 | "column": 3, |
3972 | "line": 34 | 4558 | "line": 37 |
3973 | }, | 4559 | }, |
3974 | "file": "src/lib/Menu.js", | 4560 | "file": "src/lib/Menu.js", |
3975 | "id": "menu.edit.copy", | 4561 | "id": "menu.edit.copy", |
3976 | "start": { | 4562 | "start": { |
3977 | "column": 8, | 4563 | "column": 8, |
3978 | "line": 31 | 4564 | "line": 34 |
3979 | } | 4565 | } |
3980 | }, | 4566 | }, |
3981 | { | 4567 | { |
3982 | "defaultMessage": "!!!Paste", | 4568 | "defaultMessage": "!!!Paste", |
3983 | "end": { | 4569 | "end": { |
3984 | "column": 3, | 4570 | "column": 3, |
3985 | "line": 38 | 4571 | "line": 41 |
3986 | }, | 4572 | }, |
3987 | "file": "src/lib/Menu.js", | 4573 | "file": "src/lib/Menu.js", |
3988 | "id": "menu.edit.paste", | 4574 | "id": "menu.edit.paste", |
3989 | "start": { | 4575 | "start": { |
3990 | "column": 9, | 4576 | "column": 9, |
3991 | "line": 35 | 4577 | "line": 38 |
3992 | } | 4578 | } |
3993 | }, | 4579 | }, |
3994 | { | 4580 | { |
3995 | "defaultMessage": "!!!Paste And Match Style", | 4581 | "defaultMessage": "!!!Paste And Match Style", |
3996 | "end": { | 4582 | "end": { |
3997 | "column": 3, | 4583 | "column": 3, |
3998 | "line": 42 | 4584 | "line": 45 |
3999 | }, | 4585 | }, |
4000 | "file": "src/lib/Menu.js", | 4586 | "file": "src/lib/Menu.js", |
4001 | "id": "menu.edit.pasteAndMatchStyle", | 4587 | "id": "menu.edit.pasteAndMatchStyle", |
4002 | "start": { | 4588 | "start": { |
4003 | "column": 22, | 4589 | "column": 22, |
4004 | "line": 39 | 4590 | "line": 42 |
4005 | } | 4591 | } |
4006 | }, | 4592 | }, |
4007 | { | 4593 | { |
4008 | "defaultMessage": "!!!Delete", | 4594 | "defaultMessage": "!!!Delete", |
4009 | "end": { | 4595 | "end": { |
4010 | "column": 3, | 4596 | "column": 3, |
4011 | "line": 46 | 4597 | "line": 49 |
4012 | }, | 4598 | }, |
4013 | "file": "src/lib/Menu.js", | 4599 | "file": "src/lib/Menu.js", |
4014 | "id": "menu.edit.delete", | 4600 | "id": "menu.edit.delete", |
4015 | "start": { | 4601 | "start": { |
4016 | "column": 10, | 4602 | "column": 10, |
4017 | "line": 43 | 4603 | "line": 46 |
4018 | } | 4604 | } |
4019 | }, | 4605 | }, |
4020 | { | 4606 | { |
4021 | "defaultMessage": "!!!Select All", | 4607 | "defaultMessage": "!!!Select All", |
4022 | "end": { | 4608 | "end": { |
4023 | "column": 3, | 4609 | "column": 3, |
4024 | "line": 50 | 4610 | "line": 53 |
4025 | }, | 4611 | }, |
4026 | "file": "src/lib/Menu.js", | 4612 | "file": "src/lib/Menu.js", |
4027 | "id": "menu.edit.selectAll", | 4613 | "id": "menu.edit.selectAll", |
4028 | "start": { | 4614 | "start": { |
4029 | "column": 13, | 4615 | "column": 13, |
4030 | "line": 47 | 4616 | "line": 50 |
4031 | } | 4617 | } |
4032 | }, | 4618 | }, |
4033 | { | 4619 | { |
4034 | "defaultMessage": "!!!Speech", | 4620 | "defaultMessage": "!!!Speech", |
4035 | "end": { | 4621 | "end": { |
4036 | "column": 3, | 4622 | "column": 3, |
4037 | "line": 54 | 4623 | "line": 57 |
4038 | }, | 4624 | }, |
4039 | "file": "src/lib/Menu.js", | 4625 | "file": "src/lib/Menu.js", |
4040 | "id": "menu.edit.speech", | 4626 | "id": "menu.edit.speech", |
4041 | "start": { | 4627 | "start": { |
4042 | "column": 10, | 4628 | "column": 10, |
4043 | "line": 51 | 4629 | "line": 54 |
4044 | } | 4630 | } |
4045 | }, | 4631 | }, |
4046 | { | 4632 | { |
4047 | "defaultMessage": "!!!Start Speaking", | 4633 | "defaultMessage": "!!!Start Speaking", |
4048 | "end": { | 4634 | "end": { |
4049 | "column": 3, | 4635 | "column": 3, |
4050 | "line": 58 | 4636 | "line": 61 |
4051 | }, | 4637 | }, |
4052 | "file": "src/lib/Menu.js", | 4638 | "file": "src/lib/Menu.js", |
4053 | "id": "menu.edit.startSpeaking", | 4639 | "id": "menu.edit.startSpeaking", |
4054 | "start": { | 4640 | "start": { |
4055 | "column": 17, | 4641 | "column": 17, |
4056 | "line": 55 | 4642 | "line": 58 |
4057 | } | 4643 | } |
4058 | }, | 4644 | }, |
4059 | { | 4645 | { |
4060 | "defaultMessage": "!!!Stop Speaking", | 4646 | "defaultMessage": "!!!Stop Speaking", |
4061 | "end": { | 4647 | "end": { |
4062 | "column": 3, | 4648 | "column": 3, |
4063 | "line": 62 | 4649 | "line": 65 |
4064 | }, | 4650 | }, |
4065 | "file": "src/lib/Menu.js", | 4651 | "file": "src/lib/Menu.js", |
4066 | "id": "menu.edit.stopSpeaking", | 4652 | "id": "menu.edit.stopSpeaking", |
4067 | "start": { | 4653 | "start": { |
4068 | "column": 16, | 4654 | "column": 16, |
4069 | "line": 59 | 4655 | "line": 62 |
4070 | } | 4656 | } |
4071 | }, | 4657 | }, |
4072 | { | 4658 | { |
4073 | "defaultMessage": "!!!Start Dictation", | 4659 | "defaultMessage": "!!!Start Dictation", |
4074 | "end": { | 4660 | "end": { |
4075 | "column": 3, | 4661 | "column": 3, |
4076 | "line": 66 | 4662 | "line": 69 |
4077 | }, | 4663 | }, |
4078 | "file": "src/lib/Menu.js", | 4664 | "file": "src/lib/Menu.js", |
4079 | "id": "menu.edit.startDictation", | 4665 | "id": "menu.edit.startDictation", |
4080 | "start": { | 4666 | "start": { |
4081 | "column": 18, | 4667 | "column": 18, |
4082 | "line": 63 | 4668 | "line": 66 |
4083 | } | 4669 | } |
4084 | }, | 4670 | }, |
4085 | { | 4671 | { |
4086 | "defaultMessage": "!!!Emoji & Symbols", | 4672 | "defaultMessage": "!!!Emoji & Symbols", |
4087 | "end": { | 4673 | "end": { |
4088 | "column": 3, | 4674 | "column": 3, |
4089 | "line": 70 | 4675 | "line": 73 |
4090 | }, | 4676 | }, |
4091 | "file": "src/lib/Menu.js", | 4677 | "file": "src/lib/Menu.js", |
4092 | "id": "menu.edit.emojiSymbols", | 4678 | "id": "menu.edit.emojiSymbols", |
4093 | "start": { | 4679 | "start": { |
4094 | "column": 16, | 4680 | "column": 16, |
4095 | "line": 67 | 4681 | "line": 70 |
4096 | } | 4682 | } |
4097 | }, | 4683 | }, |
4098 | { | 4684 | { |
4099 | "defaultMessage": "!!!Actual Size", | 4685 | "defaultMessage": "!!!Actual Size", |
4100 | "end": { | 4686 | "end": { |
4101 | "column": 3, | 4687 | "column": 3, |
4102 | "line": 74 | 4688 | "line": 77 |
4103 | }, | 4689 | }, |
4104 | "file": "src/lib/Menu.js", | 4690 | "file": "src/lib/Menu.js", |
4105 | "id": "menu.view.resetZoom", | 4691 | "id": "menu.view.resetZoom", |
4106 | "start": { | 4692 | "start": { |
4107 | "column": 13, | 4693 | "column": 13, |
4108 | "line": 71 | 4694 | "line": 74 |
4109 | } | 4695 | } |
4110 | }, | 4696 | }, |
4111 | { | 4697 | { |
4112 | "defaultMessage": "!!!Zoom In", | 4698 | "defaultMessage": "!!!Zoom In", |
4113 | "end": { | 4699 | "end": { |
4114 | "column": 3, | 4700 | "column": 3, |
4115 | "line": 78 | 4701 | "line": 81 |
4116 | }, | 4702 | }, |
4117 | "file": "src/lib/Menu.js", | 4703 | "file": "src/lib/Menu.js", |
4118 | "id": "menu.view.zoomIn", | 4704 | "id": "menu.view.zoomIn", |
4119 | "start": { | 4705 | "start": { |
4120 | "column": 10, | 4706 | "column": 10, |
4121 | "line": 75 | 4707 | "line": 78 |
4122 | } | 4708 | } |
4123 | }, | 4709 | }, |
4124 | { | 4710 | { |
4125 | "defaultMessage": "!!!Zoom Out", | 4711 | "defaultMessage": "!!!Zoom Out", |
4126 | "end": { | 4712 | "end": { |
4127 | "column": 3, | 4713 | "column": 3, |
4128 | "line": 82 | 4714 | "line": 85 |
4129 | }, | 4715 | }, |
4130 | "file": "src/lib/Menu.js", | 4716 | "file": "src/lib/Menu.js", |
4131 | "id": "menu.view.zoomOut", | 4717 | "id": "menu.view.zoomOut", |
4132 | "start": { | 4718 | "start": { |
4133 | "column": 11, | 4719 | "column": 11, |
4134 | "line": 79 | 4720 | "line": 82 |
4135 | } | 4721 | } |
4136 | }, | 4722 | }, |
4137 | { | 4723 | { |
4138 | "defaultMessage": "!!!Enter Full Screen", | 4724 | "defaultMessage": "!!!Enter Full Screen", |
4139 | "end": { | 4725 | "end": { |
4140 | "column": 3, | 4726 | "column": 3, |
4141 | "line": 86 | 4727 | "line": 89 |
4142 | }, | 4728 | }, |
4143 | "file": "src/lib/Menu.js", | 4729 | "file": "src/lib/Menu.js", |
4144 | "id": "menu.view.enterFullScreen", | 4730 | "id": "menu.view.enterFullScreen", |
4145 | "start": { | 4731 | "start": { |
4146 | "column": 19, | 4732 | "column": 19, |
4147 | "line": 83 | 4733 | "line": 86 |
4148 | } | 4734 | } |
4149 | }, | 4735 | }, |
4150 | { | 4736 | { |
4151 | "defaultMessage": "!!!Exit Full Screen", | 4737 | "defaultMessage": "!!!Exit Full Screen", |
4152 | "end": { | 4738 | "end": { |
4153 | "column": 3, | 4739 | "column": 3, |
4154 | "line": 90 | 4740 | "line": 93 |
4155 | }, | 4741 | }, |
4156 | "file": "src/lib/Menu.js", | 4742 | "file": "src/lib/Menu.js", |
4157 | "id": "menu.view.exitFullScreen", | 4743 | "id": "menu.view.exitFullScreen", |
4158 | "start": { | 4744 | "start": { |
4159 | "column": 18, | 4745 | "column": 18, |
4160 | "line": 87 | 4746 | "line": 90 |
4161 | } | 4747 | } |
4162 | }, | 4748 | }, |
4163 | { | 4749 | { |
4164 | "defaultMessage": "!!!Toggle Full Screen", | 4750 | "defaultMessage": "!!!Toggle Full Screen", |
4165 | "end": { | 4751 | "end": { |
4166 | "column": 3, | 4752 | "column": 3, |
4167 | "line": 94 | 4753 | "line": 97 |
4168 | }, | 4754 | }, |
4169 | "file": "src/lib/Menu.js", | 4755 | "file": "src/lib/Menu.js", |
4170 | "id": "menu.view.toggleFullScreen", | 4756 | "id": "menu.view.toggleFullScreen", |
4171 | "start": { | 4757 | "start": { |
4172 | "column": 20, | 4758 | "column": 20, |
4173 | "line": 91 | 4759 | "line": 94 |
4174 | } | 4760 | } |
4175 | }, | 4761 | }, |
4176 | { | 4762 | { |
4177 | "defaultMessage": "!!!Toggle Developer Tools", | 4763 | "defaultMessage": "!!!Toggle Developer Tools", |
4178 | "end": { | 4764 | "end": { |
4179 | "column": 3, | 4765 | "column": 3, |
4180 | "line": 98 | 4766 | "line": 101 |
4181 | }, | 4767 | }, |
4182 | "file": "src/lib/Menu.js", | 4768 | "file": "src/lib/Menu.js", |
4183 | "id": "menu.view.toggleDevTools", | 4769 | "id": "menu.view.toggleDevTools", |
4184 | "start": { | 4770 | "start": { |
4185 | "column": 18, | 4771 | "column": 18, |
4186 | "line": 95 | 4772 | "line": 98 |
4187 | } | 4773 | } |
4188 | }, | 4774 | }, |
4189 | { | 4775 | { |
4190 | "defaultMessage": "!!!Toggle Service Developer Tools", | 4776 | "defaultMessage": "!!!Toggle Todos Developer Tools", |
4191 | "end": { | 4777 | "end": { |
4192 | "column": 3, | 4778 | "column": 3, |
4779 | "line": 105 | ||
4780 | }, | ||
4781 | "file": "src/lib/Menu.js", | ||
4782 | "id": "menu.view.toggleTodosDevTools", | ||
4783 | "start": { | ||
4784 | "column": 23, | ||
4193 | "line": 102 | 4785 | "line": 102 |
4786 | } | ||
4787 | }, | ||
4788 | { | ||
4789 | "defaultMessage": "!!!Toggle Service Developer Tools", | ||
4790 | "end": { | ||
4791 | "column": 3, | ||
4792 | "line": 109 | ||
4194 | }, | 4793 | }, |
4195 | "file": "src/lib/Menu.js", | 4794 | "file": "src/lib/Menu.js", |
4196 | "id": "menu.view.toggleServiceDevTools", | 4795 | "id": "menu.view.toggleServiceDevTools", |
4197 | "start": { | 4796 | "start": { |
4198 | "column": 25, | 4797 | "column": 25, |
4199 | "line": 99 | 4798 | "line": 106 |
4200 | } | 4799 | } |
4201 | }, | 4800 | }, |
4202 | { | 4801 | { |
4203 | "defaultMessage": "!!!Reload Service", | 4802 | "defaultMessage": "!!!Reload Service", |
4204 | "end": { | 4803 | "end": { |
4205 | "column": 3, | 4804 | "column": 3, |
4206 | "line": 106 | 4805 | "line": 113 |
4207 | }, | 4806 | }, |
4208 | "file": "src/lib/Menu.js", | 4807 | "file": "src/lib/Menu.js", |
4209 | "id": "menu.view.reloadService", | 4808 | "id": "menu.view.reloadService", |
4210 | "start": { | 4809 | "start": { |
4211 | "column": 17, | 4810 | "column": 17, |
4212 | "line": 103 | 4811 | "line": 110 |
4213 | } | 4812 | } |
4214 | }, | 4813 | }, |
4215 | { | 4814 | { |
4216 | "defaultMessage": "!!!Reload Franz", | 4815 | "defaultMessage": "!!!Reload Franz", |
4217 | "end": { | 4816 | "end": { |
4218 | "column": 3, | 4817 | "column": 3, |
4219 | "line": 110 | 4818 | "line": 117 |
4220 | }, | 4819 | }, |
4221 | "file": "src/lib/Menu.js", | 4820 | "file": "src/lib/Menu.js", |
4222 | "id": "menu.view.reloadFranz", | 4821 | "id": "menu.view.reloadFranz", |
4223 | "start": { | 4822 | "start": { |
4224 | "column": 15, | 4823 | "column": 15, |
4225 | "line": 107 | 4824 | "line": 114 |
4226 | } | 4825 | } |
4227 | }, | 4826 | }, |
4228 | { | 4827 | { |
4229 | "defaultMessage": "!!!Minimize", | 4828 | "defaultMessage": "!!!Minimize", |
4230 | "end": { | 4829 | "end": { |
4231 | "column": 3, | 4830 | "column": 3, |
4232 | "line": 114 | 4831 | "line": 121 |
4233 | }, | 4832 | }, |
4234 | "file": "src/lib/Menu.js", | 4833 | "file": "src/lib/Menu.js", |
4235 | "id": "menu.window.minimize", | 4834 | "id": "menu.window.minimize", |
4236 | "start": { | 4835 | "start": { |
4237 | "column": 12, | 4836 | "column": 12, |
4238 | "line": 111 | 4837 | "line": 118 |
4239 | } | 4838 | } |
4240 | }, | 4839 | }, |
4241 | { | 4840 | { |
4242 | "defaultMessage": "!!!Close", | 4841 | "defaultMessage": "!!!Close", |
4243 | "end": { | 4842 | "end": { |
4244 | "column": 3, | 4843 | "column": 3, |
4245 | "line": 118 | 4844 | "line": 125 |
4246 | }, | 4845 | }, |
4247 | "file": "src/lib/Menu.js", | 4846 | "file": "src/lib/Menu.js", |
4248 | "id": "menu.window.close", | 4847 | "id": "menu.window.close", |
4249 | "start": { | 4848 | "start": { |
4250 | "column": 9, | 4849 | "column": 9, |
4251 | "line": 115 | 4850 | "line": 122 |
4252 | } | 4851 | } |
4253 | }, | 4852 | }, |
4254 | { | 4853 | { |
4255 | "defaultMessage": "!!!Learn More", | 4854 | "defaultMessage": "!!!Learn More", |
4256 | "end": { | 4855 | "end": { |
4257 | "column": 3, | 4856 | "column": 3, |
4258 | "line": 122 | 4857 | "line": 129 |
4259 | }, | 4858 | }, |
4260 | "file": "src/lib/Menu.js", | 4859 | "file": "src/lib/Menu.js", |
4261 | "id": "menu.help.learnMore", | 4860 | "id": "menu.help.learnMore", |
4262 | "start": { | 4861 | "start": { |
4263 | "column": 13, | 4862 | "column": 13, |
4264 | "line": 119 | 4863 | "line": 126 |
4265 | } | 4864 | } |
4266 | }, | 4865 | }, |
4267 | { | 4866 | { |
4268 | "defaultMessage": "!!!Changelog", | 4867 | "defaultMessage": "!!!Changelog", |
4269 | "end": { | 4868 | "end": { |
4270 | "column": 3, | 4869 | "column": 3, |
4271 | "line": 126 | 4870 | "line": 133 |
4272 | }, | 4871 | }, |
4273 | "file": "src/lib/Menu.js", | 4872 | "file": "src/lib/Menu.js", |
4274 | "id": "menu.help.changelog", | 4873 | "id": "menu.help.changelog", |
4275 | "start": { | 4874 | "start": { |
4276 | "column": 13, | 4875 | "column": 13, |
4277 | "line": 123 | 4876 | "line": 130 |
4278 | } | 4877 | } |
4279 | }, | 4878 | }, |
4280 | { | 4879 | { |
4281 | "defaultMessage": "!!!Support", | 4880 | "defaultMessage": "!!!Support", |
4282 | "end": { | 4881 | "end": { |
4283 | "column": 3, | 4882 | "column": 3, |
4284 | "line": 130 | 4883 | "line": 137 |
4285 | }, | 4884 | }, |
4286 | "file": "src/lib/Menu.js", | 4885 | "file": "src/lib/Menu.js", |
4287 | "id": "menu.help.support", | 4886 | "id": "menu.help.support", |
4288 | "start": { | 4887 | "start": { |
4289 | "column": 11, | 4888 | "column": 11, |
4290 | "line": 127 | 4889 | "line": 134 |
4890 | } | ||
4891 | }, | ||
4892 | { | ||
4893 | "defaultMessage": "!!!Copy Debug Information", | ||
4894 | "end": { | ||
4895 | "column": 3, | ||
4896 | "line": 141 | ||
4897 | }, | ||
4898 | "file": "src/lib/Menu.js", | ||
4899 | "id": "menu.help.debugInfo", | ||
4900 | "start": { | ||
4901 | "column": 13, | ||
4902 | "line": 138 | ||
4903 | } | ||
4904 | }, | ||
4905 | { | ||
4906 | "defaultMessage": "!!!Franz Debug Information", | ||
4907 | "end": { | ||
4908 | "column": 3, | ||
4909 | "line": 145 | ||
4910 | }, | ||
4911 | "file": "src/lib/Menu.js", | ||
4912 | "id": "menu.help.debugInfoCopiedHeadline", | ||
4913 | "start": { | ||
4914 | "column": 27, | ||
4915 | "line": 142 | ||
4916 | } | ||
4917 | }, | ||
4918 | { | ||
4919 | "defaultMessage": "!!!Your Debug Information has been copied to your clipboard.", | ||
4920 | "end": { | ||
4921 | "column": 3, | ||
4922 | "line": 149 | ||
4923 | }, | ||
4924 | "file": "src/lib/Menu.js", | ||
4925 | "id": "menu.help.debugInfoCopiedBody", | ||
4926 | "start": { | ||
4927 | "column": 23, | ||
4928 | "line": 146 | ||
4291 | } | 4929 | } |
4292 | }, | 4930 | }, |
4293 | { | 4931 | { |
4294 | "defaultMessage": "!!!Terms of Service", | 4932 | "defaultMessage": "!!!Terms of Service", |
4295 | "end": { | 4933 | "end": { |
4296 | "column": 3, | 4934 | "column": 3, |
4297 | "line": 134 | 4935 | "line": 153 |
4298 | }, | 4936 | }, |
4299 | "file": "src/lib/Menu.js", | 4937 | "file": "src/lib/Menu.js", |
4300 | "id": "menu.help.tos", | 4938 | "id": "menu.help.tos", |
4301 | "start": { | 4939 | "start": { |
4302 | "column": 7, | 4940 | "column": 7, |
4303 | "line": 131 | 4941 | "line": 150 |
4304 | } | 4942 | } |
4305 | }, | 4943 | }, |
4306 | { | 4944 | { |
4307 | "defaultMessage": "!!!Privacy Statement", | 4945 | "defaultMessage": "!!!Privacy Statement", |
4308 | "end": { | 4946 | "end": { |
4309 | "column": 3, | 4947 | "column": 3, |
4310 | "line": 138 | 4948 | "line": 157 |
4311 | }, | 4949 | }, |
4312 | "file": "src/lib/Menu.js", | 4950 | "file": "src/lib/Menu.js", |
4313 | "id": "menu.help.privacy", | 4951 | "id": "menu.help.privacy", |
4314 | "start": { | 4952 | "start": { |
4315 | "column": 11, | 4953 | "column": 11, |
4316 | "line": 135 | 4954 | "line": 154 |
4317 | } | 4955 | } |
4318 | }, | 4956 | }, |
4319 | { | 4957 | { |
4320 | "defaultMessage": "!!!File", | 4958 | "defaultMessage": "!!!File", |
4321 | "end": { | 4959 | "end": { |
4322 | "column": 3, | 4960 | "column": 3, |
4323 | "line": 142 | 4961 | "line": 161 |
4324 | }, | 4962 | }, |
4325 | "file": "src/lib/Menu.js", | 4963 | "file": "src/lib/Menu.js", |
4326 | "id": "menu.file", | 4964 | "id": "menu.file", |
4327 | "start": { | 4965 | "start": { |
4328 | "column": 8, | 4966 | "column": 8, |
4329 | "line": 139 | 4967 | "line": 158 |
4330 | } | 4968 | } |
4331 | }, | 4969 | }, |
4332 | { | 4970 | { |
4333 | "defaultMessage": "!!!View", | 4971 | "defaultMessage": "!!!View", |
4334 | "end": { | 4972 | "end": { |
4335 | "column": 3, | 4973 | "column": 3, |
4336 | "line": 146 | 4974 | "line": 165 |
4337 | }, | 4975 | }, |
4338 | "file": "src/lib/Menu.js", | 4976 | "file": "src/lib/Menu.js", |
4339 | "id": "menu.view", | 4977 | "id": "menu.view", |
4340 | "start": { | 4978 | "start": { |
4341 | "column": 8, | 4979 | "column": 8, |
4342 | "line": 143 | 4980 | "line": 162 |
4343 | } | 4981 | } |
4344 | }, | 4982 | }, |
4345 | { | 4983 | { |
4346 | "defaultMessage": "!!!Services", | 4984 | "defaultMessage": "!!!Services", |
4347 | "end": { | 4985 | "end": { |
4348 | "column": 3, | 4986 | "column": 3, |
4349 | "line": 150 | 4987 | "line": 169 |
4350 | }, | 4988 | }, |
4351 | "file": "src/lib/Menu.js", | 4989 | "file": "src/lib/Menu.js", |
4352 | "id": "menu.services", | 4990 | "id": "menu.services", |
4353 | "start": { | 4991 | "start": { |
4354 | "column": 12, | 4992 | "column": 12, |
4355 | "line": 147 | 4993 | "line": 166 |
4356 | } | 4994 | } |
4357 | }, | 4995 | }, |
4358 | { | 4996 | { |
4359 | "defaultMessage": "!!!Window", | 4997 | "defaultMessage": "!!!Window", |
4360 | "end": { | 4998 | "end": { |
4361 | "column": 3, | 4999 | "column": 3, |
4362 | "line": 154 | 5000 | "line": 173 |
4363 | }, | 5001 | }, |
4364 | "file": "src/lib/Menu.js", | 5002 | "file": "src/lib/Menu.js", |
4365 | "id": "menu.window", | 5003 | "id": "menu.window", |
4366 | "start": { | 5004 | "start": { |
4367 | "column": 10, | 5005 | "column": 10, |
4368 | "line": 151 | 5006 | "line": 170 |
4369 | } | 5007 | } |
4370 | }, | 5008 | }, |
4371 | { | 5009 | { |
4372 | "defaultMessage": "!!!Help", | 5010 | "defaultMessage": "!!!Help", |
4373 | "end": { | 5011 | "end": { |
4374 | "column": 3, | 5012 | "column": 3, |
4375 | "line": 158 | 5013 | "line": 177 |
4376 | }, | 5014 | }, |
4377 | "file": "src/lib/Menu.js", | 5015 | "file": "src/lib/Menu.js", |
4378 | "id": "menu.help", | 5016 | "id": "menu.help", |
4379 | "start": { | 5017 | "start": { |
4380 | "column": 8, | 5018 | "column": 8, |
4381 | "line": 155 | 5019 | "line": 174 |
4382 | } | 5020 | } |
4383 | }, | 5021 | }, |
4384 | { | 5022 | { |
4385 | "defaultMessage": "!!!About Franz", | 5023 | "defaultMessage": "!!!About Franz", |
4386 | "end": { | 5024 | "end": { |
4387 | "column": 3, | 5025 | "column": 3, |
4388 | "line": 162 | 5026 | "line": 181 |
4389 | }, | 5027 | }, |
4390 | "file": "src/lib/Menu.js", | 5028 | "file": "src/lib/Menu.js", |
4391 | "id": "menu.app.about", | 5029 | "id": "menu.app.about", |
4392 | "start": { | 5030 | "start": { |
4393 | "column": 9, | 5031 | "column": 9, |
4394 | "line": 159 | 5032 | "line": 178 |
4395 | } | 5033 | } |
4396 | }, | 5034 | }, |
4397 | { | 5035 | { |
4398 | "defaultMessage": "!!!What's new?", | 5036 | "defaultMessage": "!!!What's new?", |
4399 | "end": { | 5037 | "end": { |
4400 | "column": 3, | 5038 | "column": 3, |
4401 | "line": 166 | 5039 | "line": 185 |
4402 | }, | 5040 | }, |
4403 | "file": "src/lib/Menu.js", | 5041 | "file": "src/lib/Menu.js", |
4404 | "id": "menu.app.announcement", | 5042 | "id": "menu.app.announcement", |
4405 | "start": { | 5043 | "start": { |
4406 | "column": 16, | 5044 | "column": 16, |
4407 | "line": 163 | 5045 | "line": 182 |
4408 | } | 5046 | } |
4409 | }, | 5047 | }, |
4410 | { | 5048 | { |
4411 | "defaultMessage": "!!!Settings", | 5049 | "defaultMessage": "!!!Settings", |
4412 | "end": { | 5050 | "end": { |
4413 | "column": 3, | 5051 | "column": 3, |
4414 | "line": 170 | 5052 | "line": 189 |
4415 | }, | 5053 | }, |
4416 | "file": "src/lib/Menu.js", | 5054 | "file": "src/lib/Menu.js", |
4417 | "id": "menu.app.settings", | 5055 | "id": "menu.app.settings", |
4418 | "start": { | 5056 | "start": { |
4419 | "column": 12, | 5057 | "column": 12, |
4420 | "line": 167 | 5058 | "line": 186 |
4421 | } | 5059 | } |
4422 | }, | 5060 | }, |
4423 | { | 5061 | { |
4424 | "defaultMessage": "!!!Check for updates", | 5062 | "defaultMessage": "!!!Check for updates", |
4425 | "end": { | 5063 | "end": { |
4426 | "column": 3, | 5064 | "column": 3, |
4427 | "line": 174 | 5065 | "line": 193 |
4428 | }, | 5066 | }, |
4429 | "file": "src/lib/Menu.js", | 5067 | "file": "src/lib/Menu.js", |
4430 | "id": "menu.app.checkForUpdates", | 5068 | "id": "menu.app.checkForUpdates", |
4431 | "start": { | 5069 | "start": { |
4432 | "column": 19, | 5070 | "column": 19, |
4433 | "line": 171 | 5071 | "line": 190 |
4434 | } | 5072 | } |
4435 | }, | 5073 | }, |
4436 | { | 5074 | { |
4437 | "defaultMessage": "!!!Hide", | 5075 | "defaultMessage": "!!!Hide", |
4438 | "end": { | 5076 | "end": { |
4439 | "column": 3, | 5077 | "column": 3, |
4440 | "line": 178 | 5078 | "line": 197 |
4441 | }, | 5079 | }, |
4442 | "file": "src/lib/Menu.js", | 5080 | "file": "src/lib/Menu.js", |
4443 | "id": "menu.app.hide", | 5081 | "id": "menu.app.hide", |
4444 | "start": { | 5082 | "start": { |
4445 | "column": 8, | 5083 | "column": 8, |
4446 | "line": 175 | 5084 | "line": 194 |
4447 | } | 5085 | } |
4448 | }, | 5086 | }, |
4449 | { | 5087 | { |
4450 | "defaultMessage": "!!!Hide Others", | 5088 | "defaultMessage": "!!!Hide Others", |
4451 | "end": { | 5089 | "end": { |
4452 | "column": 3, | 5090 | "column": 3, |
4453 | "line": 182 | 5091 | "line": 201 |
4454 | }, | 5092 | }, |
4455 | "file": "src/lib/Menu.js", | 5093 | "file": "src/lib/Menu.js", |
4456 | "id": "menu.app.hideOthers", | 5094 | "id": "menu.app.hideOthers", |
4457 | "start": { | 5095 | "start": { |
4458 | "column": 14, | 5096 | "column": 14, |
4459 | "line": 179 | 5097 | "line": 198 |
4460 | } | 5098 | } |
4461 | }, | 5099 | }, |
4462 | { | 5100 | { |
4463 | "defaultMessage": "!!!Unhide", | 5101 | "defaultMessage": "!!!Unhide", |
4464 | "end": { | 5102 | "end": { |
4465 | "column": 3, | 5103 | "column": 3, |
4466 | "line": 186 | 5104 | "line": 205 |
4467 | }, | 5105 | }, |
4468 | "file": "src/lib/Menu.js", | 5106 | "file": "src/lib/Menu.js", |
4469 | "id": "menu.app.unhide", | 5107 | "id": "menu.app.unhide", |
4470 | "start": { | 5108 | "start": { |
4471 | "column": 10, | 5109 | "column": 10, |
4472 | "line": 183 | 5110 | "line": 202 |
4473 | } | 5111 | } |
4474 | }, | 5112 | }, |
4475 | { | 5113 | { |
4476 | "defaultMessage": "!!!Quit", | 5114 | "defaultMessage": "!!!Quit", |
4477 | "end": { | 5115 | "end": { |
4478 | "column": 3, | 5116 | "column": 3, |
4479 | "line": 190 | 5117 | "line": 209 |
4480 | }, | 5118 | }, |
4481 | "file": "src/lib/Menu.js", | 5119 | "file": "src/lib/Menu.js", |
4482 | "id": "menu.app.quit", | 5120 | "id": "menu.app.quit", |
4483 | "start": { | 5121 | "start": { |
4484 | "column": 8, | 5122 | "column": 8, |
4485 | "line": 187 | 5123 | "line": 206 |
4486 | } | 5124 | } |
4487 | }, | 5125 | }, |
4488 | { | 5126 | { |
4489 | "defaultMessage": "!!!Add New Service...", | 5127 | "defaultMessage": "!!!Add New Service...", |
4490 | "end": { | 5128 | "end": { |
4491 | "column": 3, | 5129 | "column": 3, |
4492 | "line": 194 | 5130 | "line": 213 |
4493 | }, | 5131 | }, |
4494 | "file": "src/lib/Menu.js", | 5132 | "file": "src/lib/Menu.js", |
4495 | "id": "menu.services.addNewService", | 5133 | "id": "menu.services.addNewService", |
4496 | "start": { | 5134 | "start": { |
4497 | "column": 17, | 5135 | "column": 17, |
4498 | "line": 191 | 5136 | "line": 210 |
4499 | } | 5137 | } |
4500 | }, | 5138 | }, |
4501 | { | 5139 | { |
4502 | "defaultMessage": "!!!Add New Workspace...", | 5140 | "defaultMessage": "!!!Add New Workspace...", |
4503 | "end": { | 5141 | "end": { |
4504 | "column": 3, | 5142 | "column": 3, |
4505 | "line": 198 | 5143 | "line": 217 |
4506 | }, | 5144 | }, |
4507 | "file": "src/lib/Menu.js", | 5145 | "file": "src/lib/Menu.js", |
4508 | "id": "menu.workspaces.addNewWorkspace", | 5146 | "id": "menu.workspaces.addNewWorkspace", |
4509 | "start": { | 5147 | "start": { |
4510 | "column": 19, | 5148 | "column": 19, |
4511 | "line": 195 | 5149 | "line": 214 |
4512 | } | 5150 | } |
4513 | }, | 5151 | }, |
4514 | { | 5152 | { |
4515 | "defaultMessage": "!!!Open workspace drawer", | 5153 | "defaultMessage": "!!!Open workspace drawer", |
4516 | "end": { | 5154 | "end": { |
4517 | "column": 3, | 5155 | "column": 3, |
4518 | "line": 202 | 5156 | "line": 221 |
4519 | }, | 5157 | }, |
4520 | "file": "src/lib/Menu.js", | 5158 | "file": "src/lib/Menu.js", |
4521 | "id": "menu.workspaces.openWorkspaceDrawer", | 5159 | "id": "menu.workspaces.openWorkspaceDrawer", |
4522 | "start": { | 5160 | "start": { |
4523 | "column": 23, | 5161 | "column": 23, |
4524 | "line": 199 | 5162 | "line": 218 |
4525 | } | 5163 | } |
4526 | }, | 5164 | }, |
4527 | { | 5165 | { |
4528 | "defaultMessage": "!!!Close workspace drawer", | 5166 | "defaultMessage": "!!!Close workspace drawer", |
4529 | "end": { | 5167 | "end": { |
4530 | "column": 3, | 5168 | "column": 3, |
4531 | "line": 206 | 5169 | "line": 225 |
4532 | }, | 5170 | }, |
4533 | "file": "src/lib/Menu.js", | 5171 | "file": "src/lib/Menu.js", |
4534 | "id": "menu.workspaces.closeWorkspaceDrawer", | 5172 | "id": "menu.workspaces.closeWorkspaceDrawer", |
4535 | "start": { | 5173 | "start": { |
4536 | "column": 24, | 5174 | "column": 24, |
4537 | "line": 203 | 5175 | "line": 222 |
4538 | } | 5176 | } |
4539 | }, | 5177 | }, |
4540 | { | 5178 | { |
4541 | "defaultMessage": "!!!Activate next service...", | 5179 | "defaultMessage": "!!!Activate next service...", |
4542 | "end": { | 5180 | "end": { |
4543 | "column": 3, | 5181 | "column": 3, |
4544 | "line": 210 | 5182 | "line": 229 |
4545 | }, | 5183 | }, |
4546 | "file": "src/lib/Menu.js", | 5184 | "file": "src/lib/Menu.js", |
4547 | "id": "menu.services.setNextServiceActive", | 5185 | "id": "menu.services.setNextServiceActive", |
4548 | "start": { | 5186 | "start": { |
4549 | "column": 23, | 5187 | "column": 23, |
4550 | "line": 207 | 5188 | "line": 226 |
4551 | } | 5189 | } |
4552 | }, | 5190 | }, |
4553 | { | 5191 | { |
4554 | "defaultMessage": "!!!Activate previous service...", | 5192 | "defaultMessage": "!!!Activate previous service...", |
4555 | "end": { | 5193 | "end": { |
4556 | "column": 3, | 5194 | "column": 3, |
4557 | "line": 214 | 5195 | "line": 233 |
4558 | }, | 5196 | }, |
4559 | "file": "src/lib/Menu.js", | 5197 | "file": "src/lib/Menu.js", |
4560 | "id": "menu.services.activatePreviousService", | 5198 | "id": "menu.services.activatePreviousService", |
4561 | "start": { | 5199 | "start": { |
4562 | "column": 27, | 5200 | "column": 27, |
4563 | "line": 211 | 5201 | "line": 230 |
4564 | } | 5202 | } |
4565 | }, | 5203 | }, |
4566 | { | 5204 | { |
4567 | "defaultMessage": "!!!Disable notifications & audio", | 5205 | "defaultMessage": "!!!Disable notifications & audio", |
4568 | "end": { | 5206 | "end": { |
4569 | "column": 3, | 5207 | "column": 3, |
4570 | "line": 218 | 5208 | "line": 237 |
4571 | }, | 5209 | }, |
4572 | "file": "src/lib/Menu.js", | 5210 | "file": "src/lib/Menu.js", |
4573 | "id": "sidebar.muteApp", | 5211 | "id": "sidebar.muteApp", |
4574 | "start": { | 5212 | "start": { |
4575 | "column": 11, | 5213 | "column": 11, |
4576 | "line": 215 | 5214 | "line": 234 |
4577 | } | 5215 | } |
4578 | }, | 5216 | }, |
4579 | { | 5217 | { |
4580 | "defaultMessage": "!!!Enable notifications & audio", | 5218 | "defaultMessage": "!!!Enable notifications & audio", |
4581 | "end": { | 5219 | "end": { |
4582 | "column": 3, | 5220 | "column": 3, |
4583 | "line": 222 | 5221 | "line": 241 |
4584 | }, | 5222 | }, |
4585 | "file": "src/lib/Menu.js", | 5223 | "file": "src/lib/Menu.js", |
4586 | "id": "sidebar.unmuteApp", | 5224 | "id": "sidebar.unmuteApp", |
4587 | "start": { | 5225 | "start": { |
4588 | "column": 13, | 5226 | "column": 13, |
4589 | "line": 219 | 5227 | "line": 238 |
4590 | } | 5228 | } |
4591 | }, | 5229 | }, |
4592 | { | 5230 | { |
4593 | "defaultMessage": "!!!Workspaces", | 5231 | "defaultMessage": "!!!Workspaces", |
4594 | "end": { | 5232 | "end": { |
4595 | "column": 3, | 5233 | "column": 3, |
4596 | "line": 226 | 5234 | "line": 245 |
4597 | }, | 5235 | }, |
4598 | "file": "src/lib/Menu.js", | 5236 | "file": "src/lib/Menu.js", |
4599 | "id": "menu.workspaces", | 5237 | "id": "menu.workspaces", |
4600 | "start": { | 5238 | "start": { |
4601 | "column": 14, | 5239 | "column": 14, |
4602 | "line": 223 | 5240 | "line": 242 |
4603 | } | 5241 | } |
4604 | }, | 5242 | }, |
4605 | { | 5243 | { |
4606 | "defaultMessage": "!!!Default", | 5244 | "defaultMessage": "!!!Default", |
4607 | "end": { | 5245 | "end": { |
4608 | "column": 3, | 5246 | "column": 3, |
4609 | "line": 230 | 5247 | "line": 249 |
4610 | }, | 5248 | }, |
4611 | "file": "src/lib/Menu.js", | 5249 | "file": "src/lib/Menu.js", |
4612 | "id": "menu.workspaces.defaultWorkspace", | 5250 | "id": "menu.workspaces.defaultWorkspace", |
4613 | "start": { | 5251 | "start": { |
4614 | "column": 20, | 5252 | "column": 20, |
4615 | "line": 227 | 5253 | "line": 246 |
5254 | } | ||
5255 | }, | ||
5256 | { | ||
5257 | "defaultMessage": "!!!Todos", | ||
5258 | "end": { | ||
5259 | "column": 3, | ||
5260 | "line": 253 | ||
5261 | }, | ||
5262 | "file": "src/lib/Menu.js", | ||
5263 | "id": "menu.todos", | ||
5264 | "start": { | ||
5265 | "column": 9, | ||
5266 | "line": 250 | ||
5267 | } | ||
5268 | }, | ||
5269 | { | ||
5270 | "defaultMessage": "!!!Open Todos drawer", | ||
5271 | "end": { | ||
5272 | "column": 3, | ||
5273 | "line": 257 | ||
5274 | }, | ||
5275 | "file": "src/lib/Menu.js", | ||
5276 | "id": "menu.Todoss.openTodosDrawer", | ||
5277 | "start": { | ||
5278 | "column": 19, | ||
5279 | "line": 254 | ||
5280 | } | ||
5281 | }, | ||
5282 | { | ||
5283 | "defaultMessage": "!!!Close Todos drawer", | ||
5284 | "end": { | ||
5285 | "column": 3, | ||
5286 | "line": 261 | ||
5287 | }, | ||
5288 | "file": "src/lib/Menu.js", | ||
5289 | "id": "menu.Todoss.closeTodosDrawer", | ||
5290 | "start": { | ||
5291 | "column": 20, | ||
5292 | "line": 258 | ||
4616 | } | 5293 | } |
4617 | } | 5294 | } |
4618 | ], | 5295 | ], |
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index e2edbd596..727eb2884 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -2,9 +2,12 @@ | |||
2 | "app.errorHandler.action": "Reload", | 2 | "app.errorHandler.action": "Reload", |
3 | "app.errorHandler.headline": "Something went wrong", | 3 | "app.errorHandler.headline": "Something went wrong", |
4 | "feature.announcements.changelog.headline": "Changes in Franz {version}", | 4 | "feature.announcements.changelog.headline": "Changes in Franz {version}", |
5 | "feature.delayApp.action": "Get a Franz Supporter License", | ||
6 | "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", | 5 | "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", |
7 | "feature.delayApp.text": "Franz will continue in {seconds} seconds.", | 6 | "feature.delayApp.text": "Franz will continue in {seconds} seconds.", |
7 | "feature.delayApp.trial.action": "Yes, I want the free 14 day trial of Franz Professional", | ||
8 | "feature.delayApp.trial.headline": "Get the free Franz Professional 14 day trial and skip the line", | ||
9 | "feature.delayApp.upgrade.action": "Get a Franz Supporter License", | ||
10 | "feature.serviceLimit.limitReached": "You have added {amount} out of {limit} services that are included in your plan. Please upgrade your account to add more services.", | ||
8 | "feature.shareFranz.action.email": "Send as email", | 11 | "feature.shareFranz.action.email": "Send as email", |
9 | "feature.shareFranz.action.facebook": "Share on Facebook", | 12 | "feature.shareFranz.action.facebook": "Share on Facebook", |
10 | "feature.shareFranz.action.twitter": "Share on Twitter", | 13 | "feature.shareFranz.action.twitter": "Share on Twitter", |
@@ -27,6 +30,7 @@ | |||
27 | "infobar.buttonReloadServices": "Reload services", | 30 | "infobar.buttonReloadServices": "Reload services", |
28 | "infobar.requiredRequestsFailed": "Could not load services and user information", | 31 | "infobar.requiredRequestsFailed": "Could not load services and user information", |
29 | "infobar.servicesUpdated": "Your services have been updated.", | 32 | "infobar.servicesUpdated": "Your services have been updated.", |
33 | "infobar.trialActivated": "Your trial was successfully activated. Happy messaging!", | ||
30 | "infobar.updateAvailable": "A new update for Franz is available.", | 34 | "infobar.updateAvailable": "A new update for Franz is available.", |
31 | "invite.email.label": "Email address", | 35 | "invite.email.label": "Email address", |
32 | "invite.headline.friends": "Invite 3 of your friends or colleagues", | 36 | "invite.headline.friends": "Invite 3 of your friends or colleagues", |
@@ -43,6 +47,8 @@ | |||
43 | "login.serverLogout": "Your session expired, please login again.", | 47 | "login.serverLogout": "Your session expired, please login again.", |
44 | "login.submit.label": "Sign in", | 48 | "login.submit.label": "Sign in", |
45 | "login.tokenExpired": "Your session expired, please login again.", | 49 | "login.tokenExpired": "Your session expired, please login again.", |
50 | "menu.Todoss.closeTodosDrawer": "Close Todos drawer", | ||
51 | "menu.Todoss.openTodosDrawer": "Open Todos drawer", | ||
46 | "menu.app.about": "About Franz", | 52 | "menu.app.about": "About Franz", |
47 | "menu.app.announcement": "What's new?", | 53 | "menu.app.announcement": "What's new?", |
48 | "menu.app.checkForUpdates": "Check for updates", | 54 | "menu.app.checkForUpdates": "Check for updates", |
@@ -68,6 +74,9 @@ | |||
68 | "menu.file": "File", | 74 | "menu.file": "File", |
69 | "menu.help": "Help", | 75 | "menu.help": "Help", |
70 | "menu.help.changelog": "Changelog", | 76 | "menu.help.changelog": "Changelog", |
77 | "menu.help.debugInfo": "Copy Debug Information", | ||
78 | "menu.help.debugInfoCopiedBody": "Your Debug Information has been copied to your clipboard.", | ||
79 | "menu.help.debugInfoCopiedHeadline": "Franz Debug Information", | ||
71 | "menu.help.learnMore": "Learn More", | 80 | "menu.help.learnMore": "Learn More", |
72 | "menu.help.privacy": "Privacy Statement", | 81 | "menu.help.privacy": "Privacy Statement", |
73 | "menu.help.support": "Support", | 82 | "menu.help.support": "Support", |
@@ -76,6 +85,7 @@ | |||
76 | "menu.services.activatePreviousService": "Activate previous service", | 85 | "menu.services.activatePreviousService": "Activate previous service", |
77 | "menu.services.addNewService": "Add New Service...", | 86 | "menu.services.addNewService": "Add New Service...", |
78 | "menu.services.setNextServiceActive": "Activate next service", | 87 | "menu.services.setNextServiceActive": "Activate next service", |
88 | "menu.todos": "Todos", | ||
79 | "menu.view": "View", | 89 | "menu.view": "View", |
80 | "menu.view.enterFullScreen": "Enter Full Screen", | 90 | "menu.view.enterFullScreen": "Enter Full Screen", |
81 | "menu.view.exitFullScreen": "Exit Full Screen", | 91 | "menu.view.exitFullScreen": "Exit Full Screen", |
@@ -85,6 +95,7 @@ | |||
85 | "menu.view.toggleDevTools": "Toggle Developer Tools", | 95 | "menu.view.toggleDevTools": "Toggle Developer Tools", |
86 | "menu.view.toggleFullScreen": "Toggle Full Screen", | 96 | "menu.view.toggleFullScreen": "Toggle Full Screen", |
87 | "menu.view.toggleServiceDevTools": "Toggle Service Developer Tools", | 97 | "menu.view.toggleServiceDevTools": "Toggle Service Developer Tools", |
98 | "menu.view.toggleTodosDevTools": "Toggle Todos Developer Tools", | ||
88 | "menu.view.zoomIn": "Zoom In", | 99 | "menu.view.zoomIn": "Zoom In", |
89 | "menu.view.zoomOut": "Zoom Out", | 100 | "menu.view.zoomOut": "Zoom Out", |
90 | "menu.window": "Window", | 101 | "menu.window": "Window", |
@@ -103,10 +114,33 @@ | |||
103 | "password.submit.label": "Submit", | 114 | "password.submit.label": "Submit", |
104 | "password.successInfo": "Please check your email", | 115 | "password.successInfo": "Please check your email", |
105 | "premiumFeature.button.upgradeAccount": "Upgrade account", | 116 | "premiumFeature.button.upgradeAccount": "Upgrade account", |
106 | "pricing.headline": "Support Franz", | 117 | "pricing.features.adFree": "Forever ad-free", |
107 | "pricing.link.skipPayment": "I don't want to support the development of Franz.", | 118 | "pricing.features.appDelays": "No Waiting Screens", |
108 | "pricing.submit.label": "I want to support the development of Franz", | 119 | "pricing.features.customWebsites": "Add Custom Websites", |
109 | "pricing.support.label": "Select your support plan", | 120 | "pricing.features.onPremise": "On-premise & other Hosted Services", |
121 | "pricing.features.serviceProxies": "Service Proxies", | ||
122 | "pricing.features.spellchecker": "Spellchecker support", | ||
123 | "pricing.features.teamManagement": "Team Management", | ||
124 | "pricing.features.thirdPartyServices": "Install 3rd party services", | ||
125 | "pricing.features.unlimitedServices": "Add unlimited services", | ||
126 | "pricing.features.workspaces": "Workspaces", | ||
127 | "pricing.plan.free": "Franz Free", | ||
128 | "pricing.plan.legacy": "Franz Premium", | ||
129 | "pricing.plan.personal": "Franz Personal", | ||
130 | "pricing.plan.personal-monthly": "Franz Personal Monthly", | ||
131 | "pricing.plan.personal-yearly": "Franz Personal Yearly", | ||
132 | "pricing.plan.pro": "Franz Professional", | ||
133 | "pricing.plan.pro-monthly": "Franz Professional Monthly", | ||
134 | "pricing.plan.pro-yearly": "Franz Professional Yearly", | ||
135 | "pricing.trial.cta.accept": "Yes, upgrade my account to Franz Professional", | ||
136 | "pricing.trial.cta.skip": "Continue to Franz", | ||
137 | "pricing.trial.error": "Sorry, we could not activate your trial!", | ||
138 | "pricing.trial.features.headline": "Franz Professional includes:", | ||
139 | "pricing.trial.headline": "Franz Professional", | ||
140 | "pricing.trial.subheadline": "Your personal welcome offer:", | ||
141 | "pricing.trial.terms.automaticTrialEnd": "Your free trial ends automatically after 14 days", | ||
142 | "pricing.trial.terms.headline": "No strings attached", | ||
143 | "pricing.trial.terms.noCreditCard": "No credit card required", | ||
110 | "service.crashHandler.action": "Reload {name}", | 144 | "service.crashHandler.action": "Reload {name}", |
111 | "service.crashHandler.autoReload": "Trying to automatically restore {name} in {seconds} seconds", | 145 | "service.crashHandler.autoReload": "Trying to automatically restore {name} in {seconds} seconds", |
112 | "service.crashHandler.headline": "Oh no!", | 146 | "service.crashHandler.headline": "Oh no!", |
@@ -118,6 +152,11 @@ | |||
118 | "service.errorHandler.headline": "Oh no!", | 152 | "service.errorHandler.headline": "Oh no!", |
119 | "service.errorHandler.message": "Error", | 153 | "service.errorHandler.message": "Error", |
120 | "service.errorHandler.text": "{name} has failed to load.", | 154 | "service.errorHandler.text": "{name} has failed to load.", |
155 | "service.restrictedHandler.action": "Upgrade Account", | ||
156 | "service.restrictedHandler.customUrl.headline": "Franz Professional Plan required", | ||
157 | "service.restrictedHandler.customUrl.text": "Please upgrade to the Franz Professional plan to use custom urls & self hosted services.", | ||
158 | "service.restrictedHandler.serviceLimit.headline": "You have reached your service limit.", | ||
159 | "service.restrictedHandler.serviceLimit.text": "Please upgrade your account to use more than {count} services.", | ||
121 | "service.webviewLoader.loading": "Loading", | 160 | "service.webviewLoader.loading": "Loading", |
122 | "services.getStarted": "Get started", | 161 | "services.getStarted": "Get started", |
123 | "services.welcome": "Welcome to Franz", | 162 | "services.welcome": "Welcome to Franz", |
@@ -135,13 +174,19 @@ | |||
135 | "settings.account.headlinePassword": "Change password", | 174 | "settings.account.headlinePassword": "Change password", |
136 | "settings.account.headlineProfile": "Update profile", | 175 | "settings.account.headlineProfile": "Update profile", |
137 | "settings.account.headlineSubscription": "Your subscription", | 176 | "settings.account.headlineSubscription": "Your subscription", |
138 | "settings.account.headlineUpgrade": "Upgrade your account & support Franz", | 177 | "settings.account.headlineTrialUpgrade": "Get the free 14 day Franz Professional Trial", |
178 | "settings.account.headlineUpgradeAccount": "Upgrade your account & get the full Franz experience", | ||
139 | "settings.account.invoiceDownload": "Download", | 179 | "settings.account.invoiceDownload": "Download", |
140 | "settings.account.manageSubscription.label": "Manage your subscription", | 180 | "settings.account.manageSubscription.label": "Manage your subscription", |
141 | "settings.account.successInfo": "Your changes have been saved", | 181 | "settings.account.successInfo": "Your changes have been saved", |
182 | "settings.account.trial": "Free Trial", | ||
183 | "settings.account.trialEndsIn": "Your free trial ends in {duration}.", | ||
184 | "settings.account.trialUpdateBillingInfo": "Please update your billing info to continue using {license} after your trial period.", | ||
142 | "settings.account.tryReloadServices": "Try again", | 185 | "settings.account.tryReloadServices": "Try again", |
143 | "settings.account.tryReloadUserInfoRequest": "Try again", | 186 | "settings.account.tryReloadUserInfoRequest": "Try again", |
187 | "settings.account.upgradeToPro.label": "Upgrade to Franz Professional", | ||
144 | "settings.account.userInfoRequestFailed": "Could not load user information", | 188 | "settings.account.userInfoRequestFailed": "Could not load user information", |
189 | "settings.account.yourLicense": "Your Franz License", | ||
145 | "settings.app.buttonClearAllCache": "Clear cache", | 190 | "settings.app.buttonClearAllCache": "Clear cache", |
146 | "settings.app.buttonInstallUpdate": "Restart & install update", | 191 | "settings.app.buttonInstallUpdate": "Restart & install update", |
147 | "settings.app.buttonSearchForUpdate": "Check for updates", | 192 | "settings.app.buttonSearchForUpdate": "Check for updates", |
@@ -182,7 +227,13 @@ | |||
182 | "settings.navigation.yourServices": "Your services", | 227 | "settings.navigation.yourServices": "Your services", |
183 | "settings.navigation.yourWorkspaces": "Your workspaces", | 228 | "settings.navigation.yourWorkspaces": "Your workspaces", |
184 | "settings.recipes.all": "All services", | 229 | "settings.recipes.all": "All services", |
185 | "settings.recipes.dev": "Development", | 230 | "settings.recipes.custom": "Custom Services", |
231 | "settings.recipes.customService.headline.communityRecipes": "Community Services", | ||
232 | "settings.recipes.customService.headline.customRecipes": "Custom Service Recipes", | ||
233 | "settings.recipes.customService.headline.devRecipes": "Your Development Service Recipes", | ||
234 | "settings.recipes.customService.intro": "To add a custom service, copy the service recipe to:", | ||
235 | "settings.recipes.customService.openDevDocs": "Developer Documentation", | ||
236 | "settings.recipes.customService.openFolder": "Open folder", | ||
186 | "settings.recipes.headline": "Available services", | 237 | "settings.recipes.headline": "Available services", |
187 | "settings.recipes.missingService": "Missing a service?", | 238 | "settings.recipes.missingService": "Missing a service?", |
188 | "settings.recipes.mostPopular": "Most popular", | 239 | "settings.recipes.mostPopular": "Most popular", |
@@ -274,7 +325,6 @@ | |||
274 | "sidebar.openWorkspaceDrawer": "Open workspace drawer", | 325 | "sidebar.openWorkspaceDrawer": "Open workspace drawer", |
275 | "sidebar.settings": "Settings", | 326 | "sidebar.settings": "Settings", |
276 | "sidebar.unmuteApp": "Enable notifications & audio", | 327 | "sidebar.unmuteApp": "Enable notifications & audio", |
277 | "signup.company.label": "Company", | ||
278 | "signup.email.label": "Email address", | 328 | "signup.email.label": "Email address", |
279 | "signup.emailDuplicate": "A user with that email address already exists", | 329 | "signup.emailDuplicate": "A user with that email address already exists", |
280 | "signup.firstname.label": "First Name", | 330 | "signup.firstname.label": "First Name", |
@@ -286,20 +336,12 @@ | |||
286 | "signup.link.login": "Already have an account, sign in?", | 336 | "signup.link.login": "Already have an account, sign in?", |
287 | "signup.password.label": "Password", | 337 | "signup.password.label": "Password", |
288 | "signup.submit.label": "Create account", | 338 | "signup.submit.label": "Create account", |
289 | "subscription.euTaxInfo": "EU residents: local sales tax may apply", | 339 | "subscription.cta.activateTrial": "Yes, start the free Franz Professional trial", |
290 | "subscription.features.ads": "No ads, ever!", | 340 | "subscription.cta.allOptions": "See all options", |
291 | "subscription.features.comingSoon": "coming soon", | 341 | "subscription.cta.choosePlan": "Choose your plan", |
292 | "subscription.features.noInterruptions": "No app delays & nagging to upgrade license", | 342 | "subscription.includedProFeatures": "The Franz Professional Plan includes:", |
293 | "subscription.features.onpremise.mattermost": "Add on-premise/hosted services like Mattermost", | 343 | "subscription.teaser.includedFeatures": "Paid Franz Plans include:", |
294 | "subscription.features.proxy": "Proxy support for services", | 344 | "subscription.teaser.intro": "Franz 5 comes with a wide range of new features to boost up your everyday communication - batteries included. Check out our new plans and find out which one suits you most!", |
295 | "subscription.features.spellchecker": "Support for spellchecker", | ||
296 | "subscription.features.workspaces": "Organize your services in workspaces", | ||
297 | "subscription.includedFeatures": "Paid Franz Premium Supporter Account includes", | ||
298 | "subscription.paymentSessionError": "Could not initialize payment form", | ||
299 | "subscription.submit.label": "I want to support the development of Franz", | ||
300 | "subscription.type.free": "free", | ||
301 | "subscription.type.month": "month", | ||
302 | "subscription.type.year": "year", | ||
303 | "subscriptionPopup.buttonCancel": "Cancel", | 345 | "subscriptionPopup.buttonCancel": "Cancel", |
304 | "subscriptionPopup.buttonDone": "Done", | 346 | "subscriptionPopup.buttonDone": "Done", |
305 | "tabs.item.deleteService": "Delete service", | 347 | "tabs.item.deleteService": "Delete service", |
diff --git a/src/i18n/messages/src/components/TrialActivationInfoBar.json b/src/i18n/messages/src/components/TrialActivationInfoBar.json new file mode 100644 index 000000000..65dd964a6 --- /dev/null +++ b/src/i18n/messages/src/components/TrialActivationInfoBar.json | |||
@@ -0,0 +1,15 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "infobar.trialActivated", | ||
4 | "defaultMessage": "!!!Your trial was successfully activated. Happy messaging!", | ||
5 | "file": "src/components/TrialActivationInfoBar.js", | ||
6 | "start": { | ||
7 | "line": 11, | ||
8 | "column": 11 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 14, | ||
12 | "column": 3 | ||
13 | } | ||
14 | } | ||
15 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/auth/Pricing.json b/src/i18n/messages/src/components/auth/Pricing.json index f711a55b4..f15617ca5 100644 --- a/src/i18n/messages/src/components/auth/Pricing.json +++ b/src/i18n/messages/src/components/auth/Pricing.json | |||
@@ -1,53 +1,118 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "id": "pricing.headline", | 3 | "id": "pricing.trial.headline", |
4 | "defaultMessage": "!!!Support Franz", | 4 | "defaultMessage": "!!!Franz Professional", |
5 | "file": "src/components/auth/Pricing.js", | 5 | "file": "src/components/auth/Pricing.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 13, | 7 | "line": 15, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 16, | 11 | "line": 18, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
15 | { | 15 | { |
16 | "id": "pricing.support.label", | 16 | "id": "pricing.trial.subheadline", |
17 | "defaultMessage": "!!!Select your support plan", | 17 | "defaultMessage": "!!!Your personal welcome offer:", |
18 | "file": "src/components/auth/Pricing.js", | 18 | "file": "src/components/auth/Pricing.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 17, | 20 | "line": 19, |
21 | "column": 23 | 21 | "column": 17 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 20, | 24 | "line": 22, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
28 | { | 28 | { |
29 | "id": "pricing.submit.label", | 29 | "id": "pricing.trial.terms.headline", |
30 | "defaultMessage": "!!!Support the development of Franz", | 30 | "defaultMessage": "!!!No strings attached", |
31 | "file": "src/components/auth/Pricing.js", | 31 | "file": "src/components/auth/Pricing.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 21, | 33 | "line": 23, |
34 | "column": 29 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 26, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "pricing.trial.terms.noCreditCard", | ||
43 | "defaultMessage": "!!!No credit card required", | ||
44 | "file": "src/components/auth/Pricing.js", | ||
45 | "start": { | ||
46 | "line": 27, | ||
47 | "column": 16 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 30, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "pricing.trial.terms.automaticTrialEnd", | ||
56 | "defaultMessage": "!!!Your free trial ends automatically after 14 days", | ||
57 | "file": "src/components/auth/Pricing.js", | ||
58 | "start": { | ||
59 | "line": 31, | ||
34 | "column": 21 | 60 | "column": 21 |
35 | }, | 61 | }, |
36 | "end": { | 62 | "end": { |
37 | "line": 24, | 63 | "line": 34, |
64 | "column": 3 | ||
65 | } | ||
66 | }, | ||
67 | { | ||
68 | "id": "pricing.trial.error", | ||
69 | "defaultMessage": "!!!Sorry, we could not activate your trial!", | ||
70 | "file": "src/components/auth/Pricing.js", | ||
71 | "start": { | ||
72 | "line": 35, | ||
73 | "column": 19 | ||
74 | }, | ||
75 | "end": { | ||
76 | "line": 38, | ||
77 | "column": 3 | ||
78 | } | ||
79 | }, | ||
80 | { | ||
81 | "id": "pricing.trial.cta.accept", | ||
82 | "defaultMessage": "!!!Yes, upgrade my account to Franz Professional", | ||
83 | "file": "src/components/auth/Pricing.js", | ||
84 | "start": { | ||
85 | "line": 39, | ||
86 | "column": 13 | ||
87 | }, | ||
88 | "end": { | ||
89 | "line": 42, | ||
90 | "column": 3 | ||
91 | } | ||
92 | }, | ||
93 | { | ||
94 | "id": "pricing.trial.cta.skip", | ||
95 | "defaultMessage": "!!!Continue to Franz", | ||
96 | "file": "src/components/auth/Pricing.js", | ||
97 | "start": { | ||
98 | "line": 43, | ||
99 | "column": 11 | ||
100 | }, | ||
101 | "end": { | ||
102 | "line": 46, | ||
38 | "column": 3 | 103 | "column": 3 |
39 | } | 104 | } |
40 | }, | 105 | }, |
41 | { | 106 | { |
42 | "id": "pricing.link.skipPayment", | 107 | "id": "pricing.trial.features.headline", |
43 | "defaultMessage": "!!!I don't want to support the development of Franz.", | 108 | "defaultMessage": "!!!Franz Professional includes:", |
44 | "file": "src/components/auth/Pricing.js", | 109 | "file": "src/components/auth/Pricing.js", |
45 | "start": { | 110 | "start": { |
46 | "line": 25, | 111 | "line": 47, |
47 | "column": 15 | 112 | "column": 20 |
48 | }, | 113 | }, |
49 | "end": { | 114 | "end": { |
50 | "line": 28, | 115 | "line": 50, |
51 | "column": 3 | 116 | "column": 3 |
52 | } | 117 | } |
53 | } | 118 | } |
diff --git a/src/i18n/messages/src/components/auth/Signup.json b/src/i18n/messages/src/components/auth/Signup.json index a09745048..2ea71e5ff 100644 --- a/src/i18n/messages/src/components/auth/Signup.json +++ b/src/i18n/messages/src/components/auth/Signup.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Sign up", | 4 | "defaultMessage": "!!!Sign up", |
5 | "file": "src/components/auth/Signup.js", | 5 | "file": "src/components/auth/Signup.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 18, | 7 | "line": 17, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 21, | 11 | "line": 20, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Firstname", | 17 | "defaultMessage": "!!!Firstname", |
18 | "file": "src/components/auth/Signup.js", | 18 | "file": "src/components/auth/Signup.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 22, | 20 | "line": 21, |
21 | "column": 18 | 21 | "column": 18 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 25, | 24 | "line": 24, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Lastname", | 30 | "defaultMessage": "!!!Lastname", |
31 | "file": "src/components/auth/Signup.js", | 31 | "file": "src/components/auth/Signup.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 26, | 33 | "line": 25, |
34 | "column": 17 | 34 | "column": 17 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 29, | 37 | "line": 28, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,24 +43,11 @@ | |||
43 | "defaultMessage": "!!!Email address", | 43 | "defaultMessage": "!!!Email address", |
44 | "file": "src/components/auth/Signup.js", | 44 | "file": "src/components/auth/Signup.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 30, | 46 | "line": 29, |
47 | "column": 14 | 47 | "column": 14 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 33, | 50 | "line": 32, |
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "signup.company.label", | ||
56 | "defaultMessage": "!!!Company", | ||
57 | "file": "src/components/auth/Signup.js", | ||
58 | "start": { | ||
59 | "line": 34, | ||
60 | "column": 16 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 37, | ||
64 | "column": 3 | 51 | "column": 3 |
65 | } | 52 | } |
66 | }, | 53 | }, |
@@ -69,11 +56,11 @@ | |||
69 | "defaultMessage": "!!!Password", | 56 | "defaultMessage": "!!!Password", |
70 | "file": "src/components/auth/Signup.js", | 57 | "file": "src/components/auth/Signup.js", |
71 | "start": { | 58 | "start": { |
72 | "line": 38, | 59 | "line": 37, |
73 | "column": 17 | 60 | "column": 17 |
74 | }, | 61 | }, |
75 | "end": { | 62 | "end": { |
76 | "line": 41, | 63 | "line": 40, |
77 | "column": 3 | 64 | "column": 3 |
78 | } | 65 | } |
79 | }, | 66 | }, |
@@ -82,11 +69,11 @@ | |||
82 | "defaultMessage": "!!!By creating a Franz account you accept the", | 69 | "defaultMessage": "!!!By creating a Franz account you accept the", |
83 | "file": "src/components/auth/Signup.js", | 70 | "file": "src/components/auth/Signup.js", |
84 | "start": { | 71 | "start": { |
85 | "line": 42, | 72 | "line": 41, |
86 | "column": 13 | 73 | "column": 13 |
87 | }, | 74 | }, |
88 | "end": { | 75 | "end": { |
89 | "line": 45, | 76 | "line": 44, |
90 | "column": 3 | 77 | "column": 3 |
91 | } | 78 | } |
92 | }, | 79 | }, |
@@ -95,11 +82,11 @@ | |||
95 | "defaultMessage": "!!!Terms of service", | 82 | "defaultMessage": "!!!Terms of service", |
96 | "file": "src/components/auth/Signup.js", | 83 | "file": "src/components/auth/Signup.js", |
97 | "start": { | 84 | "start": { |
98 | "line": 46, | 85 | "line": 45, |
99 | "column": 9 | 86 | "column": 9 |
100 | }, | 87 | }, |
101 | "end": { | 88 | "end": { |
102 | "line": 49, | 89 | "line": 48, |
103 | "column": 3 | 90 | "column": 3 |
104 | } | 91 | } |
105 | }, | 92 | }, |
@@ -108,11 +95,11 @@ | |||
108 | "defaultMessage": "!!!Privacy Statement", | 95 | "defaultMessage": "!!!Privacy Statement", |
109 | "file": "src/components/auth/Signup.js", | 96 | "file": "src/components/auth/Signup.js", |
110 | "start": { | 97 | "start": { |
111 | "line": 50, | 98 | "line": 49, |
112 | "column": 11 | 99 | "column": 11 |
113 | }, | 100 | }, |
114 | "end": { | 101 | "end": { |
115 | "line": 53, | 102 | "line": 52, |
116 | "column": 3 | 103 | "column": 3 |
117 | } | 104 | } |
118 | }, | 105 | }, |
@@ -121,11 +108,11 @@ | |||
121 | "defaultMessage": "!!!Create account", | 108 | "defaultMessage": "!!!Create account", |
122 | "file": "src/components/auth/Signup.js", | 109 | "file": "src/components/auth/Signup.js", |
123 | "start": { | 110 | "start": { |
124 | "line": 54, | 111 | "line": 53, |
125 | "column": 21 | 112 | "column": 21 |
126 | }, | 113 | }, |
127 | "end": { | 114 | "end": { |
128 | "line": 57, | 115 | "line": 56, |
129 | "column": 3 | 116 | "column": 3 |
130 | } | 117 | } |
131 | }, | 118 | }, |
@@ -134,11 +121,11 @@ | |||
134 | "defaultMessage": "!!!Already have an account, sign in?", | 121 | "defaultMessage": "!!!Already have an account, sign in?", |
135 | "file": "src/components/auth/Signup.js", | 122 | "file": "src/components/auth/Signup.js", |
136 | "start": { | 123 | "start": { |
137 | "line": 58, | 124 | "line": 57, |
138 | "column": 13 | 125 | "column": 13 |
139 | }, | 126 | }, |
140 | "end": { | 127 | "end": { |
141 | "line": 61, | 128 | "line": 60, |
142 | "column": 3 | 129 | "column": 3 |
143 | } | 130 | } |
144 | }, | 131 | }, |
@@ -147,11 +134,11 @@ | |||
147 | "defaultMessage": "!!!A user with that email address already exists", | 134 | "defaultMessage": "!!!A user with that email address already exists", |
148 | "file": "src/components/auth/Signup.js", | 135 | "file": "src/components/auth/Signup.js", |
149 | "start": { | 136 | "start": { |
150 | "line": 62, | 137 | "line": 61, |
151 | "column": 18 | 138 | "column": 18 |
152 | }, | 139 | }, |
153 | "end": { | 140 | "end": { |
154 | "line": 65, | 141 | "line": 64, |
155 | "column": 3 | 142 | "column": 3 |
156 | } | 143 | } |
157 | } | 144 | } |
diff --git a/src/i18n/messages/src/components/layout/AppLayout.json b/src/i18n/messages/src/components/layout/AppLayout.json index 190c5dff7..44cf4fab9 100644 --- a/src/i18n/messages/src/components/layout/AppLayout.json +++ b/src/i18n/messages/src/components/layout/AppLayout.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Your services have been updated.", | 4 | "defaultMessage": "!!!Your services have been updated.", |
5 | "file": "src/components/layout/AppLayout.js", | 5 | "file": "src/components/layout/AppLayout.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 26, | 7 | "line": 28, |
8 | "column": 19 | 8 | "column": 19 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 29, | 11 | "line": 31, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Reload services", | 17 | "defaultMessage": "!!!Reload services", |
18 | "file": "src/components/layout/AppLayout.js", | 18 | "file": "src/components/layout/AppLayout.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 30, | 20 | "line": 32, |
21 | "column": 24 | 21 | "column": 24 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 33, | 24 | "line": 35, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Could not load services and user information", | 30 | "defaultMessage": "!!!Could not load services and user information", |
31 | "file": "src/components/layout/AppLayout.js", | 31 | "file": "src/components/layout/AppLayout.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 34, | 33 | "line": 36, |
34 | "column": 26 | 34 | "column": 26 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 37, | 37 | "line": 39, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | } | 40 | } |
diff --git a/src/i18n/messages/src/components/services/content/ServiceRestricted.json b/src/i18n/messages/src/components/services/content/ServiceRestricted.json new file mode 100644 index 000000000..c1984afe3 --- /dev/null +++ b/src/i18n/messages/src/components/services/content/ServiceRestricted.json | |||
@@ -0,0 +1,67 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "service.restrictedHandler.serviceLimit.headline", | ||
4 | "defaultMessage": "!!!You have reached your service limit.", | ||
5 | "file": "src/components/services/content/ServiceRestricted.js", | ||
6 | "start": { | ||
7 | "line": 11, | ||
8 | "column": 24 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 14, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "service.restrictedHandler.serviceLimit.text", | ||
17 | "defaultMessage": "!!!Please upgrade your account to use more than {count} services.", | ||
18 | "file": "src/components/services/content/ServiceRestricted.js", | ||
19 | "start": { | ||
20 | "line": 15, | ||
21 | "column": 20 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 18, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "service.restrictedHandler.customUrl.headline", | ||
30 | "defaultMessage": "!!!Franz Professional Plan required", | ||
31 | "file": "src/components/services/content/ServiceRestricted.js", | ||
32 | "start": { | ||
33 | "line": 19, | ||
34 | "column": 21 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 22, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "service.restrictedHandler.customUrl.text", | ||
43 | "defaultMessage": "!!!Please upgrade to the Franz Professional plan to use custom urls & self hosted services.", | ||
44 | "file": "src/components/services/content/ServiceRestricted.js", | ||
45 | "start": { | ||
46 | "line": 23, | ||
47 | "column": 17 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 26, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "service.restrictedHandler.action", | ||
56 | "defaultMessage": "!!!Upgrade Account", | ||
57 | "file": "src/components/services/content/ServiceRestricted.js", | ||
58 | "start": { | ||
59 | "line": 27, | ||
60 | "column": 10 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 30, | ||
64 | "column": 3 | ||
65 | } | ||
66 | } | ||
67 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/services/content/Services.json b/src/i18n/messages/src/components/services/content/Services.json index 884ab0c90..eb466c0ac 100644 --- a/src/i18n/messages/src/components/services/content/Services.json +++ b/src/i18n/messages/src/components/services/content/Services.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Welcome to Franz", | 4 | "defaultMessage": "!!!Welcome to Franz", |
5 | "file": "src/components/services/content/Services.js", | 5 | "file": "src/components/services/content/Services.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 11, | 7 | "line": 14, |
8 | "column": 11 | 8 | "column": 11 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 14, | 11 | "line": 17, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Get started", | 17 | "defaultMessage": "!!!Get started", |
18 | "file": "src/components/services/content/Services.js", | 18 | "file": "src/components/services/content/Services.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 15, | 20 | "line": 18, |
21 | "column": 14 | 21 | "column": 14 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 18, | 24 | "line": 21, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | } | 27 | } |
diff --git a/src/i18n/messages/src/components/settings/account/AccountDashboard.json b/src/i18n/messages/src/components/settings/account/AccountDashboard.json index 4969db910..06d53e41d 100644 --- a/src/i18n/messages/src/components/settings/account/AccountDashboard.json +++ b/src/i18n/messages/src/components/settings/account/AccountDashboard.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Account", | 4 | "defaultMessage": "!!!Account", |
5 | "file": "src/components/settings/account/AccountDashboard.js", | 5 | "file": "src/components/settings/account/AccountDashboard.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 14, | 7 | "line": 18, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 17, | 11 | "line": 21, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,21 +17,8 @@ | |||
17 | "defaultMessage": "!!!Your Subscription", | 17 | "defaultMessage": "!!!Your Subscription", |
18 | "file": "src/components/settings/account/AccountDashboard.js", | 18 | "file": "src/components/settings/account/AccountDashboard.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 18, | ||
21 | "column": 24 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 21, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "settings.account.headlineUpgrade", | ||
30 | "defaultMessage": "!!!Upgrade your Account", | ||
31 | "file": "src/components/settings/account/AccountDashboard.js", | ||
32 | "start": { | ||
33 | "line": 22, | 20 | "line": 22, |
34 | "column": 19 | 21 | "column": 24 |
35 | }, | 22 | }, |
36 | "end": { | 23 | "end": { |
37 | "line": 25, | 24 | "line": 25, |
@@ -65,15 +52,28 @@ | |||
65 | } | 52 | } |
66 | }, | 53 | }, |
67 | { | 54 | { |
55 | "id": "settings.account.upgradeToPro.label", | ||
56 | "defaultMessage": "!!!Upgrade to Franz Professional", | ||
57 | "file": "src/components/settings/account/AccountDashboard.js", | ||
58 | "start": { | ||
59 | "line": 34, | ||
60 | "column": 23 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 37, | ||
64 | "column": 3 | ||
65 | } | ||
66 | }, | ||
67 | { | ||
68 | "id": "settings.account.accountType.basic", | 68 | "id": "settings.account.accountType.basic", |
69 | "defaultMessage": "!!!Basic Account", | 69 | "defaultMessage": "!!!Basic Account", |
70 | "file": "src/components/settings/account/AccountDashboard.js", | 70 | "file": "src/components/settings/account/AccountDashboard.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 34, | 72 | "line": 38, |
73 | "column": 20 | 73 | "column": 20 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 37, | 76 | "line": 41, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Premium Supporter Account", | 82 | "defaultMessage": "!!!Premium Supporter Account", |
83 | "file": "src/components/settings/account/AccountDashboard.js", | 83 | "file": "src/components/settings/account/AccountDashboard.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 38, | 85 | "line": 42, |
86 | "column": 22 | 86 | "column": 22 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 41, | 89 | "line": 45, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Edit Account", | 95 | "defaultMessage": "!!!Edit Account", |
96 | "file": "src/components/settings/account/AccountDashboard.js", | 96 | "file": "src/components/settings/account/AccountDashboard.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 42, | 98 | "line": 46, |
99 | "column": 21 | 99 | "column": 21 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 45, | 102 | "line": 49, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | }, | 105 | }, |
@@ -108,11 +108,11 @@ | |||
108 | "defaultMessage": "!!Invoices", | 108 | "defaultMessage": "!!Invoices", |
109 | "file": "src/components/settings/account/AccountDashboard.js", | 109 | "file": "src/components/settings/account/AccountDashboard.js", |
110 | "start": { | 110 | "start": { |
111 | "line": 46, | 111 | "line": 50, |
112 | "column": 18 | 112 | "column": 18 |
113 | }, | 113 | }, |
114 | "end": { | 114 | "end": { |
115 | "line": 49, | 115 | "line": 53, |
116 | "column": 3 | 116 | "column": 3 |
117 | } | 117 | } |
118 | }, | 118 | }, |
@@ -121,11 +121,11 @@ | |||
121 | "defaultMessage": "!!!Download", | 121 | "defaultMessage": "!!!Download", |
122 | "file": "src/components/settings/account/AccountDashboard.js", | 122 | "file": "src/components/settings/account/AccountDashboard.js", |
123 | "start": { | 123 | "start": { |
124 | "line": 50, | 124 | "line": 54, |
125 | "column": 19 | 125 | "column": 19 |
126 | }, | 126 | }, |
127 | "end": { | 127 | "end": { |
128 | "line": 53, | 128 | "line": 57, |
129 | "column": 3 | 129 | "column": 3 |
130 | } | 130 | } |
131 | }, | 131 | }, |
@@ -134,11 +134,11 @@ | |||
134 | "defaultMessage": "!!!Could not load user information", | 134 | "defaultMessage": "!!!Could not load user information", |
135 | "file": "src/components/settings/account/AccountDashboard.js", | 135 | "file": "src/components/settings/account/AccountDashboard.js", |
136 | "start": { | 136 | "start": { |
137 | "line": 54, | 137 | "line": 58, |
138 | "column": 25 | 138 | "column": 25 |
139 | }, | 139 | }, |
140 | "end": { | 140 | "end": { |
141 | "line": 57, | 141 | "line": 61, |
142 | "column": 3 | 142 | "column": 3 |
143 | } | 143 | } |
144 | }, | 144 | }, |
@@ -147,11 +147,11 @@ | |||
147 | "defaultMessage": "!!!Try again", | 147 | "defaultMessage": "!!!Try again", |
148 | "file": "src/components/settings/account/AccountDashboard.js", | 148 | "file": "src/components/settings/account/AccountDashboard.js", |
149 | "start": { | 149 | "start": { |
150 | "line": 58, | 150 | "line": 62, |
151 | "column": 28 | 151 | "column": 28 |
152 | }, | 152 | }, |
153 | "end": { | 153 | "end": { |
154 | "line": 61, | 154 | "line": 65, |
155 | "column": 3 | 155 | "column": 3 |
156 | } | 156 | } |
157 | }, | 157 | }, |
@@ -160,11 +160,11 @@ | |||
160 | "defaultMessage": "!!!Delete account", | 160 | "defaultMessage": "!!!Delete account", |
161 | "file": "src/components/settings/account/AccountDashboard.js", | 161 | "file": "src/components/settings/account/AccountDashboard.js", |
162 | "start": { | 162 | "start": { |
163 | "line": 62, | 163 | "line": 66, |
164 | "column": 17 | 164 | "column": 17 |
165 | }, | 165 | }, |
166 | "end": { | 166 | "end": { |
167 | "line": 65, | 167 | "line": 69, |
168 | "column": 3 | 168 | "column": 3 |
169 | } | 169 | } |
170 | }, | 170 | }, |
@@ -173,11 +173,11 @@ | |||
173 | "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", | 173 | "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", |
174 | "file": "src/components/settings/account/AccountDashboard.js", | 174 | "file": "src/components/settings/account/AccountDashboard.js", |
175 | "start": { | 175 | "start": { |
176 | "line": 66, | 176 | "line": 70, |
177 | "column": 14 | 177 | "column": 14 |
178 | }, | 178 | }, |
179 | "end": { | 179 | "end": { |
180 | "line": 69, | 180 | "line": 73, |
181 | "column": 3 | 181 | "column": 3 |
182 | } | 182 | } |
183 | }, | 183 | }, |
@@ -186,11 +186,63 @@ | |||
186 | "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", | 186 | "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", |
187 | "file": "src/components/settings/account/AccountDashboard.js", | 187 | "file": "src/components/settings/account/AccountDashboard.js", |
188 | "start": { | 188 | "start": { |
189 | "line": 70, | 189 | "line": 74, |
190 | "column": 19 | 190 | "column": 19 |
191 | }, | 191 | }, |
192 | "end": { | 192 | "end": { |
193 | "line": 73, | 193 | "line": 77, |
194 | "column": 3 | ||
195 | } | ||
196 | }, | ||
197 | { | ||
198 | "id": "settings.account.trial", | ||
199 | "defaultMessage": "!!!Free Trial", | ||
200 | "file": "src/components/settings/account/AccountDashboard.js", | ||
201 | "start": { | ||
202 | "line": 78, | ||
203 | "column": 9 | ||
204 | }, | ||
205 | "end": { | ||
206 | "line": 81, | ||
207 | "column": 3 | ||
208 | } | ||
209 | }, | ||
210 | { | ||
211 | "id": "settings.account.yourLicense", | ||
212 | "defaultMessage": "!!!Your Franz License:", | ||
213 | "file": "src/components/settings/account/AccountDashboard.js", | ||
214 | "start": { | ||
215 | "line": 82, | ||
216 | "column": 15 | ||
217 | }, | ||
218 | "end": { | ||
219 | "line": 85, | ||
220 | "column": 3 | ||
221 | } | ||
222 | }, | ||
223 | { | ||
224 | "id": "settings.account.trialEndsIn", | ||
225 | "defaultMessage": "!!!Your free trial ends in {duration}.", | ||
226 | "file": "src/components/settings/account/AccountDashboard.js", | ||
227 | "start": { | ||
228 | "line": 86, | ||
229 | "column": 15 | ||
230 | }, | ||
231 | "end": { | ||
232 | "line": 89, | ||
233 | "column": 3 | ||
234 | } | ||
235 | }, | ||
236 | { | ||
237 | "id": "settings.account.trialUpdateBillingInfo", | ||
238 | "defaultMessage": "!!!Please update your billing info to continue using {license} after your trial period.", | ||
239 | "file": "src/components/settings/account/AccountDashboard.js", | ||
240 | "start": { | ||
241 | "line": 90, | ||
242 | "column": 33 | ||
243 | }, | ||
244 | "end": { | ||
245 | "line": 93, | ||
194 | "column": 3 | 246 | "column": 3 |
195 | } | 247 | } |
196 | } | 248 | } |
diff --git a/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json b/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json index 70a989211..7dfb3ce04 100644 --- a/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json +++ b/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Available services", | 4 | "defaultMessage": "!!!Available services", |
5 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 5 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 13, | 7 | "line": 14, |
8 | "column": 21 | 8 | "column": 21 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 16, | 11 | "line": 17, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Your services", | 17 | "defaultMessage": "!!!Your services", |
18 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 18 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 17, | 20 | "line": 18, |
21 | "column": 16 | 21 | "column": 16 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 20, | 24 | "line": 21, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Your workspaces", | 30 | "defaultMessage": "!!!Your workspaces", |
31 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 31 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 21, | 33 | "line": 22, |
34 | "column": 18 | 34 | "column": 18 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 24, | 37 | "line": 25, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Account", | 43 | "defaultMessage": "!!!Account", |
44 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 44 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 25, | 46 | "line": 26, |
47 | "column": 11 | 47 | "column": 11 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 28, | 50 | "line": 29, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Manage Team", | 56 | "defaultMessage": "!!!Manage Team", |
57 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 57 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 29, | 59 | "line": 30, |
60 | "column": 8 | 60 | "column": 8 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 32, | 63 | "line": 33, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Settings", | 69 | "defaultMessage": "!!!Settings", |
70 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 70 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 33, | 72 | "line": 34, |
73 | "column": 12 | 73 | "column": 12 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 36, | 76 | "line": 37, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Invite Friends", | 82 | "defaultMessage": "!!!Invite Friends", |
83 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 83 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 37, | 85 | "line": 38, |
86 | "column": 17 | 86 | "column": 17 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 40, | 89 | "line": 41, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Logout", | 95 | "defaultMessage": "!!!Logout", |
96 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 96 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 41, | 98 | "line": 42, |
99 | "column": 10 | 99 | "column": 10 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 44, | 102 | "line": 45, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | } | 105 | } |
diff --git a/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json b/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json index 7d9ed3283..8afaaed50 100644 --- a/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json +++ b/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Available Services", | 4 | "defaultMessage": "!!!Available Services", |
5 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 5 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 15, | 7 | "line": 20, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 18, | 11 | "line": 23, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Search service", | 17 | "defaultMessage": "!!!Search service", |
18 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 18 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 19, | 20 | "line": 24, |
21 | "column": 17 | 21 | "column": 17 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 22, | 24 | "line": 27, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Most popular", | 30 | "defaultMessage": "!!!Most popular", |
31 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 31 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 23, | 33 | "line": 28, |
34 | "column": 22 | 34 | "column": 22 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 26, | 37 | "line": 31, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,24 +43,24 @@ | |||
43 | "defaultMessage": "!!!All services", | 43 | "defaultMessage": "!!!All services", |
44 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 44 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 27, | 46 | "line": 32, |
47 | "column": 14 | 47 | "column": 14 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 30, | 50 | "line": 35, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
54 | { | 54 | { |
55 | "id": "settings.recipes.dev", | 55 | "id": "settings.recipes.custom", |
56 | "defaultMessage": "!!!Development", | 56 | "defaultMessage": "!!!Custom Services", |
57 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 57 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 31, | 59 | "line": 36, |
60 | "column": 14 | 60 | "column": 17 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 34, | 63 | "line": 39, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Sorry, but no service matched your search term.", | 69 | "defaultMessage": "!!!Sorry, but no service matched your search term.", |
70 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 70 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 35, | 72 | "line": 40, |
73 | "column": 16 | 73 | "column": 16 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 38, | 76 | "line": 43, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Service successfully added", | 82 | "defaultMessage": "!!!Service successfully added", |
83 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 83 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 39, | 85 | "line": 44, |
86 | "column": 31 | 86 | "column": 31 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 42, | 89 | "line": 47, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,89 @@ | |||
95 | "defaultMessage": "!!!Missing a service?", | 95 | "defaultMessage": "!!!Missing a service?", |
96 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 96 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 43, | 98 | "line": 48, |
99 | "column": 18 | 99 | "column": 18 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 46, | 102 | "line": 51, |
103 | "column": 3 | ||
104 | } | ||
105 | }, | ||
106 | { | ||
107 | "id": "settings.recipes.customService.intro", | ||
108 | "defaultMessage": "!!!To add a custom service, copy the recipe folder into:", | ||
109 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
110 | "start": { | ||
111 | "line": 52, | ||
112 | "column": 21 | ||
113 | }, | ||
114 | "end": { | ||
115 | "line": 55, | ||
116 | "column": 3 | ||
117 | } | ||
118 | }, | ||
119 | { | ||
120 | "id": "settings.recipes.customService.openFolder", | ||
121 | "defaultMessage": "!!!Open directory", | ||
122 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
123 | "start": { | ||
124 | "line": 56, | ||
125 | "column": 14 | ||
126 | }, | ||
127 | "end": { | ||
128 | "line": 59, | ||
129 | "column": 3 | ||
130 | } | ||
131 | }, | ||
132 | { | ||
133 | "id": "settings.recipes.customService.openDevDocs", | ||
134 | "defaultMessage": "!!!Developer Documentation", | ||
135 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
136 | "start": { | ||
137 | "line": 60, | ||
138 | "column": 15 | ||
139 | }, | ||
140 | "end": { | ||
141 | "line": 63, | ||
142 | "column": 3 | ||
143 | } | ||
144 | }, | ||
145 | { | ||
146 | "id": "settings.recipes.customService.headline.customRecipes", | ||
147 | "defaultMessage": "!!!Custom Service Recipes", | ||
148 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
149 | "start": { | ||
150 | "line": 64, | ||
151 | "column": 25 | ||
152 | }, | ||
153 | "end": { | ||
154 | "line": 67, | ||
155 | "column": 3 | ||
156 | } | ||
157 | }, | ||
158 | { | ||
159 | "id": "settings.recipes.customService.headline.communityRecipes", | ||
160 | "defaultMessage": "!!!Community Services", | ||
161 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
162 | "start": { | ||
163 | "line": 68, | ||
164 | "column": 28 | ||
165 | }, | ||
166 | "end": { | ||
167 | "line": 71, | ||
168 | "column": 3 | ||
169 | } | ||
170 | }, | ||
171 | { | ||
172 | "id": "settings.recipes.customService.headline.devRecipes", | ||
173 | "defaultMessage": "!!!Your Development Service Recipes", | ||
174 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
175 | "start": { | ||
176 | "line": 72, | ||
177 | "column": 22 | ||
178 | }, | ||
179 | "end": { | ||
180 | "line": 75, | ||
103 | "column": 3 | 181 | "column": 3 |
104 | } | 182 | } |
105 | } | 183 | } |
diff --git a/src/i18n/messages/src/components/settings/services/EditServiceForm.json b/src/i18n/messages/src/components/settings/services/EditServiceForm.json index 42b741b7a..e66db807d 100644 --- a/src/i18n/messages/src/components/settings/services/EditServiceForm.json +++ b/src/i18n/messages/src/components/settings/services/EditServiceForm.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Save service", | 4 | "defaultMessage": "!!!Save service", |
5 | "file": "src/components/settings/services/EditServiceForm.js", | 5 | "file": "src/components/settings/services/EditServiceForm.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 22, | 7 | "line": 24, |
8 | "column": 15 | 8 | "column": 15 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 25, | 11 | "line": 27, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Delete Service", | 17 | "defaultMessage": "!!!Delete Service", |
18 | "file": "src/components/settings/services/EditServiceForm.js", | 18 | "file": "src/components/settings/services/EditServiceForm.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 26, | 20 | "line": 28, |
21 | "column": 17 | 21 | "column": 17 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 29, | 24 | "line": 31, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Available services", | 30 | "defaultMessage": "!!!Available services", |
31 | "file": "src/components/settings/services/EditServiceForm.js", | 31 | "file": "src/components/settings/services/EditServiceForm.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 30, | 33 | "line": 32, |
34 | "column": 21 | 34 | "column": 21 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 33, | 37 | "line": 35, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Your services", | 43 | "defaultMessage": "!!!Your services", |
44 | "file": "src/components/settings/services/EditServiceForm.js", | 44 | "file": "src/components/settings/services/EditServiceForm.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 34, | 46 | "line": 36, |
47 | "column": 16 | 47 | "column": 16 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 37, | 50 | "line": 39, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Add {name}", | 56 | "defaultMessage": "!!!Add {name}", |
57 | "file": "src/components/settings/services/EditServiceForm.js", | 57 | "file": "src/components/settings/services/EditServiceForm.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 38, | 59 | "line": 40, |
60 | "column": 22 | 60 | "column": 22 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 41, | 63 | "line": 43, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Edit {name}", | 69 | "defaultMessage": "!!!Edit {name}", |
70 | "file": "src/components/settings/services/EditServiceForm.js", | 70 | "file": "src/components/settings/services/EditServiceForm.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 42, | 72 | "line": 44, |
73 | "column": 23 | 73 | "column": 23 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 45, | 76 | "line": 47, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Hosted", | 82 | "defaultMessage": "!!!Hosted", |
83 | "file": "src/components/settings/services/EditServiceForm.js", | 83 | "file": "src/components/settings/services/EditServiceForm.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 46, | 85 | "line": 48, |
86 | "column": 13 | 86 | "column": 13 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 49, | 89 | "line": 51, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Self hosted ⭐️", | 95 | "defaultMessage": "!!!Self hosted ⭐️", |
96 | "file": "src/components/settings/services/EditServiceForm.js", | 96 | "file": "src/components/settings/services/EditServiceForm.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 50, | 98 | "line": 52, |
99 | "column": 16 | 99 | "column": 16 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 53, | 102 | "line": 55, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | }, | 105 | }, |
@@ -108,11 +108,11 @@ | |||
108 | "defaultMessage": "!!!Use the hosted {name} service.", | 108 | "defaultMessage": "!!!Use the hosted {name} service.", |
109 | "file": "src/components/settings/services/EditServiceForm.js", | 109 | "file": "src/components/settings/services/EditServiceForm.js", |
110 | "start": { | 110 | "start": { |
111 | "line": 54, | 111 | "line": 56, |
112 | "column": 20 | 112 | "column": 20 |
113 | }, | 113 | }, |
114 | "end": { | 114 | "end": { |
115 | "line": 57, | 115 | "line": 59, |
116 | "column": 3 | 116 | "column": 3 |
117 | } | 117 | } |
118 | }, | 118 | }, |
@@ -121,11 +121,11 @@ | |||
121 | "defaultMessage": "!!!Could not validate custom {name} server.", | 121 | "defaultMessage": "!!!Could not validate custom {name} server.", |
122 | "file": "src/components/settings/services/EditServiceForm.js", | 122 | "file": "src/components/settings/services/EditServiceForm.js", |
123 | "start": { | 123 | "start": { |
124 | "line": 58, | 124 | "line": 60, |
125 | "column": 28 | 125 | "column": 28 |
126 | }, | 126 | }, |
127 | "end": { | 127 | "end": { |
128 | "line": 61, | 128 | "line": 63, |
129 | "column": 3 | 129 | "column": 3 |
130 | } | 130 | } |
131 | }, | 131 | }, |
@@ -134,11 +134,11 @@ | |||
134 | "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", | 134 | "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", |
135 | "file": "src/components/settings/services/EditServiceForm.js", | 135 | "file": "src/components/settings/services/EditServiceForm.js", |
136 | "start": { | 136 | "start": { |
137 | "line": 62, | 137 | "line": 64, |
138 | "column": 24 | 138 | "column": 24 |
139 | }, | 139 | }, |
140 | "end": { | 140 | "end": { |
141 | "line": 65, | 141 | "line": 67, |
142 | "column": 3 | 142 | "column": 3 |
143 | } | 143 | } |
144 | }, | 144 | }, |
@@ -147,11 +147,11 @@ | |||
147 | "defaultMessage": "!!!Upgrade your account", | 147 | "defaultMessage": "!!!Upgrade your account", |
148 | "file": "src/components/settings/services/EditServiceForm.js", | 148 | "file": "src/components/settings/services/EditServiceForm.js", |
149 | "start": { | 149 | "start": { |
150 | "line": 66, | 150 | "line": 68, |
151 | "column": 27 | 151 | "column": 27 |
152 | }, | 152 | }, |
153 | "end": { | 153 | "end": { |
154 | "line": 69, | 154 | "line": 71, |
155 | "column": 3 | 155 | "column": 3 |
156 | } | 156 | } |
157 | }, | 157 | }, |
@@ -160,11 +160,11 @@ | |||
160 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", | 160 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", |
161 | "file": "src/components/settings/services/EditServiceForm.js", | 161 | "file": "src/components/settings/services/EditServiceForm.js", |
162 | "start": { | 162 | "start": { |
163 | "line": 70, | 163 | "line": 72, |
164 | "column": 23 | 164 | "column": 23 |
165 | }, | 165 | }, |
166 | "end": { | 166 | "end": { |
167 | "line": 73, | 167 | "line": 75, |
168 | "column": 3 | 168 | "column": 3 |
169 | } | 169 | } |
170 | }, | 170 | }, |
@@ -173,11 +173,11 @@ | |||
173 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", | 173 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", |
174 | "file": "src/components/settings/services/EditServiceForm.js", | 174 | "file": "src/components/settings/services/EditServiceForm.js", |
175 | "start": { | 175 | "start": { |
176 | "line": 74, | 176 | "line": 76, |
177 | "column": 15 | 177 | "column": 15 |
178 | }, | 178 | }, |
179 | "end": { | 179 | "end": { |
180 | "line": 77, | 180 | "line": 79, |
181 | "column": 3 | 181 | "column": 3 |
182 | } | 182 | } |
183 | }, | 183 | }, |
@@ -186,11 +186,11 @@ | |||
186 | "defaultMessage": "!!!Notifications", | 186 | "defaultMessage": "!!!Notifications", |
187 | "file": "src/components/settings/services/EditServiceForm.js", | 187 | "file": "src/components/settings/services/EditServiceForm.js", |
188 | "start": { | 188 | "start": { |
189 | "line": 78, | 189 | "line": 80, |
190 | "column": 25 | 190 | "column": 25 |
191 | }, | 191 | }, |
192 | "end": { | 192 | "end": { |
193 | "line": 81, | 193 | "line": 83, |
194 | "column": 3 | 194 | "column": 3 |
195 | } | 195 | } |
196 | }, | 196 | }, |
@@ -199,11 +199,11 @@ | |||
199 | "defaultMessage": "!!!Unread message badges", | 199 | "defaultMessage": "!!!Unread message badges", |
200 | "file": "src/components/settings/services/EditServiceForm.js", | 200 | "file": "src/components/settings/services/EditServiceForm.js", |
201 | "start": { | 201 | "start": { |
202 | "line": 82, | 202 | "line": 84, |
203 | "column": 18 | 203 | "column": 18 |
204 | }, | 204 | }, |
205 | "end": { | 205 | "end": { |
206 | "line": 85, | 206 | "line": 87, |
207 | "column": 3 | 207 | "column": 3 |
208 | } | 208 | } |
209 | }, | 209 | }, |
@@ -212,11 +212,11 @@ | |||
212 | "defaultMessage": "!!!General", | 212 | "defaultMessage": "!!!General", |
213 | "file": "src/components/settings/services/EditServiceForm.js", | 213 | "file": "src/components/settings/services/EditServiceForm.js", |
214 | "start": { | 214 | "start": { |
215 | "line": 86, | 215 | "line": 88, |
216 | "column": 19 | 216 | "column": 19 |
217 | }, | 217 | }, |
218 | "end": { | 218 | "end": { |
219 | "line": 89, | 219 | "line": 91, |
220 | "column": 3 | 220 | "column": 3 |
221 | } | 221 | } |
222 | }, | 222 | }, |
@@ -225,11 +225,11 @@ | |||
225 | "defaultMessage": "!!!Delete", | 225 | "defaultMessage": "!!!Delete", |
226 | "file": "src/components/settings/services/EditServiceForm.js", | 226 | "file": "src/components/settings/services/EditServiceForm.js", |
227 | "start": { | 227 | "start": { |
228 | "line": 90, | 228 | "line": 92, |
229 | "column": 14 | 229 | "column": 14 |
230 | }, | 230 | }, |
231 | "end": { | 231 | "end": { |
232 | "line": 93, | 232 | "line": 95, |
233 | "column": 3 | 233 | "column": 3 |
234 | } | 234 | } |
235 | }, | 235 | }, |
@@ -238,11 +238,11 @@ | |||
238 | "defaultMessage": "!!!Drop your image, or click here", | 238 | "defaultMessage": "!!!Drop your image, or click here", |
239 | "file": "src/components/settings/services/EditServiceForm.js", | 239 | "file": "src/components/settings/services/EditServiceForm.js", |
240 | "start": { | 240 | "start": { |
241 | "line": 94, | 241 | "line": 96, |
242 | "column": 14 | 242 | "column": 14 |
243 | }, | 243 | }, |
244 | "end": { | 244 | "end": { |
245 | "line": 97, | 245 | "line": 99, |
246 | "column": 3 | 246 | "column": 3 |
247 | } | 247 | } |
248 | }, | 248 | }, |
@@ -251,11 +251,11 @@ | |||
251 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", | 251 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", |
252 | "file": "src/components/settings/services/EditServiceForm.js", | 252 | "file": "src/components/settings/services/EditServiceForm.js", |
253 | "start": { | 253 | "start": { |
254 | "line": 98, | 254 | "line": 100, |
255 | "column": 17 | 255 | "column": 17 |
256 | }, | 256 | }, |
257 | "end": { | 257 | "end": { |
258 | "line": 101, | 258 | "line": 103, |
259 | "column": 3 | 259 | "column": 3 |
260 | } | 260 | } |
261 | }, | 261 | }, |
@@ -264,11 +264,11 @@ | |||
264 | "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", | 264 | "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", |
265 | "file": "src/components/settings/services/EditServiceForm.js", | 265 | "file": "src/components/settings/services/EditServiceForm.js", |
266 | "start": { | 266 | "start": { |
267 | "line": 102, | 267 | "line": 104, |
268 | "column": 20 | 268 | "column": 20 |
269 | }, | 269 | }, |
270 | "end": { | 270 | "end": { |
271 | "line": 105, | 271 | "line": 107, |
272 | "column": 3 | 272 | "column": 3 |
273 | } | 273 | } |
274 | }, | 274 | }, |
@@ -277,11 +277,11 @@ | |||
277 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", | 277 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", |
278 | "file": "src/components/settings/services/EditServiceForm.js", | 278 | "file": "src/components/settings/services/EditServiceForm.js", |
279 | "start": { | 279 | "start": { |
280 | "line": 106, | 280 | "line": 108, |
281 | "column": 13 | 281 | "column": 13 |
282 | }, | 282 | }, |
283 | "end": { | 283 | "end": { |
284 | "line": 109, | 284 | "line": 111, |
285 | "column": 3 | 285 | "column": 3 |
286 | } | 286 | } |
287 | } | 287 | } |
diff --git a/src/i18n/messages/src/components/settings/services/ServicesDashboard.json b/src/i18n/messages/src/components/settings/services/ServicesDashboard.json index 3803c6512..fa661ea2f 100644 --- a/src/i18n/messages/src/components/settings/services/ServicesDashboard.json +++ b/src/i18n/messages/src/components/settings/services/ServicesDashboard.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Your services", | 4 | "defaultMessage": "!!!Your services", |
5 | "file": "src/components/settings/services/ServicesDashboard.js", | 5 | "file": "src/components/settings/services/ServicesDashboard.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 14, | 7 | "line": 15, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 17, | 11 | "line": 18, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Search service", | 17 | "defaultMessage": "!!!Search service", |
18 | "file": "src/components/settings/services/ServicesDashboard.js", | 18 | "file": "src/components/settings/services/ServicesDashboard.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 18, | 20 | "line": 19, |
21 | "column": 17 | 21 | "column": 17 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 21, | 24 | "line": 22, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!You haven't added any services yet.", | 30 | "defaultMessage": "!!!You haven't added any services yet.", |
31 | "file": "src/components/settings/services/ServicesDashboard.js", | 31 | "file": "src/components/settings/services/ServicesDashboard.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 22, | 33 | "line": 23, |
34 | "column": 19 | 34 | "column": 19 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 25, | 37 | "line": 26, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Sorry, but no service matched your search term.", | 43 | "defaultMessage": "!!!Sorry, but no service matched your search term.", |
44 | "file": "src/components/settings/services/ServicesDashboard.js", | 44 | "file": "src/components/settings/services/ServicesDashboard.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 26, | 46 | "line": 27, |
47 | "column": 18 | 47 | "column": 18 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 29, | 50 | "line": 30, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Discover services", | 56 | "defaultMessage": "!!!Discover services", |
57 | "file": "src/components/settings/services/ServicesDashboard.js", | 57 | "file": "src/components/settings/services/ServicesDashboard.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 30, | 59 | "line": 31, |
60 | "column": 20 | 60 | "column": 20 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 33, | 63 | "line": 34, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Could not load your services", | 69 | "defaultMessage": "!!!Could not load your services", |
70 | "file": "src/components/settings/services/ServicesDashboard.js", | 70 | "file": "src/components/settings/services/ServicesDashboard.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 34, | 72 | "line": 35, |
73 | "column": 25 | 73 | "column": 25 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 37, | 76 | "line": 38, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Try again", | 82 | "defaultMessage": "!!!Try again", |
83 | "file": "src/components/settings/services/ServicesDashboard.js", | 83 | "file": "src/components/settings/services/ServicesDashboard.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 38, | 85 | "line": 39, |
86 | "column": 21 | 86 | "column": 21 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 41, | 89 | "line": 42, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Your changes have been saved", | 95 | "defaultMessage": "!!!Your changes have been saved", |
96 | "file": "src/components/settings/services/ServicesDashboard.js", | 96 | "file": "src/components/settings/services/ServicesDashboard.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 42, | 98 | "line": 43, |
99 | "column": 15 | 99 | "column": 15 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 45, | 102 | "line": 46, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | }, | 105 | }, |
@@ -108,11 +108,11 @@ | |||
108 | "defaultMessage": "!!!Service has been deleted", | 108 | "defaultMessage": "!!!Service has been deleted", |
109 | "file": "src/components/settings/services/ServicesDashboard.js", | 109 | "file": "src/components/settings/services/ServicesDashboard.js", |
110 | "start": { | 110 | "start": { |
111 | "line": 46, | 111 | "line": 47, |
112 | "column": 15 | 112 | "column": 15 |
113 | }, | 113 | }, |
114 | "end": { | 114 | "end": { |
115 | "line": 49, | 115 | "line": 50, |
116 | "column": 3 | 116 | "column": 3 |
117 | } | 117 | } |
118 | } | 118 | } |
diff --git a/src/i18n/messages/src/components/subscription/SubscriptionForm.json b/src/i18n/messages/src/components/subscription/SubscriptionForm.json index f98eb986f..6d235254e 100644 --- a/src/i18n/messages/src/components/subscription/SubscriptionForm.json +++ b/src/i18n/messages/src/components/subscription/SubscriptionForm.json | |||
@@ -1,183 +1,53 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "id": "subscription.submit.label", | 3 | "id": "subscription.cta.choosePlan", |
4 | "defaultMessage": "!!!Support the development of Franz", | 4 | "defaultMessage": "!!!Choose your plan", |
5 | "file": "src/components/subscription/SubscriptionForm.js", | 5 | "file": "src/components/subscription/SubscriptionForm.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 14, | 7 | "line": 13, |
8 | "column": 21 | 8 | "column": 21 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 17, | 11 | "line": 16, |
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "subscription.paymentSessionError", | ||
17 | "defaultMessage": "!!!Could not initialize payment form", | ||
18 | "file": "src/components/subscription/SubscriptionForm.js", | ||
19 | "start": { | ||
20 | "line": 18, | ||
21 | "column": 23 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 21, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "subscription.type.free", | ||
30 | "defaultMessage": "!!!free", | ||
31 | "file": "src/components/subscription/SubscriptionForm.js", | ||
32 | "start": { | ||
33 | "line": 22, | ||
34 | "column": 12 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 25, | ||
38 | "column": 3 | 12 | "column": 3 |
39 | } | 13 | } |
40 | }, | 14 | }, |
41 | { | 15 | { |
42 | "id": "subscription.type.month", | 16 | "id": "settings.account.headlineUpgradeAccount", |
43 | "defaultMessage": "!!!month", | 17 | "defaultMessage": "!!!Upgrade your account and get the full Franz experience", |
44 | "file": "src/components/subscription/SubscriptionForm.js", | 18 | "file": "src/components/subscription/SubscriptionForm.js", |
45 | "start": { | 19 | "start": { |
46 | "line": 26, | 20 | "line": 17, |
47 | "column": 15 | 21 | "column": 18 |
48 | }, | 22 | }, |
49 | "end": { | 23 | "end": { |
50 | "line": 29, | 24 | "line": 20, |
51 | "column": 3 | 25 | "column": 3 |
52 | } | 26 | } |
53 | }, | 27 | }, |
54 | { | 28 | { |
55 | "id": "subscription.type.year", | 29 | "id": "subscription.teaser.intro", |
56 | "defaultMessage": "!!!year", | 30 | "defaultMessage": "!!!Franz 5 comes with a wide range of new features to boost up your everyday communication - batteries included. Check out our new plans and find out which one suits you most!", |
57 | "file": "src/components/subscription/SubscriptionForm.js", | 31 | "file": "src/components/subscription/SubscriptionForm.js", |
58 | "start": { | 32 | "start": { |
59 | "line": 30, | 33 | "line": 21, |
60 | "column": 14 | 34 | "column": 14 |
61 | }, | 35 | }, |
62 | "end": { | 36 | "end": { |
63 | "line": 33, | 37 | "line": 24, |
64 | "column": 3 | 38 | "column": 3 |
65 | } | 39 | } |
66 | }, | 40 | }, |
67 | { | 41 | { |
68 | "id": "subscription.includedFeatures", | 42 | "id": "subscription.teaser.includedFeatures", |
69 | "defaultMessage": "!!!The Franz Premium Supporter Account includes", | 43 | "defaultMessage": "!!!Paid Franz Plans include:", |
70 | "file": "src/components/subscription/SubscriptionForm.js", | 44 | "file": "src/components/subscription/SubscriptionForm.js", |
71 | "start": { | 45 | "start": { |
72 | "line": 34, | 46 | "line": 25, |
73 | "column": 20 | 47 | "column": 20 |
74 | }, | 48 | }, |
75 | "end": { | 49 | "end": { |
76 | "line": 37, | 50 | "line": 28, |
77 | "column": 3 | ||
78 | } | ||
79 | }, | ||
80 | { | ||
81 | "id": "subscription.features.onpremise.mattermost", | ||
82 | "defaultMessage": "!!!Add on-premise/hosted services like Mattermost", | ||
83 | "file": "src/components/subscription/SubscriptionForm.js", | ||
84 | "start": { | ||
85 | "line": 38, | ||
86 | "column": 13 | ||
87 | }, | ||
88 | "end": { | ||
89 | "line": 41, | ||
90 | "column": 3 | ||
91 | } | ||
92 | }, | ||
93 | { | ||
94 | "id": "subscription.features.noInterruptions", | ||
95 | "defaultMessage": "!!!No app delays & nagging to upgrade license", | ||
96 | "file": "src/components/subscription/SubscriptionForm.js", | ||
97 | "start": { | ||
98 | "line": 42, | ||
99 | "column": 19 | ||
100 | }, | ||
101 | "end": { | ||
102 | "line": 45, | ||
103 | "column": 3 | ||
104 | } | ||
105 | }, | ||
106 | { | ||
107 | "id": "subscription.features.proxy", | ||
108 | "defaultMessage": "!!!Proxy support for services", | ||
109 | "file": "src/components/subscription/SubscriptionForm.js", | ||
110 | "start": { | ||
111 | "line": 46, | ||
112 | "column": 9 | ||
113 | }, | ||
114 | "end": { | ||
115 | "line": 49, | ||
116 | "column": 3 | ||
117 | } | ||
118 | }, | ||
119 | { | ||
120 | "id": "subscription.features.spellchecker", | ||
121 | "defaultMessage": "!!!Support for Spellchecker", | ||
122 | "file": "src/components/subscription/SubscriptionForm.js", | ||
123 | "start": { | ||
124 | "line": 50, | ||
125 | "column": 16 | ||
126 | }, | ||
127 | "end": { | ||
128 | "line": 53, | ||
129 | "column": 3 | ||
130 | } | ||
131 | }, | ||
132 | { | ||
133 | "id": "subscription.features.workspaces", | ||
134 | "defaultMessage": "!!!Organize your services in workspaces", | ||
135 | "file": "src/components/subscription/SubscriptionForm.js", | ||
136 | "start": { | ||
137 | "line": 54, | ||
138 | "column": 14 | ||
139 | }, | ||
140 | "end": { | ||
141 | "line": 57, | ||
142 | "column": 3 | ||
143 | } | ||
144 | }, | ||
145 | { | ||
146 | "id": "subscription.features.ads", | ||
147 | "defaultMessage": "!!!No ads, ever!", | ||
148 | "file": "src/components/subscription/SubscriptionForm.js", | ||
149 | "start": { | ||
150 | "line": 58, | ||
151 | "column": 7 | ||
152 | }, | ||
153 | "end": { | ||
154 | "line": 61, | ||
155 | "column": 3 | ||
156 | } | ||
157 | }, | ||
158 | { | ||
159 | "id": "subscription.features.comingSoon", | ||
160 | "defaultMessage": "!!!coming soon", | ||
161 | "file": "src/components/subscription/SubscriptionForm.js", | ||
162 | "start": { | ||
163 | "line": 62, | ||
164 | "column": 14 | ||
165 | }, | ||
166 | "end": { | ||
167 | "line": 65, | ||
168 | "column": 3 | ||
169 | } | ||
170 | }, | ||
171 | { | ||
172 | "id": "subscription.euTaxInfo", | ||
173 | "defaultMessage": "!!!EU residents: local sales tax may apply", | ||
174 | "file": "src/components/subscription/SubscriptionForm.js", | ||
175 | "start": { | ||
176 | "line": 66, | ||
177 | "column": 13 | ||
178 | }, | ||
179 | "end": { | ||
180 | "line": 69, | ||
181 | "column": 3 | 51 | "column": 3 |
182 | } | 52 | } |
183 | } | 53 | } |
diff --git a/src/i18n/messages/src/components/subscription/TrialForm.json b/src/i18n/messages/src/components/subscription/TrialForm.json new file mode 100644 index 000000000..8b387ba36 --- /dev/null +++ b/src/i18n/messages/src/components/subscription/TrialForm.json | |||
@@ -0,0 +1,93 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "subscription.cta.activateTrial", | ||
4 | "defaultMessage": "!!!Yes, start the free Franz Professional trial", | ||
5 | "file": "src/components/subscription/TrialForm.js", | ||
6 | "start": { | ||
7 | "line": 14, | ||
8 | "column": 21 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 17, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "subscription.cta.allOptions", | ||
17 | "defaultMessage": "!!!See all options", | ||
18 | "file": "src/components/subscription/TrialForm.js", | ||
19 | "start": { | ||
20 | "line": 18, | ||
21 | "column": 20 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 21, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "settings.account.headlineTrialUpgrade", | ||
30 | "defaultMessage": "!!!Get the free 14 day Franz Professional Trial", | ||
31 | "file": "src/components/subscription/TrialForm.js", | ||
32 | "start": { | ||
33 | "line": 22, | ||
34 | "column": 18 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 25, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "subscription.includedProFeatures", | ||
43 | "defaultMessage": "!!!The Franz Professional Plan includes:", | ||
44 | "file": "src/components/subscription/TrialForm.js", | ||
45 | "start": { | ||
46 | "line": 26, | ||
47 | "column": 20 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 29, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "pricing.trial.terms.headline", | ||
56 | "defaultMessage": "!!!No strings attached", | ||
57 | "file": "src/components/subscription/TrialForm.js", | ||
58 | "start": { | ||
59 | "line": 30, | ||
60 | "column": 29 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 33, | ||
64 | "column": 3 | ||
65 | } | ||
66 | }, | ||
67 | { | ||
68 | "id": "pricing.trial.terms.noCreditCard", | ||
69 | "defaultMessage": "!!!No credit card required", | ||
70 | "file": "src/components/subscription/TrialForm.js", | ||
71 | "start": { | ||
72 | "line": 34, | ||
73 | "column": 16 | ||
74 | }, | ||
75 | "end": { | ||
76 | "line": 37, | ||
77 | "column": 3 | ||
78 | } | ||
79 | }, | ||
80 | { | ||
81 | "id": "pricing.trial.terms.automaticTrialEnd", | ||
82 | "defaultMessage": "!!!Your free trial ends automatically after 14 days", | ||
83 | "file": "src/components/subscription/TrialForm.js", | ||
84 | "start": { | ||
85 | "line": 38, | ||
86 | "column": 21 | ||
87 | }, | ||
88 | "end": { | ||
89 | "line": 41, | ||
90 | "column": 3 | ||
91 | } | ||
92 | } | ||
93 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/ui/FeatureList.json b/src/i18n/messages/src/components/ui/FeatureList.json new file mode 100644 index 000000000..497e299a4 --- /dev/null +++ b/src/i18n/messages/src/components/ui/FeatureList.json | |||
@@ -0,0 +1,132 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "pricing.features.unlimitedServices", | ||
4 | "defaultMessage": "!!!Add unlimited services", | ||
5 | "file": "src/components/ui/FeatureList.js", | ||
6 | "start": { | ||
7 | "line": 8, | ||
8 | "column": 21 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 11, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "pricing.features.spellchecker", | ||
17 | "defaultMessage": "!!!Spellchecker support", | ||
18 | "file": "src/components/ui/FeatureList.js", | ||
19 | "start": { | ||
20 | "line": 12, | ||
21 | "column": 16 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 15, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "pricing.features.workspaces", | ||
30 | "defaultMessage": "!!!Workspaces", | ||
31 | "file": "src/components/ui/FeatureList.js", | ||
32 | "start": { | ||
33 | "line": 16, | ||
34 | "column": 14 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 19, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "pricing.features.customWebsites", | ||
43 | "defaultMessage": "!!!Add Custom Websites", | ||
44 | "file": "src/components/ui/FeatureList.js", | ||
45 | "start": { | ||
46 | "line": 20, | ||
47 | "column": 18 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 23, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "pricing.features.onPremise", | ||
56 | "defaultMessage": "!!!On-premise & other Hosted Services", | ||
57 | "file": "src/components/ui/FeatureList.js", | ||
58 | "start": { | ||
59 | "line": 24, | ||
60 | "column": 13 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 27, | ||
64 | "column": 3 | ||
65 | } | ||
66 | }, | ||
67 | { | ||
68 | "id": "pricing.features.thirdPartyServices", | ||
69 | "defaultMessage": "!!!Install 3rd party services", | ||
70 | "file": "src/components/ui/FeatureList.js", | ||
71 | "start": { | ||
72 | "line": 28, | ||
73 | "column": 22 | ||
74 | }, | ||
75 | "end": { | ||
76 | "line": 31, | ||
77 | "column": 3 | ||
78 | } | ||
79 | }, | ||
80 | { | ||
81 | "id": "pricing.features.serviceProxies", | ||
82 | "defaultMessage": "!!!Service Proxies", | ||
83 | "file": "src/components/ui/FeatureList.js", | ||
84 | "start": { | ||
85 | "line": 32, | ||
86 | "column": 18 | ||
87 | }, | ||
88 | "end": { | ||
89 | "line": 35, | ||
90 | "column": 3 | ||
91 | } | ||
92 | }, | ||
93 | { | ||
94 | "id": "pricing.features.teamManagement", | ||
95 | "defaultMessage": "!!!Team Management", | ||
96 | "file": "src/components/ui/FeatureList.js", | ||
97 | "start": { | ||
98 | "line": 36, | ||
99 | "column": 18 | ||
100 | }, | ||
101 | "end": { | ||
102 | "line": 39, | ||
103 | "column": 3 | ||
104 | } | ||
105 | }, | ||
106 | { | ||
107 | "id": "pricing.features.appDelays", | ||
108 | "defaultMessage": "!!!No Waiting Screens", | ||
109 | "file": "src/components/ui/FeatureList.js", | ||
110 | "start": { | ||
111 | "line": 40, | ||
112 | "column": 13 | ||
113 | }, | ||
114 | "end": { | ||
115 | "line": 43, | ||
116 | "column": 3 | ||
117 | } | ||
118 | }, | ||
119 | { | ||
120 | "id": "pricing.features.adFree", | ||
121 | "defaultMessage": "!!!Forever ad-free", | ||
122 | "file": "src/components/ui/FeatureList.js", | ||
123 | "start": { | ||
124 | "line": 44, | ||
125 | "column": 10 | ||
126 | }, | ||
127 | "end": { | ||
128 | "line": 47, | ||
129 | "column": 3 | ||
130 | } | ||
131 | } | ||
132 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/features/delayApp/Component.json b/src/i18n/messages/src/features/delayApp/Component.json index bacd9444a..0d345a47b 100644 --- a/src/i18n/messages/src/features/delayApp/Component.json +++ b/src/i18n/messages/src/features/delayApp/Component.json | |||
@@ -4,24 +4,50 @@ | |||
4 | "defaultMessage": "!!!Please purchase license to skip waiting", | 4 | "defaultMessage": "!!!Please purchase license to skip waiting", |
5 | "file": "src/features/delayApp/Component.js", | 5 | "file": "src/features/delayApp/Component.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 15, | 7 | "line": 17, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 18, | 11 | "line": 20, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
15 | { | 15 | { |
16 | "id": "feature.delayApp.action", | 16 | "id": "feature.delayApp.trial.headline", |
17 | "defaultMessage": "!!!Get the free Franz Professional 14 day trial and skip the line", | ||
18 | "file": "src/features/delayApp/Component.js", | ||
19 | "start": { | ||
20 | "line": 21, | ||
21 | "column": 17 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 24, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "feature.delayApp.upgrade.action", | ||
17 | "defaultMessage": "!!!Get a Franz Supporter License", | 30 | "defaultMessage": "!!!Get a Franz Supporter License", |
18 | "file": "src/features/delayApp/Component.js", | 31 | "file": "src/features/delayApp/Component.js", |
19 | "start": { | 32 | "start": { |
20 | "line": 19, | 33 | "line": 25, |
21 | "column": 10 | 34 | "column": 10 |
22 | }, | 35 | }, |
23 | "end": { | 36 | "end": { |
24 | "line": 22, | 37 | "line": 28, |
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "feature.delayApp.trial.action", | ||
43 | "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", | ||
44 | "file": "src/features/delayApp/Component.js", | ||
45 | "start": { | ||
46 | "line": 29, | ||
47 | "column": 15 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 32, | ||
25 | "column": 3 | 51 | "column": 3 |
26 | } | 52 | } |
27 | }, | 53 | }, |
@@ -30,11 +56,11 @@ | |||
30 | "defaultMessage": "!!!Franz will continue in {seconds} seconds.", | 56 | "defaultMessage": "!!!Franz will continue in {seconds} seconds.", |
31 | "file": "src/features/delayApp/Component.js", | 57 | "file": "src/features/delayApp/Component.js", |
32 | "start": { | 58 | "start": { |
33 | "line": 23, | 59 | "line": 33, |
34 | "column": 8 | 60 | "column": 8 |
35 | }, | 61 | }, |
36 | "end": { | 62 | "end": { |
37 | "line": 26, | 63 | "line": 36, |
38 | "column": 3 | 64 | "column": 3 |
39 | } | 65 | } |
40 | } | 66 | } |
diff --git a/src/i18n/messages/src/features/serviceLimit/components/AnnouncementScreen.json b/src/i18n/messages/src/features/serviceLimit/components/AnnouncementScreen.json new file mode 100644 index 000000000..e6e3cef99 --- /dev/null +++ b/src/i18n/messages/src/features/serviceLimit/components/AnnouncementScreen.json | |||
@@ -0,0 +1,15 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "feature.announcements.changelog.headline", | ||
4 | "defaultMessage": "!!!Changes in Franz {version}", | ||
5 | "file": "src/features/serviceLimit/components/AnnouncementScreen.js", | ||
6 | "start": { | ||
7 | "line": 20, | ||
8 | "column": 12 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 23, | ||
12 | "column": 3 | ||
13 | } | ||
14 | } | ||
15 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/features/serviceLimit/components/LimitReachedInfobox.json b/src/i18n/messages/src/features/serviceLimit/components/LimitReachedInfobox.json new file mode 100644 index 000000000..df5bc03e8 --- /dev/null +++ b/src/i18n/messages/src/features/serviceLimit/components/LimitReachedInfobox.json | |||
@@ -0,0 +1,28 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "feature.serviceLimit.limitReached", | ||
4 | "defaultMessage": "!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.", | ||
5 | "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", | ||
6 | "start": { | ||
7 | "line": 11, | ||
8 | "column": 16 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 14, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "premiumFeature.button.upgradeAccount", | ||
17 | "defaultMessage": "!!!Upgrade account", | ||
18 | "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", | ||
19 | "start": { | ||
20 | "line": 15, | ||
21 | "column": 10 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 18, | ||
25 | "column": 3 | ||
26 | } | ||
27 | } | ||
28 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/features/shareFranz/Component.json b/src/i18n/messages/src/features/shareFranz/Component.json index 34a43d5a0..79b425b15 100644 --- a/src/i18n/messages/src/features/shareFranz/Component.json +++ b/src/i18n/messages/src/features/shareFranz/Component.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Franz is better together!", | 4 | "defaultMessage": "!!!Franz is better together!", |
5 | "file": "src/features/shareFranz/Component.js", | 5 | "file": "src/features/shareFranz/Component.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 15, | 7 | "line": 16, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 18, | 11 | "line": 19, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Tell your friends and colleagues how awesome Franz is and help us to spread the word.", | 17 | "defaultMessage": "!!!Tell your friends and colleagues how awesome Franz is and help us to spread the word.", |
18 | "file": "src/features/shareFranz/Component.js", | 18 | "file": "src/features/shareFranz/Component.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 19, | 20 | "line": 20, |
21 | "column": 8 | 21 | "column": 8 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 22, | 24 | "line": 23, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Share as email", | 30 | "defaultMessage": "!!!Share as email", |
31 | "file": "src/features/shareFranz/Component.js", | 31 | "file": "src/features/shareFranz/Component.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 23, | 33 | "line": 24, |
34 | "column": 16 | 34 | "column": 16 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 26, | 37 | "line": 27, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Share on Facebook", | 43 | "defaultMessage": "!!!Share on Facebook", |
44 | "file": "src/features/shareFranz/Component.js", | 44 | "file": "src/features/shareFranz/Component.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 27, | 46 | "line": 28, |
47 | "column": 19 | 47 | "column": 19 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 30, | 50 | "line": 31, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Share on Twitter", | 56 | "defaultMessage": "!!!Share on Twitter", |
57 | "file": "src/features/shareFranz/Component.js", | 57 | "file": "src/features/shareFranz/Component.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 31, | 59 | "line": 32, |
60 | "column": 18 | 60 | "column": 18 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 34, | 63 | "line": 35, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", | 69 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", |
70 | "file": "src/features/shareFranz/Component.js", | 70 | "file": "src/features/shareFranz/Component.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 35, | 72 | "line": 36, |
73 | "column": 18 | 73 | "column": 18 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 38, | 76 | "line": 39, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", | 82 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", |
83 | "file": "src/features/shareFranz/Component.js", | 83 | "file": "src/features/shareFranz/Component.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 39, | 85 | "line": 40, |
86 | "column": 20 | 86 | "column": 20 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 42, | 89 | "line": 43, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | } | 92 | } |
diff --git a/src/i18n/messages/src/helpers/plan-helpers.json b/src/i18n/messages/src/helpers/plan-helpers.json new file mode 100644 index 000000000..df8ee19e3 --- /dev/null +++ b/src/i18n/messages/src/helpers/plan-helpers.json | |||
@@ -0,0 +1,54 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "pricing.plan.pro", | ||
4 | "defaultMessage": "!!!Franz Professional", | ||
5 | "file": "src/helpers/plan-helpers.js", | ||
6 | "start": { | ||
7 | "line": 5, | ||
8 | "column": 15 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 8, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "pricing.plan.personal", | ||
17 | "defaultMessage": "!!!Franz Personal", | ||
18 | "file": "src/helpers/plan-helpers.js", | ||
19 | "start": { | ||
20 | "line": 9, | ||
21 | "column": 20 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 12, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "pricing.plan.free", | ||
30 | "defaultMessage": "!!!Franz Free", | ||
31 | "file": "src/helpers/plan-helpers.js", | ||
32 | "start": { | ||
33 | "line": 13, | ||
34 | "column": 16 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 16, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "pricing.plan.legacy", | ||
43 | "defaultMessage": "!!!Franz Premium", | ||
44 | "file": "src/helpers/plan-helpers.js", | ||
45 | "start": { | ||
46 | "line": 17, | ||
47 | "column": 18 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 20, | ||
51 | "column": 3 | ||
52 | } | ||
53 | } | ||
54 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/helpers/pricing-helpers.json b/src/i18n/messages/src/helpers/pricing-helpers.json new file mode 100644 index 000000000..4030a3e3b --- /dev/null +++ b/src/i18n/messages/src/helpers/pricing-helpers.json | |||
@@ -0,0 +1,80 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "pricing.plan.pro-yearly", | ||
4 | "defaultMessage": "!!!Franz Professional Yearly", | ||
5 | "file": "src/helpers/pricing-helpers.js", | ||
6 | "start": { | ||
7 | "line": 5, | ||
8 | "column": 22 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 8, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "pricing.plan.pro-monthly", | ||
17 | "defaultMessage": "!!!Franz Professional Monthly", | ||
18 | "file": "src/helpers/pricing-helpers.js", | ||
19 | "start": { | ||
20 | "line": 9, | ||
21 | "column": 23 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 12, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "pricing.plan.personal-yearly", | ||
30 | "defaultMessage": "!!!Franz Personal Yearly", | ||
31 | "file": "src/helpers/pricing-helpers.js", | ||
32 | "start": { | ||
33 | "line": 13, | ||
34 | "column": 27 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 16, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "pricing.plan.personal-monthly", | ||
43 | "defaultMessage": "!!!Franz Personal Monthly", | ||
44 | "file": "src/helpers/pricing-helpers.js", | ||
45 | "start": { | ||
46 | "line": 17, | ||
47 | "column": 28 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 20, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "pricing.plan.free", | ||
56 | "defaultMessage": "!!!Franz Free", | ||
57 | "file": "src/helpers/pricing-helpers.js", | ||
58 | "start": { | ||
59 | "line": 21, | ||
60 | "column": 16 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 24, | ||
64 | "column": 3 | ||
65 | } | ||
66 | }, | ||
67 | { | ||
68 | "id": "pricing.plan.legacy", | ||
69 | "defaultMessage": "!!!Franz Premium", | ||
70 | "file": "src/helpers/pricing-helpers.js", | ||
71 | "start": { | ||
72 | "line": 25, | ||
73 | "column": 18 | ||
74 | }, | ||
75 | "end": { | ||
76 | "line": 28, | ||
77 | "column": 3 | ||
78 | } | ||
79 | } | ||
80 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/lib/Menu.json b/src/i18n/messages/src/lib/Menu.json index daafb0900..cee46608c 100644 --- a/src/i18n/messages/src/lib/Menu.json +++ b/src/i18n/messages/src/lib/Menu.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Edit", | 4 | "defaultMessage": "!!!Edit", |
5 | "file": "src/lib/Menu.js", | 5 | "file": "src/lib/Menu.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 15, | 7 | "line": 18, |
8 | "column": 8 | 8 | "column": 8 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 18, | 11 | "line": 21, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Undo", | 17 | "defaultMessage": "!!!Undo", |
18 | "file": "src/lib/Menu.js", | 18 | "file": "src/lib/Menu.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 19, | 20 | "line": 22, |
21 | "column": 8 | 21 | "column": 8 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 22, | 24 | "line": 25, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Redo", | 30 | "defaultMessage": "!!!Redo", |
31 | "file": "src/lib/Menu.js", | 31 | "file": "src/lib/Menu.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 23, | 33 | "line": 26, |
34 | "column": 8 | 34 | "column": 8 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 26, | 37 | "line": 29, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Cut", | 43 | "defaultMessage": "!!!Cut", |
44 | "file": "src/lib/Menu.js", | 44 | "file": "src/lib/Menu.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 27, | 46 | "line": 30, |
47 | "column": 7 | 47 | "column": 7 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 30, | 50 | "line": 33, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Copy", | 56 | "defaultMessage": "!!!Copy", |
57 | "file": "src/lib/Menu.js", | 57 | "file": "src/lib/Menu.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 31, | 59 | "line": 34, |
60 | "column": 8 | 60 | "column": 8 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 34, | 63 | "line": 37, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Paste", | 69 | "defaultMessage": "!!!Paste", |
70 | "file": "src/lib/Menu.js", | 70 | "file": "src/lib/Menu.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 35, | 72 | "line": 38, |
73 | "column": 9 | 73 | "column": 9 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 38, | 76 | "line": 41, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Paste And Match Style", | 82 | "defaultMessage": "!!!Paste And Match Style", |
83 | "file": "src/lib/Menu.js", | 83 | "file": "src/lib/Menu.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 39, | 85 | "line": 42, |
86 | "column": 22 | 86 | "column": 22 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 42, | 89 | "line": 45, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Delete", | 95 | "defaultMessage": "!!!Delete", |
96 | "file": "src/lib/Menu.js", | 96 | "file": "src/lib/Menu.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 43, | 98 | "line": 46, |
99 | "column": 10 | 99 | "column": 10 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 46, | 102 | "line": 49, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | }, | 105 | }, |
@@ -108,11 +108,11 @@ | |||
108 | "defaultMessage": "!!!Select All", | 108 | "defaultMessage": "!!!Select All", |
109 | "file": "src/lib/Menu.js", | 109 | "file": "src/lib/Menu.js", |
110 | "start": { | 110 | "start": { |
111 | "line": 47, | 111 | "line": 50, |
112 | "column": 13 | 112 | "column": 13 |
113 | }, | 113 | }, |
114 | "end": { | 114 | "end": { |
115 | "line": 50, | 115 | "line": 53, |
116 | "column": 3 | 116 | "column": 3 |
117 | } | 117 | } |
118 | }, | 118 | }, |
@@ -121,11 +121,11 @@ | |||
121 | "defaultMessage": "!!!Speech", | 121 | "defaultMessage": "!!!Speech", |
122 | "file": "src/lib/Menu.js", | 122 | "file": "src/lib/Menu.js", |
123 | "start": { | 123 | "start": { |
124 | "line": 51, | 124 | "line": 54, |
125 | "column": 10 | 125 | "column": 10 |
126 | }, | 126 | }, |
127 | "end": { | 127 | "end": { |
128 | "line": 54, | 128 | "line": 57, |
129 | "column": 3 | 129 | "column": 3 |
130 | } | 130 | } |
131 | }, | 131 | }, |
@@ -134,11 +134,11 @@ | |||
134 | "defaultMessage": "!!!Start Speaking", | 134 | "defaultMessage": "!!!Start Speaking", |
135 | "file": "src/lib/Menu.js", | 135 | "file": "src/lib/Menu.js", |
136 | "start": { | 136 | "start": { |
137 | "line": 55, | 137 | "line": 58, |
138 | "column": 17 | 138 | "column": 17 |
139 | }, | 139 | }, |
140 | "end": { | 140 | "end": { |
141 | "line": 58, | 141 | "line": 61, |
142 | "column": 3 | 142 | "column": 3 |
143 | } | 143 | } |
144 | }, | 144 | }, |
@@ -147,11 +147,11 @@ | |||
147 | "defaultMessage": "!!!Stop Speaking", | 147 | "defaultMessage": "!!!Stop Speaking", |
148 | "file": "src/lib/Menu.js", | 148 | "file": "src/lib/Menu.js", |
149 | "start": { | 149 | "start": { |
150 | "line": 59, | 150 | "line": 62, |
151 | "column": 16 | 151 | "column": 16 |
152 | }, | 152 | }, |
153 | "end": { | 153 | "end": { |
154 | "line": 62, | 154 | "line": 65, |
155 | "column": 3 | 155 | "column": 3 |
156 | } | 156 | } |
157 | }, | 157 | }, |
@@ -160,11 +160,11 @@ | |||
160 | "defaultMessage": "!!!Start Dictation", | 160 | "defaultMessage": "!!!Start Dictation", |
161 | "file": "src/lib/Menu.js", | 161 | "file": "src/lib/Menu.js", |
162 | "start": { | 162 | "start": { |
163 | "line": 63, | 163 | "line": 66, |
164 | "column": 18 | 164 | "column": 18 |
165 | }, | 165 | }, |
166 | "end": { | 166 | "end": { |
167 | "line": 66, | 167 | "line": 69, |
168 | "column": 3 | 168 | "column": 3 |
169 | } | 169 | } |
170 | }, | 170 | }, |
@@ -173,11 +173,11 @@ | |||
173 | "defaultMessage": "!!!Emoji & Symbols", | 173 | "defaultMessage": "!!!Emoji & Symbols", |
174 | "file": "src/lib/Menu.js", | 174 | "file": "src/lib/Menu.js", |
175 | "start": { | 175 | "start": { |
176 | "line": 67, | 176 | "line": 70, |
177 | "column": 16 | 177 | "column": 16 |
178 | }, | 178 | }, |
179 | "end": { | 179 | "end": { |
180 | "line": 70, | 180 | "line": 73, |
181 | "column": 3 | 181 | "column": 3 |
182 | } | 182 | } |
183 | }, | 183 | }, |
@@ -186,11 +186,11 @@ | |||
186 | "defaultMessage": "!!!Actual Size", | 186 | "defaultMessage": "!!!Actual Size", |
187 | "file": "src/lib/Menu.js", | 187 | "file": "src/lib/Menu.js", |
188 | "start": { | 188 | "start": { |
189 | "line": 71, | 189 | "line": 74, |
190 | "column": 13 | 190 | "column": 13 |
191 | }, | 191 | }, |
192 | "end": { | 192 | "end": { |
193 | "line": 74, | 193 | "line": 77, |
194 | "column": 3 | 194 | "column": 3 |
195 | } | 195 | } |
196 | }, | 196 | }, |
@@ -199,11 +199,11 @@ | |||
199 | "defaultMessage": "!!!Zoom In", | 199 | "defaultMessage": "!!!Zoom In", |
200 | "file": "src/lib/Menu.js", | 200 | "file": "src/lib/Menu.js", |
201 | "start": { | 201 | "start": { |
202 | "line": 75, | 202 | "line": 78, |
203 | "column": 10 | 203 | "column": 10 |
204 | }, | 204 | }, |
205 | "end": { | 205 | "end": { |
206 | "line": 78, | 206 | "line": 81, |
207 | "column": 3 | 207 | "column": 3 |
208 | } | 208 | } |
209 | }, | 209 | }, |
@@ -212,11 +212,11 @@ | |||
212 | "defaultMessage": "!!!Zoom Out", | 212 | "defaultMessage": "!!!Zoom Out", |
213 | "file": "src/lib/Menu.js", | 213 | "file": "src/lib/Menu.js", |
214 | "start": { | 214 | "start": { |
215 | "line": 79, | 215 | "line": 82, |
216 | "column": 11 | 216 | "column": 11 |
217 | }, | 217 | }, |
218 | "end": { | 218 | "end": { |
219 | "line": 82, | 219 | "line": 85, |
220 | "column": 3 | 220 | "column": 3 |
221 | } | 221 | } |
222 | }, | 222 | }, |
@@ -225,11 +225,11 @@ | |||
225 | "defaultMessage": "!!!Enter Full Screen", | 225 | "defaultMessage": "!!!Enter Full Screen", |
226 | "file": "src/lib/Menu.js", | 226 | "file": "src/lib/Menu.js", |
227 | "start": { | 227 | "start": { |
228 | "line": 83, | 228 | "line": 86, |
229 | "column": 19 | 229 | "column": 19 |
230 | }, | 230 | }, |
231 | "end": { | 231 | "end": { |
232 | "line": 86, | 232 | "line": 89, |
233 | "column": 3 | 233 | "column": 3 |
234 | } | 234 | } |
235 | }, | 235 | }, |
@@ -238,11 +238,11 @@ | |||
238 | "defaultMessage": "!!!Exit Full Screen", | 238 | "defaultMessage": "!!!Exit Full Screen", |
239 | "file": "src/lib/Menu.js", | 239 | "file": "src/lib/Menu.js", |
240 | "start": { | 240 | "start": { |
241 | "line": 87, | 241 | "line": 90, |
242 | "column": 18 | 242 | "column": 18 |
243 | }, | 243 | }, |
244 | "end": { | 244 | "end": { |
245 | "line": 90, | 245 | "line": 93, |
246 | "column": 3 | 246 | "column": 3 |
247 | } | 247 | } |
248 | }, | 248 | }, |
@@ -251,11 +251,11 @@ | |||
251 | "defaultMessage": "!!!Toggle Full Screen", | 251 | "defaultMessage": "!!!Toggle Full Screen", |
252 | "file": "src/lib/Menu.js", | 252 | "file": "src/lib/Menu.js", |
253 | "start": { | 253 | "start": { |
254 | "line": 91, | 254 | "line": 94, |
255 | "column": 20 | 255 | "column": 20 |
256 | }, | 256 | }, |
257 | "end": { | 257 | "end": { |
258 | "line": 94, | 258 | "line": 97, |
259 | "column": 3 | 259 | "column": 3 |
260 | } | 260 | } |
261 | }, | 261 | }, |
@@ -264,11 +264,24 @@ | |||
264 | "defaultMessage": "!!!Toggle Developer Tools", | 264 | "defaultMessage": "!!!Toggle Developer Tools", |
265 | "file": "src/lib/Menu.js", | 265 | "file": "src/lib/Menu.js", |
266 | "start": { | 266 | "start": { |
267 | "line": 95, | 267 | "line": 98, |
268 | "column": 18 | 268 | "column": 18 |
269 | }, | 269 | }, |
270 | "end": { | 270 | "end": { |
271 | "line": 98, | 271 | "line": 101, |
272 | "column": 3 | ||
273 | } | ||
274 | }, | ||
275 | { | ||
276 | "id": "menu.view.toggleTodosDevTools", | ||
277 | "defaultMessage": "!!!Toggle Todos Developer Tools", | ||
278 | "file": "src/lib/Menu.js", | ||
279 | "start": { | ||
280 | "line": 102, | ||
281 | "column": 23 | ||
282 | }, | ||
283 | "end": { | ||
284 | "line": 105, | ||
272 | "column": 3 | 285 | "column": 3 |
273 | } | 286 | } |
274 | }, | 287 | }, |
@@ -277,11 +290,11 @@ | |||
277 | "defaultMessage": "!!!Toggle Service Developer Tools", | 290 | "defaultMessage": "!!!Toggle Service Developer Tools", |
278 | "file": "src/lib/Menu.js", | 291 | "file": "src/lib/Menu.js", |
279 | "start": { | 292 | "start": { |
280 | "line": 99, | 293 | "line": 106, |
281 | "column": 25 | 294 | "column": 25 |
282 | }, | 295 | }, |
283 | "end": { | 296 | "end": { |
284 | "line": 102, | 297 | "line": 109, |
285 | "column": 3 | 298 | "column": 3 |
286 | } | 299 | } |
287 | }, | 300 | }, |
@@ -290,11 +303,11 @@ | |||
290 | "defaultMessage": "!!!Reload Service", | 303 | "defaultMessage": "!!!Reload Service", |
291 | "file": "src/lib/Menu.js", | 304 | "file": "src/lib/Menu.js", |
292 | "start": { | 305 | "start": { |
293 | "line": 103, | 306 | "line": 110, |
294 | "column": 17 | 307 | "column": 17 |
295 | }, | 308 | }, |
296 | "end": { | 309 | "end": { |
297 | "line": 106, | 310 | "line": 113, |
298 | "column": 3 | 311 | "column": 3 |
299 | } | 312 | } |
300 | }, | 313 | }, |
@@ -303,11 +316,11 @@ | |||
303 | "defaultMessage": "!!!Reload Franz", | 316 | "defaultMessage": "!!!Reload Franz", |
304 | "file": "src/lib/Menu.js", | 317 | "file": "src/lib/Menu.js", |
305 | "start": { | 318 | "start": { |
306 | "line": 107, | 319 | "line": 114, |
307 | "column": 15 | 320 | "column": 15 |
308 | }, | 321 | }, |
309 | "end": { | 322 | "end": { |
310 | "line": 110, | 323 | "line": 117, |
311 | "column": 3 | 324 | "column": 3 |
312 | } | 325 | } |
313 | }, | 326 | }, |
@@ -316,11 +329,11 @@ | |||
316 | "defaultMessage": "!!!Minimize", | 329 | "defaultMessage": "!!!Minimize", |
317 | "file": "src/lib/Menu.js", | 330 | "file": "src/lib/Menu.js", |
318 | "start": { | 331 | "start": { |
319 | "line": 111, | 332 | "line": 118, |
320 | "column": 12 | 333 | "column": 12 |
321 | }, | 334 | }, |
322 | "end": { | 335 | "end": { |
323 | "line": 114, | 336 | "line": 121, |
324 | "column": 3 | 337 | "column": 3 |
325 | } | 338 | } |
326 | }, | 339 | }, |
@@ -329,11 +342,11 @@ | |||
329 | "defaultMessage": "!!!Close", | 342 | "defaultMessage": "!!!Close", |
330 | "file": "src/lib/Menu.js", | 343 | "file": "src/lib/Menu.js", |
331 | "start": { | 344 | "start": { |
332 | "line": 115, | 345 | "line": 122, |
333 | "column": 9 | 346 | "column": 9 |
334 | }, | 347 | }, |
335 | "end": { | 348 | "end": { |
336 | "line": 118, | 349 | "line": 125, |
337 | "column": 3 | 350 | "column": 3 |
338 | } | 351 | } |
339 | }, | 352 | }, |
@@ -342,11 +355,11 @@ | |||
342 | "defaultMessage": "!!!Learn More", | 355 | "defaultMessage": "!!!Learn More", |
343 | "file": "src/lib/Menu.js", | 356 | "file": "src/lib/Menu.js", |
344 | "start": { | 357 | "start": { |
345 | "line": 119, | 358 | "line": 126, |
346 | "column": 13 | 359 | "column": 13 |
347 | }, | 360 | }, |
348 | "end": { | 361 | "end": { |
349 | "line": 122, | 362 | "line": 129, |
350 | "column": 3 | 363 | "column": 3 |
351 | } | 364 | } |
352 | }, | 365 | }, |
@@ -355,11 +368,11 @@ | |||
355 | "defaultMessage": "!!!Changelog", | 368 | "defaultMessage": "!!!Changelog", |
356 | "file": "src/lib/Menu.js", | 369 | "file": "src/lib/Menu.js", |
357 | "start": { | 370 | "start": { |
358 | "line": 123, | 371 | "line": 130, |
359 | "column": 13 | 372 | "column": 13 |
360 | }, | 373 | }, |
361 | "end": { | 374 | "end": { |
362 | "line": 126, | 375 | "line": 133, |
363 | "column": 3 | 376 | "column": 3 |
364 | } | 377 | } |
365 | }, | 378 | }, |
@@ -368,11 +381,50 @@ | |||
368 | "defaultMessage": "!!!Support", | 381 | "defaultMessage": "!!!Support", |
369 | "file": "src/lib/Menu.js", | 382 | "file": "src/lib/Menu.js", |
370 | "start": { | 383 | "start": { |
371 | "line": 127, | 384 | "line": 134, |
372 | "column": 11 | 385 | "column": 11 |
373 | }, | 386 | }, |
374 | "end": { | 387 | "end": { |
375 | "line": 130, | 388 | "line": 137, |
389 | "column": 3 | ||
390 | } | ||
391 | }, | ||
392 | { | ||
393 | "id": "menu.help.debugInfo", | ||
394 | "defaultMessage": "!!!Copy Debug Information", | ||
395 | "file": "src/lib/Menu.js", | ||
396 | "start": { | ||
397 | "line": 138, | ||
398 | "column": 13 | ||
399 | }, | ||
400 | "end": { | ||
401 | "line": 141, | ||
402 | "column": 3 | ||
403 | } | ||
404 | }, | ||
405 | { | ||
406 | "id": "menu.help.debugInfoCopiedHeadline", | ||
407 | "defaultMessage": "!!!Franz Debug Information", | ||
408 | "file": "src/lib/Menu.js", | ||
409 | "start": { | ||
410 | "line": 142, | ||
411 | "column": 27 | ||
412 | }, | ||
413 | "end": { | ||
414 | "line": 145, | ||
415 | "column": 3 | ||
416 | } | ||
417 | }, | ||
418 | { | ||
419 | "id": "menu.help.debugInfoCopiedBody", | ||
420 | "defaultMessage": "!!!Your Debug Information has been copied to your clipboard.", | ||
421 | "file": "src/lib/Menu.js", | ||
422 | "start": { | ||
423 | "line": 146, | ||
424 | "column": 23 | ||
425 | }, | ||
426 | "end": { | ||
427 | "line": 149, | ||
376 | "column": 3 | 428 | "column": 3 |
377 | } | 429 | } |
378 | }, | 430 | }, |
@@ -381,11 +433,11 @@ | |||
381 | "defaultMessage": "!!!Terms of Service", | 433 | "defaultMessage": "!!!Terms of Service", |
382 | "file": "src/lib/Menu.js", | 434 | "file": "src/lib/Menu.js", |
383 | "start": { | 435 | "start": { |
384 | "line": 131, | 436 | "line": 150, |
385 | "column": 7 | 437 | "column": 7 |
386 | }, | 438 | }, |
387 | "end": { | 439 | "end": { |
388 | "line": 134, | 440 | "line": 153, |
389 | "column": 3 | 441 | "column": 3 |
390 | } | 442 | } |
391 | }, | 443 | }, |
@@ -394,11 +446,11 @@ | |||
394 | "defaultMessage": "!!!Privacy Statement", | 446 | "defaultMessage": "!!!Privacy Statement", |
395 | "file": "src/lib/Menu.js", | 447 | "file": "src/lib/Menu.js", |
396 | "start": { | 448 | "start": { |
397 | "line": 135, | 449 | "line": 154, |
398 | "column": 11 | 450 | "column": 11 |
399 | }, | 451 | }, |
400 | "end": { | 452 | "end": { |
401 | "line": 138, | 453 | "line": 157, |
402 | "column": 3 | 454 | "column": 3 |
403 | } | 455 | } |
404 | }, | 456 | }, |
@@ -407,11 +459,11 @@ | |||
407 | "defaultMessage": "!!!File", | 459 | "defaultMessage": "!!!File", |
408 | "file": "src/lib/Menu.js", | 460 | "file": "src/lib/Menu.js", |
409 | "start": { | 461 | "start": { |
410 | "line": 139, | 462 | "line": 158, |
411 | "column": 8 | 463 | "column": 8 |
412 | }, | 464 | }, |
413 | "end": { | 465 | "end": { |
414 | "line": 142, | 466 | "line": 161, |
415 | "column": 3 | 467 | "column": 3 |
416 | } | 468 | } |
417 | }, | 469 | }, |
@@ -420,11 +472,11 @@ | |||
420 | "defaultMessage": "!!!View", | 472 | "defaultMessage": "!!!View", |
421 | "file": "src/lib/Menu.js", | 473 | "file": "src/lib/Menu.js", |
422 | "start": { | 474 | "start": { |
423 | "line": 143, | 475 | "line": 162, |
424 | "column": 8 | 476 | "column": 8 |
425 | }, | 477 | }, |
426 | "end": { | 478 | "end": { |
427 | "line": 146, | 479 | "line": 165, |
428 | "column": 3 | 480 | "column": 3 |
429 | } | 481 | } |
430 | }, | 482 | }, |
@@ -433,11 +485,11 @@ | |||
433 | "defaultMessage": "!!!Services", | 485 | "defaultMessage": "!!!Services", |
434 | "file": "src/lib/Menu.js", | 486 | "file": "src/lib/Menu.js", |
435 | "start": { | 487 | "start": { |
436 | "line": 147, | 488 | "line": 166, |
437 | "column": 12 | 489 | "column": 12 |
438 | }, | 490 | }, |
439 | "end": { | 491 | "end": { |
440 | "line": 150, | 492 | "line": 169, |
441 | "column": 3 | 493 | "column": 3 |
442 | } | 494 | } |
443 | }, | 495 | }, |
@@ -446,11 +498,11 @@ | |||
446 | "defaultMessage": "!!!Window", | 498 | "defaultMessage": "!!!Window", |
447 | "file": "src/lib/Menu.js", | 499 | "file": "src/lib/Menu.js", |
448 | "start": { | 500 | "start": { |
449 | "line": 151, | 501 | "line": 170, |
450 | "column": 10 | 502 | "column": 10 |
451 | }, | 503 | }, |
452 | "end": { | 504 | "end": { |
453 | "line": 154, | 505 | "line": 173, |
454 | "column": 3 | 506 | "column": 3 |
455 | } | 507 | } |
456 | }, | 508 | }, |
@@ -459,11 +511,11 @@ | |||
459 | "defaultMessage": "!!!Help", | 511 | "defaultMessage": "!!!Help", |
460 | "file": "src/lib/Menu.js", | 512 | "file": "src/lib/Menu.js", |
461 | "start": { | 513 | "start": { |
462 | "line": 155, | 514 | "line": 174, |
463 | "column": 8 | 515 | "column": 8 |
464 | }, | 516 | }, |
465 | "end": { | 517 | "end": { |
466 | "line": 158, | 518 | "line": 177, |
467 | "column": 3 | 519 | "column": 3 |
468 | } | 520 | } |
469 | }, | 521 | }, |
@@ -472,11 +524,11 @@ | |||
472 | "defaultMessage": "!!!About Franz", | 524 | "defaultMessage": "!!!About Franz", |
473 | "file": "src/lib/Menu.js", | 525 | "file": "src/lib/Menu.js", |
474 | "start": { | 526 | "start": { |
475 | "line": 159, | 527 | "line": 178, |
476 | "column": 9 | 528 | "column": 9 |
477 | }, | 529 | }, |
478 | "end": { | 530 | "end": { |
479 | "line": 162, | 531 | "line": 181, |
480 | "column": 3 | 532 | "column": 3 |
481 | } | 533 | } |
482 | }, | 534 | }, |
@@ -485,11 +537,11 @@ | |||
485 | "defaultMessage": "!!!What's new?", | 537 | "defaultMessage": "!!!What's new?", |
486 | "file": "src/lib/Menu.js", | 538 | "file": "src/lib/Menu.js", |
487 | "start": { | 539 | "start": { |
488 | "line": 163, | 540 | "line": 182, |
489 | "column": 16 | 541 | "column": 16 |
490 | }, | 542 | }, |
491 | "end": { | 543 | "end": { |
492 | "line": 166, | 544 | "line": 185, |
493 | "column": 3 | 545 | "column": 3 |
494 | } | 546 | } |
495 | }, | 547 | }, |
@@ -498,11 +550,11 @@ | |||
498 | "defaultMessage": "!!!Settings", | 550 | "defaultMessage": "!!!Settings", |
499 | "file": "src/lib/Menu.js", | 551 | "file": "src/lib/Menu.js", |
500 | "start": { | 552 | "start": { |
501 | "line": 167, | 553 | "line": 186, |
502 | "column": 12 | 554 | "column": 12 |
503 | }, | 555 | }, |
504 | "end": { | 556 | "end": { |
505 | "line": 170, | 557 | "line": 189, |
506 | "column": 3 | 558 | "column": 3 |
507 | } | 559 | } |
508 | }, | 560 | }, |
@@ -511,11 +563,11 @@ | |||
511 | "defaultMessage": "!!!Check for updates", | 563 | "defaultMessage": "!!!Check for updates", |
512 | "file": "src/lib/Menu.js", | 564 | "file": "src/lib/Menu.js", |
513 | "start": { | 565 | "start": { |
514 | "line": 171, | 566 | "line": 190, |
515 | "column": 19 | 567 | "column": 19 |
516 | }, | 568 | }, |
517 | "end": { | 569 | "end": { |
518 | "line": 174, | 570 | "line": 193, |
519 | "column": 3 | 571 | "column": 3 |
520 | } | 572 | } |
521 | }, | 573 | }, |
@@ -524,11 +576,11 @@ | |||
524 | "defaultMessage": "!!!Hide", | 576 | "defaultMessage": "!!!Hide", |
525 | "file": "src/lib/Menu.js", | 577 | "file": "src/lib/Menu.js", |
526 | "start": { | 578 | "start": { |
527 | "line": 175, | 579 | "line": 194, |
528 | "column": 8 | 580 | "column": 8 |
529 | }, | 581 | }, |
530 | "end": { | 582 | "end": { |
531 | "line": 178, | 583 | "line": 197, |
532 | "column": 3 | 584 | "column": 3 |
533 | } | 585 | } |
534 | }, | 586 | }, |
@@ -537,11 +589,11 @@ | |||
537 | "defaultMessage": "!!!Hide Others", | 589 | "defaultMessage": "!!!Hide Others", |
538 | "file": "src/lib/Menu.js", | 590 | "file": "src/lib/Menu.js", |
539 | "start": { | 591 | "start": { |
540 | "line": 179, | 592 | "line": 198, |
541 | "column": 14 | 593 | "column": 14 |
542 | }, | 594 | }, |
543 | "end": { | 595 | "end": { |
544 | "line": 182, | 596 | "line": 201, |
545 | "column": 3 | 597 | "column": 3 |
546 | } | 598 | } |
547 | }, | 599 | }, |
@@ -550,11 +602,11 @@ | |||
550 | "defaultMessage": "!!!Unhide", | 602 | "defaultMessage": "!!!Unhide", |
551 | "file": "src/lib/Menu.js", | 603 | "file": "src/lib/Menu.js", |
552 | "start": { | 604 | "start": { |
553 | "line": 183, | 605 | "line": 202, |
554 | "column": 10 | 606 | "column": 10 |
555 | }, | 607 | }, |
556 | "end": { | 608 | "end": { |
557 | "line": 186, | 609 | "line": 205, |
558 | "column": 3 | 610 | "column": 3 |
559 | } | 611 | } |
560 | }, | 612 | }, |
@@ -563,11 +615,11 @@ | |||
563 | "defaultMessage": "!!!Quit", | 615 | "defaultMessage": "!!!Quit", |
564 | "file": "src/lib/Menu.js", | 616 | "file": "src/lib/Menu.js", |
565 | "start": { | 617 | "start": { |
566 | "line": 187, | 618 | "line": 206, |
567 | "column": 8 | 619 | "column": 8 |
568 | }, | 620 | }, |
569 | "end": { | 621 | "end": { |
570 | "line": 190, | 622 | "line": 209, |
571 | "column": 3 | 623 | "column": 3 |
572 | } | 624 | } |
573 | }, | 625 | }, |
@@ -576,11 +628,11 @@ | |||
576 | "defaultMessage": "!!!Add New Service...", | 628 | "defaultMessage": "!!!Add New Service...", |
577 | "file": "src/lib/Menu.js", | 629 | "file": "src/lib/Menu.js", |
578 | "start": { | 630 | "start": { |
579 | "line": 191, | 631 | "line": 210, |
580 | "column": 17 | 632 | "column": 17 |
581 | }, | 633 | }, |
582 | "end": { | 634 | "end": { |
583 | "line": 194, | 635 | "line": 213, |
584 | "column": 3 | 636 | "column": 3 |
585 | } | 637 | } |
586 | }, | 638 | }, |
@@ -589,11 +641,11 @@ | |||
589 | "defaultMessage": "!!!Add New Workspace...", | 641 | "defaultMessage": "!!!Add New Workspace...", |
590 | "file": "src/lib/Menu.js", | 642 | "file": "src/lib/Menu.js", |
591 | "start": { | 643 | "start": { |
592 | "line": 195, | 644 | "line": 214, |
593 | "column": 19 | 645 | "column": 19 |
594 | }, | 646 | }, |
595 | "end": { | 647 | "end": { |
596 | "line": 198, | 648 | "line": 217, |
597 | "column": 3 | 649 | "column": 3 |
598 | } | 650 | } |
599 | }, | 651 | }, |
@@ -602,11 +654,11 @@ | |||
602 | "defaultMessage": "!!!Open workspace drawer", | 654 | "defaultMessage": "!!!Open workspace drawer", |
603 | "file": "src/lib/Menu.js", | 655 | "file": "src/lib/Menu.js", |
604 | "start": { | 656 | "start": { |
605 | "line": 199, | 657 | "line": 218, |
606 | "column": 23 | 658 | "column": 23 |
607 | }, | 659 | }, |
608 | "end": { | 660 | "end": { |
609 | "line": 202, | 661 | "line": 221, |
610 | "column": 3 | 662 | "column": 3 |
611 | } | 663 | } |
612 | }, | 664 | }, |
@@ -615,11 +667,11 @@ | |||
615 | "defaultMessage": "!!!Close workspace drawer", | 667 | "defaultMessage": "!!!Close workspace drawer", |
616 | "file": "src/lib/Menu.js", | 668 | "file": "src/lib/Menu.js", |
617 | "start": { | 669 | "start": { |
618 | "line": 203, | 670 | "line": 222, |
619 | "column": 24 | 671 | "column": 24 |
620 | }, | 672 | }, |
621 | "end": { | 673 | "end": { |
622 | "line": 206, | 674 | "line": 225, |
623 | "column": 3 | 675 | "column": 3 |
624 | } | 676 | } |
625 | }, | 677 | }, |
@@ -628,11 +680,11 @@ | |||
628 | "defaultMessage": "!!!Activate next service...", | 680 | "defaultMessage": "!!!Activate next service...", |
629 | "file": "src/lib/Menu.js", | 681 | "file": "src/lib/Menu.js", |
630 | "start": { | 682 | "start": { |
631 | "line": 207, | 683 | "line": 226, |
632 | "column": 23 | 684 | "column": 23 |
633 | }, | 685 | }, |
634 | "end": { | 686 | "end": { |
635 | "line": 210, | 687 | "line": 229, |
636 | "column": 3 | 688 | "column": 3 |
637 | } | 689 | } |
638 | }, | 690 | }, |
@@ -641,11 +693,11 @@ | |||
641 | "defaultMessage": "!!!Activate previous service...", | 693 | "defaultMessage": "!!!Activate previous service...", |
642 | "file": "src/lib/Menu.js", | 694 | "file": "src/lib/Menu.js", |
643 | "start": { | 695 | "start": { |
644 | "line": 211, | 696 | "line": 230, |
645 | "column": 27 | 697 | "column": 27 |
646 | }, | 698 | }, |
647 | "end": { | 699 | "end": { |
648 | "line": 214, | 700 | "line": 233, |
649 | "column": 3 | 701 | "column": 3 |
650 | } | 702 | } |
651 | }, | 703 | }, |
@@ -654,11 +706,11 @@ | |||
654 | "defaultMessage": "!!!Disable notifications & audio", | 706 | "defaultMessage": "!!!Disable notifications & audio", |
655 | "file": "src/lib/Menu.js", | 707 | "file": "src/lib/Menu.js", |
656 | "start": { | 708 | "start": { |
657 | "line": 215, | 709 | "line": 234, |
658 | "column": 11 | 710 | "column": 11 |
659 | }, | 711 | }, |
660 | "end": { | 712 | "end": { |
661 | "line": 218, | 713 | "line": 237, |
662 | "column": 3 | 714 | "column": 3 |
663 | } | 715 | } |
664 | }, | 716 | }, |
@@ -667,11 +719,11 @@ | |||
667 | "defaultMessage": "!!!Enable notifications & audio", | 719 | "defaultMessage": "!!!Enable notifications & audio", |
668 | "file": "src/lib/Menu.js", | 720 | "file": "src/lib/Menu.js", |
669 | "start": { | 721 | "start": { |
670 | "line": 219, | 722 | "line": 238, |
671 | "column": 13 | 723 | "column": 13 |
672 | }, | 724 | }, |
673 | "end": { | 725 | "end": { |
674 | "line": 222, | 726 | "line": 241, |
675 | "column": 3 | 727 | "column": 3 |
676 | } | 728 | } |
677 | }, | 729 | }, |
@@ -680,11 +732,11 @@ | |||
680 | "defaultMessage": "!!!Workspaces", | 732 | "defaultMessage": "!!!Workspaces", |
681 | "file": "src/lib/Menu.js", | 733 | "file": "src/lib/Menu.js", |
682 | "start": { | 734 | "start": { |
683 | "line": 223, | 735 | "line": 242, |
684 | "column": 14 | 736 | "column": 14 |
685 | }, | 737 | }, |
686 | "end": { | 738 | "end": { |
687 | "line": 226, | 739 | "line": 245, |
688 | "column": 3 | 740 | "column": 3 |
689 | } | 741 | } |
690 | }, | 742 | }, |
@@ -693,11 +745,50 @@ | |||
693 | "defaultMessage": "!!!Default", | 745 | "defaultMessage": "!!!Default", |
694 | "file": "src/lib/Menu.js", | 746 | "file": "src/lib/Menu.js", |
695 | "start": { | 747 | "start": { |
696 | "line": 227, | 748 | "line": 246, |
697 | "column": 20 | 749 | "column": 20 |
698 | }, | 750 | }, |
699 | "end": { | 751 | "end": { |
700 | "line": 230, | 752 | "line": 249, |
753 | "column": 3 | ||
754 | } | ||
755 | }, | ||
756 | { | ||
757 | "id": "menu.todos", | ||
758 | "defaultMessage": "!!!Todos", | ||
759 | "file": "src/lib/Menu.js", | ||
760 | "start": { | ||
761 | "line": 250, | ||
762 | "column": 9 | ||
763 | }, | ||
764 | "end": { | ||
765 | "line": 253, | ||
766 | "column": 3 | ||
767 | } | ||
768 | }, | ||
769 | { | ||
770 | "id": "menu.Todoss.openTodosDrawer", | ||
771 | "defaultMessage": "!!!Open Todos drawer", | ||
772 | "file": "src/lib/Menu.js", | ||
773 | "start": { | ||
774 | "line": 254, | ||
775 | "column": 19 | ||
776 | }, | ||
777 | "end": { | ||
778 | "line": 257, | ||
779 | "column": 3 | ||
780 | } | ||
781 | }, | ||
782 | { | ||
783 | "id": "menu.Todoss.closeTodosDrawer", | ||
784 | "defaultMessage": "!!!Close Todos drawer", | ||
785 | "file": "src/lib/Menu.js", | ||
786 | "start": { | ||
787 | "line": 258, | ||
788 | "column": 20 | ||
789 | }, | ||
790 | "end": { | ||
791 | "line": 261, | ||
701 | "column": 3 | 792 | "column": 3 |
702 | } | 793 | } |
703 | } | 794 | } |
diff --git a/src/index.html b/src/index.html index bf15e2d4e..198c1ab7b 100644 --- a/src/index.html +++ b/src/index.html | |||
@@ -10,6 +10,7 @@ | |||
10 | <div class="window-draggable"></div> | 10 | <div class="window-draggable"></div> |
11 | <div class="dev-warning">DEV MODE</div> | 11 | <div class="dev-warning">DEV MODE</div> |
12 | <div id="root"></div> | 12 | <div id="root"></div> |
13 | <div id="portalContainer"></div> | ||
13 | <script> | 14 | <script> |
14 | document.querySelector('body').classList.add(process.env.OS_PLATFORM ? process.env.OS_PLATFORM : process.platform); | 15 | document.querySelector('body').classList.add(process.env.OS_PLATFORM ? process.env.OS_PLATFORM : process.platform); |
15 | 16 | ||
@@ -34,11 +35,16 @@ | |||
34 | const originalReloadBehaviour = window._onLiveReloadFileChanged; | 35 | const originalReloadBehaviour = window._onLiveReloadFileChanged; |
35 | 36 | ||
36 | window._onLiveReloadFileChanged = (file) => { | 37 | window._onLiveReloadFileChanged = (file) => { |
37 | if (!file.path.includes('/build/webview/') && !file.path.includes('/build/index.js') && !file.path.includes('/build/electron/')) { | 38 | const isTodoPreloadPath = file.path.includes('/build/features/todos/preload.js'); |
39 | if (!file.path.includes('/build/webview/') && !file.path.includes('/build/index.js') && !file.path.includes('/build/electron/') && !isTodoPreloadPath) { | ||
38 | originalReloadBehaviour(file); | 40 | originalReloadBehaviour(file); |
39 | } else { | 41 | } else { |
40 | if (file.path.includes('/build/webview/')) { | 42 | if (isTodoPreloadPath) { |
41 | debug('Livereload: Reloading all webvies'); | 43 | debug('Livereload: Reloading all webviews'); |
44 | const webview = document.querySelector('webview[partition="persist:todos"]'); | ||
45 | if (webview) webview.reload(); | ||
46 | } else if (file.path.includes('/build/webview/')) { | ||
47 | debug('Livereload: Reloading all webviews'); | ||
42 | const webviews = document.querySelectorAll('webview').forEach(webview => webview.reload()); | 48 | const webviews = document.querySelectorAll('webview').forEach(webview => webview.reload()); |
43 | } else { | 49 | } else { |
44 | debug('Livereload: skip reload as only main process files have changed'); | 50 | debug('Livereload: skip reload as only main process files have changed'); |
diff --git a/src/index.js b/src/index.js index 55592c328..d9d51fd5b 100644 --- a/src/index.js +++ b/src/index.js | |||
@@ -105,35 +105,6 @@ if (!gotTheLock) { | |||
105 | } | 105 | } |
106 | }); | 106 | }); |
107 | } | 107 | } |
108 | // const isSecondInstance = app.makeSingleInstance((argv) => { | ||
109 | // if (mainWindow) { | ||
110 | // if (mainWindow.isMinimized()) mainWindow.restore(); | ||
111 | // mainWindow.focus(); | ||
112 | |||
113 | // if (process.platform === 'win32') { | ||
114 | // // Keep only command line / deep linked arguments | ||
115 | // const url = argv.slice(1); | ||
116 | |||
117 | // if (url) { | ||
118 | // handleDeepLink(mainWindow, url.toString()); | ||
119 | // } | ||
120 | // } | ||
121 | // } | ||
122 | |||
123 | // if (argv.includes('--reset-window')) { | ||
124 | // // Needs to be delayed to not interfere with mainWindow.restore(); | ||
125 | // setTimeout(() => { | ||
126 | // debug('Resetting windows via Task'); | ||
127 | // mainWindow.setPosition(DEFAULT_WINDOW_OPTIONS.x + 100, DEFAULT_WINDOW_OPTIONS.y + 100); | ||
128 | // mainWindow.setSize(DEFAULT_WINDOW_OPTIONS.width, DEFAULT_WINDOW_OPTIONS.height); | ||
129 | // }, 1); | ||
130 | // } | ||
131 | // }); | ||
132 | |||
133 | // if (isSecondInstance) { | ||
134 | // console.log('An instance of Franz is already running. Exiting...'); | ||
135 | // app.exit(); | ||
136 | // } | ||
137 | 108 | ||
138 | // Fix Unity indicator issue | 109 | // Fix Unity indicator issue |
139 | // https://github.com/electron/electron/issues/9046 | 110 | // https://github.com/electron/electron/issues/9046 |
diff --git a/src/lib/Menu.js b/src/lib/Menu.js index e0dfd736e..81efaf18f 100644 --- a/src/lib/Menu.js +++ b/src/lib/Menu.js | |||
@@ -1,4 +1,4 @@ | |||
1 | import { remote, shell } from 'electron'; | 1 | import { remote, shell, clipboard } from 'electron'; |
2 | import { observable, autorun } from 'mobx'; | 2 | import { observable, autorun } from 'mobx'; |
3 | import { defineMessages } from 'react-intl'; | 3 | import { defineMessages } from 'react-intl'; |
4 | 4 | ||
@@ -8,6 +8,9 @@ import { workspaceActions } from '../features/workspaces/actions'; | |||
8 | import { gaEvent } from './analytics'; | 8 | import { gaEvent } from './analytics'; |
9 | import { announcementActions } from '../features/announcements/actions'; | 9 | import { announcementActions } from '../features/announcements/actions'; |
10 | import { announcementsStore } from '../features/announcements'; | 10 | import { announcementsStore } from '../features/announcements'; |
11 | import TodoStore from '../features/todos/store'; | ||
12 | import { GA_CATEGORY_TODOS, todosStore } from '../features/todos'; | ||
13 | import { todoActions } from '../features/todos/actions'; | ||
11 | 14 | ||
12 | const { app, Menu, dialog } = remote; | 15 | const { app, Menu, dialog } = remote; |
13 | 16 | ||
@@ -96,6 +99,10 @@ const menuItems = defineMessages({ | |||
96 | id: 'menu.view.toggleDevTools', | 99 | id: 'menu.view.toggleDevTools', |
97 | defaultMessage: '!!!Toggle Developer Tools', | 100 | defaultMessage: '!!!Toggle Developer Tools', |
98 | }, | 101 | }, |
102 | toggleTodosDevTools: { | ||
103 | id: 'menu.view.toggleTodosDevTools', | ||
104 | defaultMessage: '!!!Toggle Todos Developer Tools', | ||
105 | }, | ||
99 | toggleServiceDevTools: { | 106 | toggleServiceDevTools: { |
100 | id: 'menu.view.toggleServiceDevTools', | 107 | id: 'menu.view.toggleServiceDevTools', |
101 | defaultMessage: '!!!Toggle Service Developer Tools', | 108 | defaultMessage: '!!!Toggle Service Developer Tools', |
@@ -128,6 +135,18 @@ const menuItems = defineMessages({ | |||
128 | id: 'menu.help.support', | 135 | id: 'menu.help.support', |
129 | defaultMessage: '!!!Support', | 136 | defaultMessage: '!!!Support', |
130 | }, | 137 | }, |
138 | debugInfo: { | ||
139 | id: 'menu.help.debugInfo', | ||
140 | defaultMessage: '!!!Copy Debug Information', | ||
141 | }, | ||
142 | debugInfoCopiedHeadline: { | ||
143 | id: 'menu.help.debugInfoCopiedHeadline', | ||
144 | defaultMessage: '!!!Franz Debug Information', | ||
145 | }, | ||
146 | debugInfoCopiedBody: { | ||
147 | id: 'menu.help.debugInfoCopiedBody', | ||
148 | defaultMessage: '!!!Your Debug Information has been copied to your clipboard.', | ||
149 | }, | ||
131 | tos: { | 150 | tos: { |
132 | id: 'menu.help.tos', | 151 | id: 'menu.help.tos', |
133 | defaultMessage: '!!!Terms of Service', | 152 | defaultMessage: '!!!Terms of Service', |
@@ -228,6 +247,18 @@ const menuItems = defineMessages({ | |||
228 | id: 'menu.workspaces.defaultWorkspace', | 247 | id: 'menu.workspaces.defaultWorkspace', |
229 | defaultMessage: '!!!Default', | 248 | defaultMessage: '!!!Default', |
230 | }, | 249 | }, |
250 | todos: { | ||
251 | id: 'menu.todos', | ||
252 | defaultMessage: '!!!Todos', | ||
253 | }, | ||
254 | openTodosDrawer: { | ||
255 | id: 'menu.Todoss.openTodosDrawer', | ||
256 | defaultMessage: '!!!Open Todos drawer', | ||
257 | }, | ||
258 | closeTodosDrawer: { | ||
259 | id: 'menu.Todoss.closeTodosDrawer', | ||
260 | defaultMessage: '!!!Close Todos drawer', | ||
261 | }, | ||
231 | }); | 262 | }); |
232 | 263 | ||
233 | function getActiveWebview() { | 264 | function getActiveWebview() { |
@@ -336,6 +367,11 @@ const _templateFactory = intl => [ | |||
336 | visible: workspaceStore.isFeatureEnabled, | 367 | visible: workspaceStore.isFeatureEnabled, |
337 | }, | 368 | }, |
338 | { | 369 | { |
370 | label: intl.formatMessage(menuItems.todos), | ||
371 | submenu: [], | ||
372 | visible: todosStore.isFeatureEnabled, | ||
373 | }, | ||
374 | { | ||
339 | label: intl.formatMessage(menuItems.window), | 375 | label: intl.formatMessage(menuItems.window), |
340 | role: 'window', | 376 | role: 'window', |
341 | submenu: [ | 377 | submenu: [ |
@@ -608,6 +644,17 @@ export default class FranzMenu { | |||
608 | enabled: this.stores.user.isLoggedIn && this.stores.services.enabled.length > 0, | 644 | enabled: this.stores.user.isLoggedIn && this.stores.services.enabled.length > 0, |
609 | }); | 645 | }); |
610 | 646 | ||
647 | if (this.stores.features.features.isTodosEnabled) { | ||
648 | tpl[1].submenu.push({ | ||
649 | label: intl.formatMessage(menuItems.toggleTodosDevTools), | ||
650 | accelerator: `${cmdKey}+Shift+Alt+O`, | ||
651 | click: () => { | ||
652 | const webview = document.querySelector('webview[partition="persist:todos"]'); | ||
653 | if (webview) webview.openDevTools(); | ||
654 | }, | ||
655 | }); | ||
656 | } | ||
657 | |||
611 | tpl[1].submenu.unshift({ | 658 | tpl[1].submenu.unshift({ |
612 | label: intl.formatMessage(menuItems.reloadService), | 659 | label: intl.formatMessage(menuItems.reloadService), |
613 | id: 'reloadService', // TODO: needed? | 660 | id: 'reloadService', // TODO: needed? |
@@ -760,6 +807,14 @@ export default class FranzMenu { | |||
760 | tpl[4].submenu = this.workspacesMenu(); | 807 | tpl[4].submenu = this.workspacesMenu(); |
761 | } | 808 | } |
762 | 809 | ||
810 | if (todosStore.isFeatureEnabled) { | ||
811 | tpl[5].submenu = this.todosMenu(); | ||
812 | } | ||
813 | |||
814 | tpl[tpl.length - 1].submenu.push({ | ||
815 | type: 'separator', | ||
816 | }, this.debugMenu()); | ||
817 | |||
763 | this.currentTemplate = tpl; | 818 | this.currentTemplate = tpl; |
764 | const menu = Menu.buildFromTemplate(tpl); | 819 | const menu = Menu.buildFromTemplate(tpl); |
765 | Menu.setApplicationMenu(menu); | 820 | Menu.setApplicationMenu(menu); |
@@ -870,6 +925,53 @@ export default class FranzMenu { | |||
870 | return menu; | 925 | return menu; |
871 | } | 926 | } |
872 | 927 | ||
928 | todosMenu() { | ||
929 | const { isTodosPanelVisible } = TodoStore; | ||
930 | const { intl } = window.franz; | ||
931 | const menu = []; | ||
932 | |||
933 | // Open todos drawer: | ||
934 | const drawerLabel = ( | ||
935 | isTodosPanelVisible ? menuItems.closeTodosDrawer : menuItems.openTodosDrawer | ||
936 | ); | ||
937 | menu.push({ | ||
938 | label: intl.formatMessage(drawerLabel), | ||
939 | accelerator: `${cmdKey}+T`, | ||
940 | click: () => { | ||
941 | todoActions.toggleTodosPanel(); | ||
942 | gaEvent(GA_CATEGORY_TODOS, 'toggleDrawer', 'menu'); | ||
943 | }, | ||
944 | enabled: this.stores.user.isLoggedIn, | ||
945 | }, { | ||
946 | type: 'separator', | ||
947 | }); | ||
948 | |||
949 | return menu; | ||
950 | } | ||
951 | |||
952 | |||
953 | debugMenu() { | ||
954 | const { intl } = window.franz; | ||
955 | |||
956 | return { | ||
957 | label: intl.formatMessage(menuItems.debugInfo), | ||
958 | click: () => { | ||
959 | const { debugInfo } = this.stores.app; | ||
960 | |||
961 | clipboard.write({ | ||
962 | text: JSON.stringify(debugInfo), | ||
963 | }); | ||
964 | |||
965 | this.actions.app.notify({ | ||
966 | title: intl.formatMessage(menuItems.debugInfoCopiedHeadline), | ||
967 | options: { | ||
968 | body: intl.formatMessage(menuItems.debugInfoCopiedBody), | ||
969 | }, | ||
970 | }); | ||
971 | }, | ||
972 | }; | ||
973 | } | ||
974 | |||
873 | _getServiceName(service) { | 975 | _getServiceName(service) { |
874 | if (service.name) { | 976 | if (service.name) { |
875 | return service.name; | 977 | return service.name; |
diff --git a/src/models/Service.js b/src/models/Service.js index 88bce3360..848a84aa2 100644 --- a/src/models/Service.js +++ b/src/models/Service.js | |||
@@ -4,6 +4,11 @@ import normalizeUrl from 'normalize-url'; | |||
4 | 4 | ||
5 | const debug = require('debug')('Franz:Service'); | 5 | const debug = require('debug')('Franz:Service'); |
6 | 6 | ||
7 | export const RESTRICTION_TYPES = { | ||
8 | SERVICE_LIMIT: 0, | ||
9 | CUSTOM_URL: 1, | ||
10 | }; | ||
11 | |||
7 | export default class Service { | 12 | export default class Service { |
8 | id = ''; | 13 | id = ''; |
9 | 14 | ||
@@ -59,6 +64,12 @@ export default class Service { | |||
59 | 64 | ||
60 | @observable errorMessage = ''; | 65 | @observable errorMessage = ''; |
61 | 66 | ||
67 | @observable isUsingCustomUrl = false; | ||
68 | |||
69 | @observable isServiceAccessRestricted = false; | ||
70 | |||
71 | @observable restrictionType = null; | ||
72 | |||
62 | constructor(data, recipe) { | 73 | constructor(data, recipe) { |
63 | if (!data) { | 74 | if (!data) { |
64 | console.error('Service config not valid'); | 75 | console.error('Service config not valid'); |
@@ -111,6 +122,10 @@ export default class Service { | |||
111 | this.unreadDirectMessageCount = 0; | 122 | this.unreadDirectMessageCount = 0; |
112 | this.unreadIndirectMessageCount = 0; | 123 | this.unreadIndirectMessageCount = 0; |
113 | } | 124 | } |
125 | |||
126 | if (this.recipe.hasCustomUrl && this.customUrl) { | ||
127 | this.isUsingCustomUrl = true; | ||
128 | } | ||
114 | }); | 129 | }); |
115 | } | 130 | } |
116 | 131 | ||
diff --git a/src/models/User.js b/src/models/User.js index bec78fc16..0a2b1f62a 100644 --- a/src/models/User.js +++ b/src/models/User.js | |||
@@ -20,6 +20,10 @@ export default class User { | |||
20 | 20 | ||
21 | @observable isSubscriptionOwner = false; | 21 | @observable isSubscriptionOwner = false; |
22 | 22 | ||
23 | @observable hasSubscription = false; | ||
24 | |||
25 | @observable hadSubscription = false; | ||
26 | |||
23 | @observable isPremium = false; | 27 | @observable isPremium = false; |
24 | 28 | ||
25 | @observable beta = false; | 29 | @observable beta = false; |
@@ -32,6 +36,9 @@ export default class User { | |||
32 | 36 | ||
33 | @observable locale = false; | 37 | @observable locale = false; |
34 | 38 | ||
39 | @observable team = {}; | ||
40 | |||
41 | |||
35 | constructor(data) { | 42 | constructor(data) { |
36 | if (!data.id) { | 43 | if (!data.id) { |
37 | throw Error('User requires Id'); | 44 | throw Error('User requires Id'); |
@@ -47,8 +54,13 @@ export default class User { | |||
47 | this.beta = data.beta || this.beta; | 54 | this.beta = data.beta || this.beta; |
48 | this.donor = data.donor || this.donor; | 55 | this.donor = data.donor || this.donor; |
49 | this.isDonor = data.isDonor || this.isDonor; | 56 | this.isDonor = data.isDonor || this.isDonor; |
50 | this.isSubscriptionOwner = data.isSubscriptionOwner || this.isSubscriptionOwner; | ||
51 | this.isMiner = data.isMiner || this.isMiner; | 57 | this.isMiner = data.isMiner || this.isMiner; |
52 | this.locale = data.locale || this.locale; | 58 | this.locale = data.locale || this.locale; |
59 | |||
60 | this.isSubscriptionOwner = data.isSubscriptionOwner || this.isSubscriptionOwner; | ||
61 | this.hasSubscription = data.hasSubscription || this.hasSubscription; | ||
62 | this.hadSubscription = data.hadSubscription || this.hadSubscription; | ||
63 | |||
64 | this.team = data.team || this.team; | ||
53 | } | 65 | } |
54 | } | 66 | } |
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js index 72c4b4d0b..6054e6721 100644 --- a/src/stores/AppStore.js +++ b/src/stores/AppStore.js | |||
@@ -8,6 +8,9 @@ import AutoLaunch from 'auto-launch'; | |||
8 | import prettyBytes from 'pretty-bytes'; | 8 | import prettyBytes from 'pretty-bytes'; |
9 | import ms from 'ms'; | 9 | import ms from 'ms'; |
10 | import { URL } from 'url'; | 10 | import { URL } from 'url'; |
11 | import os from 'os'; | ||
12 | import path from 'path'; | ||
13 | import { readJsonSync } from 'fs-extra'; | ||
11 | 14 | ||
12 | import Store from './lib/Store'; | 15 | import Store from './lib/Store'; |
13 | import Request from './lib/Request'; | 16 | import Request from './lib/Request'; |
@@ -23,7 +26,7 @@ import { isValidExternalURL } from '../helpers/url-helpers'; | |||
23 | 26 | ||
24 | const debug = require('debug')('Franz:AppStore'); | 27 | const debug = require('debug')('Franz:AppStore'); |
25 | 28 | ||
26 | const { app, systemPreferences } = remote; | 29 | const { app, systemPreferences, screen } = remote; |
27 | 30 | ||
28 | const mainWindow = remote.getCurrentWindow(); | 31 | const mainWindow = remote.getCurrentWindow(); |
29 | 32 | ||
@@ -182,6 +185,26 @@ export default class AppStore extends Store { | |||
182 | return prettyBytes(this.getAppCacheSizeRequest.execute().result || 0); | 185 | return prettyBytes(this.getAppCacheSizeRequest.execute().result || 0); |
183 | } | 186 | } |
184 | 187 | ||
188 | @computed get debugInfo() { | ||
189 | return { | ||
190 | host: { | ||
191 | platform: process.platform, | ||
192 | release: os.release(), | ||
193 | screens: screen.getAllDisplays(), | ||
194 | }, | ||
195 | franz: { | ||
196 | version: app.getVersion(), | ||
197 | electron: process.versions.electron, | ||
198 | installedRecipes: this.stores.recipes.all.map(recipe => ({ id: recipe.id, version: recipe.version })), | ||
199 | devRecipes: this.stores.recipePreviews.dev.map(recipe => ({ id: recipe.id, version: recipe.version })), | ||
200 | services: this.stores.services.all.map(service => ({ id: service.id, recipe: service.recipe.id })), | ||
201 | workspaces: this.stores.workspaces.workspaces.map(workspace => ({ id: workspace.id, services: workspace.services })), | ||
202 | windowSettings: readJsonSync(path.join(app.getPath('userData'), 'window-state.json')), | ||
203 | user: this.stores.user.data.id, | ||
204 | }, | ||
205 | }; | ||
206 | } | ||
207 | |||
185 | // Actions | 208 | // Actions |
186 | @action _notify({ | 209 | @action _notify({ |
187 | title, options, notificationId, serviceId = null, | 210 | title, options, notificationId, serviceId = null, |
@@ -189,7 +212,7 @@ export default class AppStore extends Store { | |||
189 | if (this.stores.settings.all.app.isAppMuted) return; | 212 | if (this.stores.settings.all.app.isAppMuted) return; |
190 | 213 | ||
191 | // TODO: is there a simple way to use blobs for notifications without storing them on disk? | 214 | // TODO: is there a simple way to use blobs for notifications without storing them on disk? |
192 | if (options.icon.startsWith('blob:')) { | 215 | if (options.icon && options.icon.startsWith('blob:')) { |
193 | delete options.icon; | 216 | delete options.icon; |
194 | } | 217 | } |
195 | 218 | ||
@@ -334,6 +357,8 @@ export default class AppStore extends Store { | |||
334 | this.locale = this._getDefaultLocale(); | 357 | this.locale = this._getDefaultLocale(); |
335 | } | 358 | } |
336 | 359 | ||
360 | moment.locale(this.locale); | ||
361 | |||
337 | debug(`Set locale to "${this.locale}"`); | 362 | debug(`Set locale to "${this.locale}"`); |
338 | } | 363 | } |
339 | 364 | ||
diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js index e7832088b..cf28b6bec 100644 --- a/src/stores/FeaturesStore.js +++ b/src/stores/FeaturesStore.js | |||
@@ -16,6 +16,9 @@ import workspaces from '../features/workspaces'; | |||
16 | import shareFranz from '../features/shareFranz'; | 16 | import shareFranz from '../features/shareFranz'; |
17 | import announcements from '../features/announcements'; | 17 | import announcements from '../features/announcements'; |
18 | import settingsWS from '../features/settingsWS'; | 18 | import settingsWS from '../features/settingsWS'; |
19 | import serviceLimit from '../features/serviceLimit'; | ||
20 | import communityRecipes from '../features/communityRecipes'; | ||
21 | import todos from '../features/todos'; | ||
19 | 22 | ||
20 | import { DEFAULT_FEATURES_CONFIG } from '../config'; | 23 | import { DEFAULT_FEATURES_CONFIG } from '../config'; |
21 | 24 | ||
@@ -75,5 +78,8 @@ export default class FeaturesStore extends Store { | |||
75 | shareFranz(this.stores, this.actions); | 78 | shareFranz(this.stores, this.actions); |
76 | announcements(this.stores, this.actions); | 79 | announcements(this.stores, this.actions); |
77 | settingsWS(this.stores, this.actions); | 80 | settingsWS(this.stores, this.actions); |
81 | serviceLimit(this.stores, this.actions); | ||
82 | communityRecipes(this.stores, this.actions); | ||
83 | todos(this.stores, this.actions); | ||
78 | } | 84 | } |
79 | } | 85 | } |
diff --git a/src/stores/RecipesStore.js b/src/stores/RecipesStore.js index ab64bf79c..d51192078 100644 --- a/src/stores/RecipesStore.js +++ b/src/stores/RecipesStore.js | |||
@@ -20,6 +20,11 @@ export default class RecipesStore extends Store { | |||
20 | // Register action handlers | 20 | // Register action handlers |
21 | this.actions.recipe.install.listen(this._install.bind(this)); | 21 | this.actions.recipe.install.listen(this._install.bind(this)); |
22 | this.actions.recipe.update.listen(this._update.bind(this)); | 22 | this.actions.recipe.update.listen(this._update.bind(this)); |
23 | |||
24 | // Reactions | ||
25 | this.registerReactions([ | ||
26 | this._checkIfRecipeIsInstalled.bind(this), | ||
27 | ]); | ||
23 | } | 28 | } |
24 | 29 | ||
25 | setup() { | 30 | setup() { |
@@ -99,4 +104,26 @@ export default class RecipesStore extends Store { | |||
99 | syncUpdate(0); | 104 | syncUpdate(0); |
100 | } | 105 | } |
101 | } | 106 | } |
107 | |||
108 | async _checkIfRecipeIsInstalled() { | ||
109 | const { router } = this.stores; | ||
110 | |||
111 | const match = matchRoute('/settings/services/add/:id', router.location.pathname); | ||
112 | if (match) { | ||
113 | const recipeId = match.id; | ||
114 | |||
115 | if (!this.stores.recipes.isInstalled(recipeId)) { | ||
116 | router.push('/settings/recipes'); | ||
117 | debug(`Recipe ${recipeId} is not installed, trying to install it`); | ||
118 | |||
119 | const recipe = await this.installRecipeRequest.execute(recipeId)._promise; | ||
120 | if (recipe) { | ||
121 | await this.allRecipesRequest.invalidate({ immediately: true })._promise; | ||
122 | router.push(`/settings/services/add/${recipeId}`); | ||
123 | } else { | ||
124 | router.push('/settings/recipes'); | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | } | ||
102 | } | 129 | } |
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index d63302fce..2fc543192 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js | |||
@@ -13,6 +13,8 @@ import CachedRequest from './lib/CachedRequest'; | |||
13 | import { matchRoute } from '../helpers/routing-helpers'; | 13 | import { matchRoute } from '../helpers/routing-helpers'; |
14 | import { gaEvent, statsEvent } from '../lib/analytics'; | 14 | import { gaEvent, statsEvent } from '../lib/analytics'; |
15 | import { workspaceStore } from '../features/workspaces'; | 15 | import { workspaceStore } from '../features/workspaces'; |
16 | import { serviceLimitStore } from '../features/serviceLimit'; | ||
17 | import { RESTRICTION_TYPES } from '../models/Service'; | ||
16 | 18 | ||
17 | const debug = require('debug')('Franz:ServiceStore'); | 19 | const debug = require('debug')('Franz:ServiceStore'); |
18 | 20 | ||
@@ -75,6 +77,7 @@ export default class ServicesStore extends Store { | |||
75 | this._saveActiveService.bind(this), | 77 | this._saveActiveService.bind(this), |
76 | this._logoutReaction.bind(this), | 78 | this._logoutReaction.bind(this), |
77 | this._handleMuteSettings.bind(this), | 79 | this._handleMuteSettings.bind(this), |
80 | this._restrictServiceAccess.bind(this), | ||
78 | ]); | 81 | ]); |
79 | 82 | ||
80 | // Just bind this | 83 | // Just bind this |
@@ -98,7 +101,10 @@ export default class ServicesStore extends Store { | |||
98 | if (this.stores.user.isLoggedIn) { | 101 | if (this.stores.user.isLoggedIn) { |
99 | const services = this.allServicesRequest.execute().result; | 102 | const services = this.allServicesRequest.execute().result; |
100 | if (services) { | 103 | if (services) { |
101 | return observable(services.slice().slice().sort((a, b) => a.order - b.order)); | 104 | return observable(services.slice().slice().sort((a, b) => a.order - b.order).map((s, index) => { |
105 | s.index = index; | ||
106 | return s; | ||
107 | })); | ||
102 | } | 108 | } |
103 | } | 109 | } |
104 | return []; | 110 | return []; |
@@ -148,22 +154,13 @@ export default class ServicesStore extends Store { | |||
148 | } | 154 | } |
149 | 155 | ||
150 | async _showAddServiceInterface({ recipeId }) { | 156 | async _showAddServiceInterface({ recipeId }) { |
151 | const recipesStore = this.stores.recipes; | 157 | this.stores.router.push(`/settings/services/add/${recipeId}`); |
152 | |||
153 | if (recipesStore.isInstalled(recipeId)) { | ||
154 | debug(`Recipe ${recipeId} is installed`); | ||
155 | this._redirectToAddServiceRoute(recipeId); | ||
156 | } else { | ||
157 | debug(`Recipe ${recipeId} is not installed`); | ||
158 | // We access the RecipeStore action directly | ||
159 | // returns Promise instead of action | ||
160 | await this.stores.recipes._install({ recipeId }); | ||
161 | this._redirectToAddServiceRoute(recipeId); | ||
162 | } | ||
163 | } | 158 | } |
164 | 159 | ||
165 | // Actions | 160 | // Actions |
166 | @action async _createService({ recipeId, serviceData, redirect = true }) { | 161 | @action async _createService({ recipeId, serviceData, redirect = true }) { |
162 | if (serviceLimitStore.userHasReachedServiceLimit) return; | ||
163 | |||
167 | const data = this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData); | 164 | const data = this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData); |
168 | 165 | ||
169 | const response = await this.createServiceRequest.execute(recipeId, data)._promise; | 166 | const response = await this.createServiceRequest.execute(recipeId, data)._promise; |
@@ -451,6 +448,9 @@ export default class ServicesStore extends Store { | |||
451 | redirect: false, | 448 | redirect: false, |
452 | }); | 449 | }); |
453 | } | 450 | } |
451 | } else if (channel === 'feature:todos') { | ||
452 | Object.assign(args[0].data, { serviceId }); | ||
453 | this.actions.todos.handleHostMessage(args[0]); | ||
454 | } | 454 | } |
455 | } | 455 | } |
456 | 456 | ||
@@ -689,12 +689,36 @@ export default class ServicesStore extends Store { | |||
689 | return serviceData; | 689 | return serviceData; |
690 | } | 690 | } |
691 | 691 | ||
692 | // Helper | 692 | _restrictServiceAccess() { |
693 | _redirectToAddServiceRoute(recipeId) { | 693 | const { features } = this.stores.features; |
694 | const route = `/settings/services/add/${recipeId}`; | 694 | const { userHasReachedServiceLimit, serviceLimit } = this.stores.serviceLimit; |
695 | this.stores.router.push(route); | 695 | |
696 | this.all.map((service, index) => { | ||
697 | if (userHasReachedServiceLimit) { | ||
698 | service.isServiceAccessRestricted = index >= serviceLimit; | ||
699 | |||
700 | if (service.isServiceAccessRestricted) { | ||
701 | service.restrictionType = RESTRICTION_TYPES.SERVICE_LIMIT; | ||
702 | |||
703 | debug('Restricting access to server due to service limit'); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | if (service.isUsingCustomUrl) { | ||
708 | service.isServiceAccessRestricted = !features.isCustomUrlIncludedInCurrentPlan; | ||
709 | |||
710 | if (service.isServiceAccessRestricted) { | ||
711 | service.restrictionType = RESTRICTION_TYPES.CUSTOM_URL; | ||
712 | |||
713 | debug('Restricting access to server due to custom url'); | ||
714 | } | ||
715 | } | ||
716 | |||
717 | return service; | ||
718 | }); | ||
696 | } | 719 | } |
697 | 720 | ||
721 | // Helper | ||
698 | _initializeServiceRecipeInWebview(serviceId) { | 722 | _initializeServiceRecipeInWebview(serviceId) { |
699 | const service = this.one(serviceId); | 723 | const service = this.one(serviceId); |
700 | 724 | ||
diff --git a/src/stores/UIStore.js b/src/stores/UIStore.js index a95a8e1e0..9680c5bcc 100644 --- a/src/stores/UIStore.js +++ b/src/stores/UIStore.js | |||
@@ -1,4 +1,9 @@ | |||
1 | import { action, observable, computed } from 'mobx'; | 1 | import { |
2 | action, | ||
3 | observable, | ||
4 | computed, | ||
5 | reaction, | ||
6 | } from 'mobx'; | ||
2 | import { theme } from '@meetfranz/theme'; | 7 | import { theme } from '@meetfranz/theme'; |
3 | 8 | ||
4 | import Store from './lib/Store'; | 9 | import Store from './lib/Store'; |
@@ -15,10 +20,18 @@ export default class UIStore extends Store { | |||
15 | this.actions.ui.toggleServiceUpdatedInfoBar.listen(this._toggleServiceUpdatedInfoBar.bind(this)); | 20 | this.actions.ui.toggleServiceUpdatedInfoBar.listen(this._toggleServiceUpdatedInfoBar.bind(this)); |
16 | } | 21 | } |
17 | 22 | ||
23 | setup() { | ||
24 | reaction( | ||
25 | () => this.isDarkThemeActive, | ||
26 | () => this._setupThemeInDOM(), | ||
27 | { fireImmediately: true }, | ||
28 | ); | ||
29 | } | ||
30 | |||
18 | @computed get showMessageBadgesEvenWhenMuted() { | 31 | @computed get showMessageBadgesEvenWhenMuted() { |
19 | const settings = this.stores.settings.all; | 32 | const settings = this.stores.settings.all; |
20 | 33 | ||
21 | return (settings.app.isAppMuted && settings.app.showMessageBadgeWhenMuted) || !settings.isAppMuted; | 34 | return (settings.app.isAppMuted && settings.app.showMessageBadgeWhenMuted) || !settings.app.isAppMuted; |
22 | } | 35 | } |
23 | 36 | ||
24 | @computed get isDarkThemeActive() { | 37 | @computed get isDarkThemeActive() { |
@@ -26,7 +39,7 @@ export default class UIStore extends Store { | |||
26 | } | 39 | } |
27 | 40 | ||
28 | @computed get theme() { | 41 | @computed get theme() { |
29 | if (this.isDarkThemeActive) return theme('dark'); | 42 | if (this.isDarkThemeActive || this.stores.settings.app.darkMode) return theme('dark'); |
30 | return theme('default'); | 43 | return theme('default'); |
31 | } | 44 | } |
32 | 45 | ||
@@ -47,4 +60,15 @@ export default class UIStore extends Store { | |||
47 | } | 60 | } |
48 | this.showServicesUpdatedInfoBar = visibility; | 61 | this.showServicesUpdatedInfoBar = visibility; |
49 | } | 62 | } |
63 | |||
64 | // Reactions | ||
65 | _setupThemeInDOM() { | ||
66 | const body = document.querySelector('body'); | ||
67 | |||
68 | if (!this.isDarkThemeActive) { | ||
69 | body.classList.remove('theme__dark'); | ||
70 | } else { | ||
71 | body.classList.add('theme__dark'); | ||
72 | } | ||
73 | } | ||
50 | } | 74 | } |
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js index b5423af3b..f3dfbdbf0 100644 --- a/src/stores/UserStore.js +++ b/src/stores/UserStore.js | |||
@@ -2,12 +2,14 @@ import { observable, computed, action } from 'mobx'; | |||
2 | import moment from 'moment'; | 2 | import moment from 'moment'; |
3 | import jwt from 'jsonwebtoken'; | 3 | import jwt from 'jsonwebtoken'; |
4 | import localStorage from 'mobx-localstorage'; | 4 | import localStorage from 'mobx-localstorage'; |
5 | import ms from 'ms'; | ||
5 | 6 | ||
6 | import { isDevMode } from '../environment'; | 7 | import { isDevMode } from '../environment'; |
7 | import Store from './lib/Store'; | 8 | import Store from './lib/Store'; |
8 | import Request from './lib/Request'; | 9 | import Request from './lib/Request'; |
9 | import CachedRequest from './lib/CachedRequest'; | 10 | import CachedRequest from './lib/CachedRequest'; |
10 | import { gaEvent } from '../lib/analytics'; | 11 | import { gaEvent } from '../lib/analytics'; |
12 | import { sleep } from '../helpers/async-helpers'; | ||
11 | 13 | ||
12 | const debug = require('debug')('Franz:UserStore'); | 14 | const debug = require('debug')('Franz:UserStore'); |
13 | 15 | ||
@@ -37,6 +39,8 @@ export default class UserStore extends Store { | |||
37 | 39 | ||
38 | @observable passwordRequest = new Request(this.api.user, 'password'); | 40 | @observable passwordRequest = new Request(this.api.user, 'password'); |
39 | 41 | ||
42 | @observable activateTrialRequest = new Request(this.api.user, 'activateTrial'); | ||
43 | |||
40 | @observable inviteRequest = new Request(this.api.user, 'invite'); | 44 | @observable inviteRequest = new Request(this.api.user, 'invite'); |
41 | 45 | ||
42 | @observable getUserInfoRequest = new CachedRequest(this.api.user, 'getInfo'); | 46 | @observable getUserInfoRequest = new CachedRequest(this.api.user, 'getInfo'); |
@@ -57,7 +61,9 @@ export default class UserStore extends Store { | |||
57 | 61 | ||
58 | @observable accountType; | 62 | @observable accountType; |
59 | 63 | ||
60 | @observable hasCompletedSignup = null; | 64 | @observable hasCompletedSignup = false; |
65 | |||
66 | @observable hasActivatedTrial = false; | ||
61 | 67 | ||
62 | @observable userData = {}; | 68 | @observable userData = {}; |
63 | 69 | ||
@@ -77,6 +83,7 @@ export default class UserStore extends Store { | |||
77 | this.actions.user.retrievePassword.listen(this._retrievePassword.bind(this)); | 83 | this.actions.user.retrievePassword.listen(this._retrievePassword.bind(this)); |
78 | this.actions.user.logout.listen(this._logout.bind(this)); | 84 | this.actions.user.logout.listen(this._logout.bind(this)); |
79 | this.actions.user.signup.listen(this._signup.bind(this)); | 85 | this.actions.user.signup.listen(this._signup.bind(this)); |
86 | this.actions.user.activateTrial.listen(this._activateTrial.bind(this)); | ||
80 | this.actions.user.invite.listen(this._invite.bind(this)); | 87 | this.actions.user.invite.listen(this._invite.bind(this)); |
81 | this.actions.user.update.listen(this._update.bind(this)); | 88 | this.actions.user.update.listen(this._update.bind(this)); |
82 | this.actions.user.resetStatus.listen(this._resetStatus.bind(this)); | 89 | this.actions.user.resetStatus.listen(this._resetStatus.bind(this)); |
@@ -87,6 +94,7 @@ export default class UserStore extends Store { | |||
87 | this.registerReactions([ | 94 | this.registerReactions([ |
88 | this._requireAuthenticatedUser, | 95 | this._requireAuthenticatedUser, |
89 | this._getUserData.bind(this), | 96 | this._getUserData.bind(this), |
97 | this._resetTrialActivationState.bind(this), | ||
90 | ]); | 98 | ]); |
91 | } | 99 | } |
92 | 100 | ||
@@ -199,6 +207,24 @@ export default class UserStore extends Store { | |||
199 | gaEvent('User', 'retrievePassword'); | 207 | gaEvent('User', 'retrievePassword'); |
200 | } | 208 | } |
201 | 209 | ||
210 | @action async _activateTrial({ planId }) { | ||
211 | debug('activate trial', planId); | ||
212 | |||
213 | this.activateTrialRequest.execute({ | ||
214 | plan: planId, | ||
215 | }); | ||
216 | |||
217 | await this.activateTrialRequest._promise; | ||
218 | |||
219 | this.hasActivatedTrial = true; | ||
220 | |||
221 | this.stores.features.featuresRequest.invalidate({ immediately: true }); | ||
222 | this.stores.user.getUserInfoRequest.invalidate({ immediately: true }); | ||
223 | |||
224 | |||
225 | gaEvent('User', 'activateTrial'); | ||
226 | } | ||
227 | |||
202 | @action async _invite({ invites }) { | 228 | @action async _invite({ invites }) { |
203 | const data = invites.filter(invite => invite.email !== ''); | 229 | const data = invites.filter(invite => invite.email !== ''); |
204 | 230 | ||
@@ -318,6 +344,14 @@ export default class UserStore extends Store { | |||
318 | } | 344 | } |
319 | } | 345 | } |
320 | 346 | ||
347 | async _resetTrialActivationState() { | ||
348 | if (this.hasActivatedTrial) { | ||
349 | await sleep(ms('12s')); | ||
350 | |||
351 | this.hasActivatedTrial = false; | ||
352 | } | ||
353 | } | ||
354 | |||
321 | // Helpers | 355 | // Helpers |
322 | _parseToken(authToken) { | 356 | _parseToken(authToken) { |
323 | try { | 357 | try { |
@@ -347,6 +381,15 @@ export default class UserStore extends Store { | |||
347 | } | 381 | } |
348 | } | 382 | } |
349 | 383 | ||
384 | getAuthURL(url) { | ||
385 | const parsedUrl = new URL(url); | ||
386 | const params = new URLSearchParams(parsedUrl.search.slice(1)); | ||
387 | |||
388 | params.append('authToken', this.authToken); | ||
389 | |||
390 | return `${parsedUrl.origin}${parsedUrl.pathname}?${params.toString()}`; | ||
391 | } | ||
392 | |||
350 | async _migrateUserLocale() { | 393 | async _migrateUserLocale() { |
351 | await this.getUserInfoRequest._promise; | 394 | await this.getUserInfoRequest._promise; |
352 | 395 | ||
diff --git a/src/stores/index.js b/src/stores/index.js index 1912418a2..10dd56665 100644 --- a/src/stores/index.js +++ b/src/stores/index.js | |||
@@ -12,6 +12,9 @@ import RequestStore from './RequestStore'; | |||
12 | import GlobalErrorStore from './GlobalErrorStore'; | 12 | import GlobalErrorStore from './GlobalErrorStore'; |
13 | import { workspaceStore } from '../features/workspaces'; | 13 | import { workspaceStore } from '../features/workspaces'; |
14 | import { announcementsStore } from '../features/announcements'; | 14 | import { announcementsStore } from '../features/announcements'; |
15 | import { serviceLimitStore } from '../features/serviceLimit'; | ||
16 | import { communityRecipesStore } from '../features/communityRecipes'; | ||
17 | import { todosStore } from '../features/todos'; | ||
15 | 18 | ||
16 | export default (api, actions, router) => { | 19 | export default (api, actions, router) => { |
17 | const stores = {}; | 20 | const stores = {}; |
@@ -31,6 +34,9 @@ export default (api, actions, router) => { | |||
31 | globalError: new GlobalErrorStore(stores, api, actions), | 34 | globalError: new GlobalErrorStore(stores, api, actions), |
32 | workspaces: workspaceStore, | 35 | workspaces: workspaceStore, |
33 | announcements: announcementsStore, | 36 | announcements: announcementsStore, |
37 | serviceLimit: serviceLimitStore, | ||
38 | communityRecipes: communityRecipesStore, | ||
39 | todos: todosStore, | ||
34 | }); | 40 | }); |
35 | // Initialize all stores | 41 | // Initialize all stores |
36 | Object.keys(stores).forEach((name) => { | 42 | Object.keys(stores).forEach((name) => { |
diff --git a/src/stores/lib/Reaction.js b/src/stores/lib/Reaction.js index f2642908f..f8009b7f6 100644 --- a/src/stores/lib/Reaction.js +++ b/src/stores/lib/Reaction.js | |||
@@ -13,15 +13,15 @@ export default class Reaction { | |||
13 | 13 | ||
14 | start() { | 14 | start() { |
15 | if (!this.isRunning) { | 15 | if (!this.isRunning) { |
16 | this.dispose = autorun(() => this.reaction()); | 16 | this.dispose = autorun(this.reaction); |
17 | this.isActive = true; | 17 | this.isRunning = true; |
18 | } | 18 | } |
19 | } | 19 | } |
20 | 20 | ||
21 | stop() { | 21 | stop() { |
22 | if (this.isRunning) { | 22 | if (this.isRunning) { |
23 | this.dispose(); | 23 | this.dispose(); |
24 | this.isActive = false; | 24 | this.isRunning = false; |
25 | } | 25 | } |
26 | } | 26 | } |
27 | } | 27 | } |
diff --git a/src/styles/auth.scss b/src/styles/auth.scss index 0a075036a..154a71a36 100644 --- a/src/styles/auth.scss +++ b/src/styles/auth.scss | |||
@@ -9,7 +9,7 @@ | |||
9 | } | 9 | } |
10 | 10 | ||
11 | .auth__logo.auth__logo--sm { | 11 | .auth__logo.auth__logo--sm { |
12 | border: 4px solid $dark-theme-black; | 12 | border: none; |
13 | box-shadow: 0 0 6px rgba($dark-theme-black, .5); | 13 | box-shadow: 0 0 6px rgba($dark-theme-black, .5); |
14 | } | 14 | } |
15 | 15 | ||
diff --git a/src/styles/layout.scss b/src/styles/layout.scss index e858b7904..10027da60 100644 --- a/src/styles/layout.scss +++ b/src/styles/layout.scss | |||
@@ -33,13 +33,19 @@ html { overflow: hidden; } | |||
33 | } | 33 | } |
34 | 34 | ||
35 | .app { | 35 | .app { |
36 | display: flex; | 36 | //display: flex; |
37 | flex-direction: column; | 37 | |
38 | .app__content { | ||
39 | display: flex; | ||
40 | width: calc(100% + 300px); | ||
41 | } | ||
38 | 42 | ||
39 | .app__content { display: flex; } | 43 | .app__main-content { |
44 | display: flex; | ||
45 | width: 100%; | ||
46 | } | ||
40 | 47 | ||
41 | .app__service { | 48 | .app__service { |
42 | position: relative; | ||
43 | display: flex; | 49 | display: flex; |
44 | flex: 1; | 50 | flex: 1; |
45 | flex-direction: column; | 51 | flex-direction: column; |
diff --git a/src/styles/recipes.scss b/src/styles/recipes.scss index 84222e1fe..5bdc60a57 100644 --- a/src/styles/recipes.scss +++ b/src/styles/recipes.scss | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | .theme__dark .recipe-teaser { | 3 | .theme__dark .recipe-teaser { |
4 | background-color: $dark-theme-gray-dark; | 4 | background-color: $dark-theme-gray-dark; |
5 | color: $dark-theme-text-color; | ||
5 | 6 | ||
6 | &:hover { background-color: $dark-theme-gray; } | 7 | &:hover { background-color: $dark-theme-gray; } |
7 | } | 8 | } |
@@ -12,7 +13,7 @@ | |||
12 | display: flex; | 13 | display: flex; |
13 | flex-flow: row wrap; | 14 | flex-flow: row wrap; |
14 | height: auto; | 15 | height: auto; |
15 | min-height: 70%; | 16 | // min-height: 70%; |
16 | 17 | ||
17 | &.recipes__list--disabled { | 18 | &.recipes__list--disabled { |
18 | filter: grayscale(100%); | 19 | filter: grayscale(100%); |
diff --git a/src/styles/reset.scss b/src/styles/reset.scss index 80328dcef..d87ce652a 100644 --- a/src/styles/reset.scss +++ b/src/styles/reset.scss | |||
@@ -51,7 +51,6 @@ button { | |||
51 | padding: 0; | 51 | padding: 0; |
52 | 52 | ||
53 | &:focus { outline: 0; } | 53 | &:focus { outline: 0; } |
54 | .theme__dark & { color: $dark-theme-gray-smoke; } | ||
55 | } | 54 | } |
56 | 55 | ||
57 | html { | 56 | html { |
@@ -64,7 +63,7 @@ body { | |||
64 | font-size: 1.4rem; | 63 | font-size: 1.4rem; |
65 | line-height: 1; | 64 | line-height: 1; |
66 | 65 | ||
67 | .theme__dark { color: $dark-theme-gray-smoke; } | 66 | &.theme__dark { color: $dark-theme-gray-smoke; } |
68 | } | 67 | } |
69 | 68 | ||
70 | * { | 69 | * { |
diff --git a/src/styles/settings.scss b/src/styles/settings.scss index 1baff8b54..0955aaa0c 100644 --- a/src/styles/settings.scss +++ b/src/styles/settings.scss | |||
@@ -360,6 +360,7 @@ | |||
360 | .account__subscription-button { margin-left: auto; } | 360 | .account__subscription-button { margin-left: auto; } |
361 | .franz-form__button { white-space: nowrap; } | 361 | .franz-form__button { white-space: nowrap; } |
362 | div { height: auto; } | 362 | div { height: auto; } |
363 | [data-type="franz-button"] div { height: 100% } | ||
363 | 364 | ||
364 | .invoices { | 365 | .invoices { |
365 | width: 100%; | 366 | width: 100%; |
diff --git a/src/webview/contextMenu.js b/src/webview/contextMenu.js index 967e8e667..663b1ebca 100644 --- a/src/webview/contextMenu.js +++ b/src/webview/contextMenu.js | |||
@@ -39,6 +39,23 @@ const buildMenuTpl = (props, suggestions, isSpellcheckEnabled, defaultSpellcheck | |||
39 | { | 39 | { |
40 | type: 'separator', | 40 | type: 'separator', |
41 | }, { | 41 | }, { |
42 | id: 'createTodo', | ||
43 | label: `Create todo: "${textSelection.length > 15 ? `${textSelection.slice(0, 15)}...` : textSelection}"`, | ||
44 | visible: hasText, | ||
45 | click() { | ||
46 | debug('Create todo from selected text', textSelection); | ||
47 | ipcRenderer.sendToHost('feature:todos', { | ||
48 | action: 'create:todo', | ||
49 | data: { | ||
50 | title: textSelection, | ||
51 | url: window.location.href, | ||
52 | }, | ||
53 | }); | ||
54 | }, | ||
55 | }, | ||
56 | { | ||
57 | type: 'separator', | ||
58 | }, { | ||
42 | id: 'lookup', | 59 | id: 'lookup', |
43 | label: `Look Up "${textSelection.length > 15 ? `${textSelection.slice(0, 15)}...` : textSelection}"`, | 60 | label: `Look Up "${textSelection.length > 15 ? `${textSelection.slice(0, 15)}...` : textSelection}"`, |
44 | visible: isMac && props.mediaType === 'none' && hasText, | 61 | visible: isMac && props.mediaType === 'none' && hasText, |
@@ -280,13 +297,12 @@ const buildMenuTpl = (props, suggestions, isSpellcheckEnabled, defaultSpellcheck | |||
280 | }; | 297 | }; |
281 | 298 | ||
282 | export default function contextMenu(spellcheckProvider, isSpellcheckEnabled, getDefaultSpellcheckerLanguage, getSpellcheckerLanguage) { | 299 | export default function contextMenu(spellcheckProvider, isSpellcheckEnabled, getDefaultSpellcheckerLanguage, getSpellcheckerLanguage) { |
283 | webContents.on('context-menu', async (e, props) => { | 300 | webContents.on('context-menu', (e, props) => { |
284 | e.preventDefault(); | 301 | e.preventDefault(); |
285 | 302 | ||
286 | let suggestions = []; | 303 | let suggestions = []; |
287 | if (spellcheckProvider && props.misspelledWord) { | 304 | if (spellcheckProvider && props.misspelledWord) { |
288 | debug('Mispelled word', props.misspelledWord); | 305 | suggestions = spellcheckProvider.getSuggestion(props.misspelledWord); |
289 | suggestions = await spellcheckProvider.getSuggestion(props.misspelledWord); | ||
290 | 306 | ||
291 | debug('Suggestions', suggestions); | 307 | debug('Suggestions', suggestions); |
292 | } | 308 | } |
diff --git a/src/webview/spellchecker.js b/src/webview/spellchecker.js index 417d1ea1a..9158b3b94 100644 --- a/src/webview/spellchecker.js +++ b/src/webview/spellchecker.js | |||
@@ -1,8 +1,6 @@ | |||
1 | import { webFrame } from 'electron'; | 1 | import { webFrame } from 'electron'; |
2 | import { attachSpellCheckProvider, SpellCheckerProvider } from 'electron-hunspell'; | 2 | import { SpellCheckerProvider } from 'electron-hunspell'; |
3 | import { ENVIRONMENT } from 'hunspell-asm'; | ||
4 | import path from 'path'; | 3 | import path from 'path'; |
5 | import { readFileSync } from 'fs'; | ||
6 | 4 | ||
7 | import { DICTIONARY_PATH } from '../config'; | 5 | import { DICTIONARY_PATH } from '../config'; |
8 | import { SPELLCHECKER_LOCALES } from '../i18n/languages'; | 6 | import { SPELLCHECKER_LOCALES } from '../i18n/languages'; |
@@ -12,12 +10,11 @@ const debug = require('debug')('Franz:spellchecker'); | |||
12 | let provider; | 10 | let provider; |
13 | let currentDict; | 11 | let currentDict; |
14 | let _isEnabled = false; | 12 | let _isEnabled = false; |
15 | let attached; | ||
16 | 13 | ||
17 | async function loadDictionary(locale) { | 14 | async function loadDictionary(locale) { |
18 | try { | 15 | try { |
19 | const fileLocation = path.join(DICTIONARY_PATH, `hunspell-dict-${locale}/${locale}`); | 16 | const fileLocation = path.join(DICTIONARY_PATH, `hunspell-dict-${locale}/${locale}`); |
20 | await provider.loadDictionary(locale, readFileSync(`${fileLocation}.dic`), readFileSync(`${fileLocation}.aff`)); | 17 | await provider.loadDictionary(locale, `${fileLocation}.dic`, `${fileLocation}.aff`); |
21 | debug('Loaded dictionary', locale, 'from', fileLocation); | 18 | debug('Loaded dictionary', locale, 'from', fileLocation); |
22 | } catch (err) { | 19 | } catch (err) { |
23 | console.error('Could not load dictionary', err); | 20 | console.error('Could not load dictionary', err); |
@@ -44,7 +41,7 @@ export async function switchDict(locale) { | |||
44 | provider.unloadDictionary(locale); | 41 | provider.unloadDictionary(locale); |
45 | } | 42 | } |
46 | loadDictionary(locale); | 43 | loadDictionary(locale); |
47 | attached.switchLanguage(locale); | 44 | provider.switchDictionary(locale); |
48 | 45 | ||
49 | debug('Switched dictionary to', locale); | 46 | debug('Switched dictionary to', locale); |
50 | 47 | ||
@@ -61,14 +58,12 @@ export default async function initialize(languageCode = 'en-us') { | |||
61 | const locale = languageCode.toLowerCase(); | 58 | const locale = languageCode.toLowerCase(); |
62 | 59 | ||
63 | debug('Init spellchecker'); | 60 | debug('Init spellchecker'); |
64 | await provider.initialize({ environment: ENVIRONMENT.NODE }); | 61 | await provider.initialize(); |
65 | 62 | // await loadDictionaries(); | |
66 | debug('Attaching spellcheck provider'); | ||
67 | attached = await attachSpellCheckProvider(provider); | ||
68 | 63 | ||
69 | debug('Available spellchecker dictionaries', provider.availableDictionaries); | 64 | debug('Available spellchecker dictionaries', provider.availableDictionaries); |
70 | 65 | ||
71 | attached.switchLanguage(locale); | 66 | switchDict(locale); |
72 | 67 | ||
73 | return provider; | 68 | return provider; |
74 | } catch (err) { | 69 | } catch (err) { |
diff --git a/uidev/src/stories/button.stories.tsx b/uidev/src/stories/button.stories.tsx index f7537895c..5c1c9246d 100644 --- a/uidev/src/stories/button.stories.tsx +++ b/uidev/src/stories/button.stories.tsx | |||
@@ -1,10 +1,10 @@ | |||
1 | import { mdiInformation } from '@mdi/js'; | ||
1 | import { observable } from 'mobx'; | 2 | import { observable } from 'mobx'; |
2 | import { observer } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
3 | import React from 'react'; | 4 | import React from 'react'; |
4 | import injectSheet from 'react-jss'; | 5 | import injectSheet from 'react-jss'; |
5 | 6 | ||
6 | import { Button, Input } from '@meetfranz/forms'; | 7 | import { Button, Input } from '@meetfranz/forms'; |
7 | import { classes } from 'istanbul-lib-coverage'; | ||
8 | import { Classes } from 'jss'; | 8 | import { Classes } from 'jss'; |
9 | import { storiesOf } from '../stores/stories'; | 9 | import { storiesOf } from '../stores/stories'; |
10 | 10 | ||
@@ -92,7 +92,7 @@ storiesOf('Button') | |||
92 | )) | 92 | )) |
93 | .add('With icon', () => ( | 93 | .add('With icon', () => ( |
94 | <WithStoreButton store={createStore({ | 94 | <WithStoreButton store={createStore({ |
95 | icon: 'mdiInformation', | 95 | icon: mdiInformation, |
96 | })} /> | 96 | })} /> |
97 | )) | 97 | )) |
98 | .add('As link', () => ( | 98 | .add('As link', () => ( |
@@ -131,7 +131,7 @@ storiesOf('Button') | |||
131 | <div className={classes.combinedElements}> | 131 | <div className={classes.combinedElements}> |
132 | <Input showLabel={false} className={classes.input} noMargin /> | 132 | <Input showLabel={false} className={classes.input} noMargin /> |
133 | <WithStoreButton store={createStore({ | 133 | <WithStoreButton store={createStore({ |
134 | icon: 'mdiInformation', | 134 | icon: mdiInformation, |
135 | })} /> | 135 | })} /> |
136 | </div> | 136 | </div> |
137 | )), | 137 | )), |
diff --git a/uidev/src/stories/icon.stories.tsx b/uidev/src/stories/icon.stories.tsx index c8e7f8ced..f9aa1635b 100644 --- a/uidev/src/stories/icon.stories.tsx +++ b/uidev/src/stories/icon.stories.tsx | |||
@@ -1,53 +1,14 @@ | |||
1 | import { observable } from 'mobx'; | 1 | import { mdiAccountCircle } from '@mdi/js'; |
2 | import { observer } from 'mobx-react'; | ||
3 | import React from 'react'; | 2 | import React from 'react'; |
4 | import uuid from 'uuid/v4'; | ||
5 | 3 | ||
6 | import { Icon } from '@meetfranz/ui'; | 4 | import { Icon } from '@meetfranz/ui'; |
7 | import { storiesOf } from '../stores/stories'; | 5 | import { storiesOf } from '../stores/stories'; |
8 | 6 | ||
9 | // interface IStoreArgs { | ||
10 | // value?: boolean; | ||
11 | // checked?: boolean; | ||
12 | // label?: string; | ||
13 | // id?: string; | ||
14 | // name?: string; | ||
15 | // disabled?: boolean; | ||
16 | // error?: string; | ||
17 | // } | ||
18 | |||
19 | // const createStore = (args?: IStoreArgs) => { | ||
20 | // return observable(Object.assign({ | ||
21 | // id: `element-${uuid()}`, | ||
22 | // name: 'toggle', | ||
23 | // label: 'Label', | ||
24 | // value: true, | ||
25 | // checked: false, | ||
26 | // disabled: false, | ||
27 | // error: '', | ||
28 | // }, args)); | ||
29 | // }; | ||
30 | |||
31 | // const WithStoreToggle = observer(({ store }: { store: any }) => ( | ||
32 | // <> | ||
33 | // <Toggle | ||
34 | // value={store.value} | ||
35 | // checked={store.checked} | ||
36 | // label={store.label} | ||
37 | // id={store.id} | ||
38 | // name={store.name} | ||
39 | // disabled={store.disabled} | ||
40 | // error={store.error} | ||
41 | // onChange={() => store.checked = !store.checked} | ||
42 | // /> | ||
43 | // </> | ||
44 | // )); | ||
45 | |||
46 | storiesOf('Icon') | 7 | storiesOf('Icon') |
47 | .add('Basic', () => ( | 8 | .add('Basic', () => ( |
48 | <> | 9 | <> |
49 | <Icon icon="mdiAccountCircle" /> | 10 | <Icon icon={mdiAccountCircle} /> |
50 | <Icon icon="mdiAccountCircle" size={2} /> | 11 | <Icon icon={mdiAccountCircle} size={2} /> |
51 | <Icon icon="mdiAccountCircle" size={3} /> | 12 | <Icon icon={mdiAccountCircle} size={3} /> |
52 | </> | 13 | </> |
53 | )); | 14 | )); |
diff --git a/uidev/src/stories/infobox.stories.tsx b/uidev/src/stories/infobox.stories.tsx index 144855376..c3442da0d 100644 --- a/uidev/src/stories/infobox.stories.tsx +++ b/uidev/src/stories/infobox.stories.tsx | |||
@@ -1,3 +1,4 @@ | |||
1 | import { mdiEarth } from '@mdi/js'; | ||
1 | import { observable } from 'mobx'; | 2 | import { observable } from 'mobx'; |
2 | import { observer } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
3 | import React from 'react'; | 4 | import React from 'react'; |
@@ -44,7 +45,7 @@ storiesOf('Infobox') | |||
44 | .add('Icon + Dismissable', () => ( | 45 | .add('Icon + Dismissable', () => ( |
45 | <WithStoreInfobox | 46 | <WithStoreInfobox |
46 | store={createStore({ | 47 | store={createStore({ |
47 | icon: 'mdiEarth', | 48 | icon: mdiEarth, |
48 | dismissable: true, | 49 | dismissable: true, |
49 | })} | 50 | })} |
50 | > | 51 | > |
@@ -54,7 +55,7 @@ storiesOf('Infobox') | |||
54 | .add('With CTA', () => ( | 55 | .add('With CTA', () => ( |
55 | <WithStoreInfobox | 56 | <WithStoreInfobox |
56 | store={createStore({ | 57 | store={createStore({ |
57 | icon: 'mdiEarth', | 58 | icon: mdiEarth, |
58 | ctaLabel: 'Ok, hi!', | 59 | ctaLabel: 'Ok, hi!', |
59 | })} | 60 | })} |
60 | > | 61 | > |
@@ -64,7 +65,7 @@ storiesOf('Infobox') | |||
64 | .add('With long text', () => ( | 65 | .add('With long text', () => ( |
65 | <WithStoreInfobox | 66 | <WithStoreInfobox |
66 | store={createStore({ | 67 | store={createStore({ |
67 | icon: 'mdiEarth', | 68 | icon: mdiEarth, |
68 | ctaLabel: 'Ok, hi!', | 69 | ctaLabel: 'Ok, hi!', |
69 | })} | 70 | })} |
70 | > | 71 | > |
@@ -74,7 +75,7 @@ storiesOf('Infobox') | |||
74 | .add('Secondary', () => ( | 75 | .add('Secondary', () => ( |
75 | <WithStoreInfobox | 76 | <WithStoreInfobox |
76 | store={createStore({ | 77 | store={createStore({ |
77 | icon: 'mdiEarth', | 78 | icon: mdiEarth, |
78 | ctaLabel: 'Ok, hi!', | 79 | ctaLabel: 'Ok, hi!', |
79 | type: 'secondary', | 80 | type: 'secondary', |
80 | })} | 81 | })} |
@@ -85,7 +86,7 @@ storiesOf('Infobox') | |||
85 | .add('Success', () => ( | 86 | .add('Success', () => ( |
86 | <WithStoreInfobox | 87 | <WithStoreInfobox |
87 | store={createStore({ | 88 | store={createStore({ |
88 | icon: 'mdiEarth', | 89 | icon: mdiEarth, |
89 | ctaLabel: 'Ok, hi!', | 90 | ctaLabel: 'Ok, hi!', |
90 | type: 'success', | 91 | type: 'success', |
91 | })} | 92 | })} |
@@ -96,7 +97,7 @@ storiesOf('Infobox') | |||
96 | .add('Warning', () => ( | 97 | .add('Warning', () => ( |
97 | <WithStoreInfobox | 98 | <WithStoreInfobox |
98 | store={createStore({ | 99 | store={createStore({ |
99 | icon: 'mdiEarth', | 100 | icon: mdiEarth, |
100 | ctaLabel: 'Ok, hi!', | 101 | ctaLabel: 'Ok, hi!', |
101 | type: 'warning', | 102 | type: 'warning', |
102 | })} | 103 | })} |
@@ -107,7 +108,7 @@ storiesOf('Infobox') | |||
107 | .add('Danger', () => ( | 108 | .add('Danger', () => ( |
108 | <WithStoreInfobox | 109 | <WithStoreInfobox |
109 | store={createStore({ | 110 | store={createStore({ |
110 | icon: 'mdiEarth', | 111 | icon: mdiEarth, |
111 | ctaLabel: 'Ok, hi!', | 112 | ctaLabel: 'Ok, hi!', |
112 | type: 'danger', | 113 | type: 'danger', |
113 | })} | 114 | })} |
@@ -118,7 +119,7 @@ storiesOf('Infobox') | |||
118 | .add('Inverted', () => ( | 119 | .add('Inverted', () => ( |
119 | <WithStoreInfobox | 120 | <WithStoreInfobox |
120 | store={createStore({ | 121 | store={createStore({ |
121 | icon: 'mdiEarth', | 122 | icon: mdiEarth, |
122 | ctaLabel: 'Ok, hi!', | 123 | ctaLabel: 'Ok, hi!', |
123 | type: 'inverted', | 124 | type: 'inverted', |
124 | })} | 125 | })} |