From 1bae1dfcbc4a5f590c51103635006198ae6a91d6 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Tue, 30 Apr 2019 15:23:38 +0200 Subject: Enforce service limit --- src/i18n/locales/defaultMessages.json | 205 +++++++++++++++++++++------------- src/i18n/locales/en-US.json | 3 +- 2 files changed, 129 insertions(+), 79 deletions(-) (limited to 'src/i18n/locales') diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index 632eb38fd..9980274d3 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -1411,104 +1411,104 @@ "defaultMessage": "!!!Available Services", "end": { "column": 3, - "line": 18 + "line": 19 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.headline", "start": { "column": 12, - "line": 15 + "line": 16 } }, { "defaultMessage": "!!!Search service", "end": { "column": 3, - "line": 22 + "line": 23 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.searchService", "start": { "column": 17, - "line": 19 + "line": 20 } }, { "defaultMessage": "!!!Most popular", "end": { "column": 3, - "line": 26 + "line": 27 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.mostPopular", "start": { "column": 22, - "line": 23 + "line": 24 } }, { "defaultMessage": "!!!All services", "end": { "column": 3, - "line": 30 + "line": 31 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.all", "start": { "column": 14, - "line": 27 + "line": 28 } }, { "defaultMessage": "!!!Development", "end": { "column": 3, - "line": 34 + "line": 35 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.dev", "start": { "column": 14, - "line": 31 + "line": 32 } }, { "defaultMessage": "!!!Sorry, but no service matched your search term.", "end": { "column": 3, - "line": 38 + "line": 39 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.nothingFound", "start": { "column": 16, - "line": 35 + "line": 36 } }, { "defaultMessage": "!!!Service successfully added", "end": { "column": 3, - "line": 42 + "line": 43 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.servicesSuccessfulAddedInfo", "start": { "column": 31, - "line": 39 + "line": 40 } }, { "defaultMessage": "!!!Missing a service?", "end": { "column": 3, - "line": 46 + "line": 47 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.missingService", "start": { "column": 18, - "line": 43 + "line": 44 } } ], @@ -1520,286 +1520,286 @@ "defaultMessage": "!!!Save service", "end": { "column": 3, - "line": 25 + "line": 26 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.saveButton", "start": { "column": 15, - "line": 22 + "line": 23 } }, { "defaultMessage": "!!!Delete Service", "end": { "column": 3, - "line": 29 + "line": 30 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.deleteButton", "start": { "column": 17, - "line": 26 + "line": 27 } }, { "defaultMessage": "!!!Available services", "end": { "column": 3, - "line": 33 + "line": 34 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.availableServices", "start": { "column": 21, - "line": 30 + "line": 31 } }, { "defaultMessage": "!!!Your services", "end": { "column": 3, - "line": 37 + "line": 38 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.yourServices", "start": { "column": 16, - "line": 34 + "line": 35 } }, { "defaultMessage": "!!!Add {name}", "end": { "column": 3, - "line": 41 + "line": 42 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.addServiceHeadline", "start": { "column": 22, - "line": 38 + "line": 39 } }, { "defaultMessage": "!!!Edit {name}", "end": { "column": 3, - "line": 45 + "line": 46 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.editServiceHeadline", "start": { "column": 23, - "line": 42 + "line": 43 } }, { "defaultMessage": "!!!Hosted", "end": { "column": 3, - "line": 49 + "line": 50 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.tabHosted", "start": { "column": 13, - "line": 46 + "line": 47 } }, { "defaultMessage": "!!!Self hosted ⭐️", "end": { "column": 3, - "line": 53 + "line": 54 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.tabOnPremise", "start": { "column": 16, - "line": 50 + "line": 51 } }, { "defaultMessage": "!!!Use the hosted {name} service.", "end": { "column": 3, - "line": 57 + "line": 58 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.useHostedService", "start": { "column": 20, - "line": 54 + "line": 55 } }, { "defaultMessage": "!!!Could not validate custom {name} server.", "end": { "column": 3, - "line": 61 + "line": 62 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.customUrlValidationError", "start": { "column": 28, - "line": 58 + "line": 59 } }, { "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", "end": { "column": 3, - "line": 65 + "line": 66 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.customUrlPremiumInfo", "start": { "column": 24, - "line": 62 + "line": 63 } }, { "defaultMessage": "!!!Upgrade your account", "end": { "column": 3, - "line": 69 + "line": 70 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.customUrlUpgradeAccount", "start": { "column": 27, - "line": 66 + "line": 67 } }, { "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", "end": { "column": 3, - "line": 73 + "line": 74 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.indirectMessageInfo", "start": { "column": 23, - "line": 70 + "line": 71 } }, { "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", "end": { "column": 3, - "line": 77 + "line": 78 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.isMutedInfo", "start": { "column": 15, - "line": 74 + "line": 75 } }, { "defaultMessage": "!!!Notifications", "end": { "column": 3, - "line": 81 + "line": 82 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.headlineNotifications", "start": { "column": 25, - "line": 78 + "line": 79 } }, { "defaultMessage": "!!!Unread message badges", "end": { "column": 3, - "line": 85 + "line": 86 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.headlineBadges", "start": { "column": 18, - "line": 82 + "line": 83 } }, { "defaultMessage": "!!!General", "end": { "column": 3, - "line": 89 + "line": 90 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.headlineGeneral", "start": { "column": 19, - "line": 86 + "line": 87 } }, { "defaultMessage": "!!!Delete", "end": { "column": 3, - "line": 93 + "line": 94 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.iconDelete", "start": { "column": 14, - "line": 90 + "line": 91 } }, { "defaultMessage": "!!!Drop your image, or click here", "end": { "column": 3, - "line": 97 + "line": 98 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.iconUpload", "start": { "column": 14, - "line": 94 + "line": 95 } }, { "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", "end": { "column": 3, - "line": 101 + "line": 102 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.proxy.headline", "start": { "column": 17, - "line": 98 + "line": 99 } }, { "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", "end": { "column": 3, - "line": 105 + "line": 106 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.proxy.restartInfo", "start": { "column": 20, - "line": 102 + "line": 103 } }, { "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", "end": { "column": 3, - "line": 109 + "line": 110 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.proxy.info", "start": { "column": 13, - "line": 106 + "line": 107 } } ], @@ -1912,117 +1912,117 @@ "defaultMessage": "!!!Your services", "end": { "column": 3, - "line": 17 + "line": 18 }, "file": "src/components/settings/services/ServicesDashboard.js", "id": "settings.services.headline", "start": { "column": 12, - "line": 14 + "line": 15 } }, { "defaultMessage": "!!!Search service", "end": { "column": 3, - "line": 21 + "line": 22 }, "file": "src/components/settings/services/ServicesDashboard.js", "id": "settings.searchService", "start": { "column": 17, - "line": 18 + "line": 19 } }, { "defaultMessage": "!!!You haven't added any services yet.", "end": { "column": 3, - "line": 25 + "line": 26 }, "file": "src/components/settings/services/ServicesDashboard.js", "id": "settings.services.noServicesAdded", "start": { "column": 19, - "line": 22 + "line": 23 } }, { "defaultMessage": "!!!Sorry, but no service matched your search term.", "end": { "column": 3, - "line": 29 + "line": 30 }, "file": "src/components/settings/services/ServicesDashboard.js", "id": "settings.recipes.nothingFound", "start": { "column": 18, - "line": 26 + "line": 27 } }, { "defaultMessage": "!!!Discover services", "end": { "column": 3, - "line": 33 + "line": 34 }, "file": "src/components/settings/services/ServicesDashboard.js", "id": "settings.services.discoverServices", "start": { "column": 20, - "line": 30 + "line": 31 } }, { "defaultMessage": "!!!Could not load your services", "end": { "column": 3, - "line": 37 + "line": 38 }, "file": "src/components/settings/services/ServicesDashboard.js", "id": "settings.services.servicesRequestFailed", "start": { "column": 25, - "line": 34 + "line": 35 } }, { "defaultMessage": "!!!Try again", "end": { "column": 3, - "line": 41 + "line": 42 }, "file": "src/components/settings/services/ServicesDashboard.js", "id": "settings.account.tryReloadServices", "start": { "column": 21, - "line": 38 + "line": 39 } }, { "defaultMessage": "!!!Your changes have been saved", "end": { "column": 3, - "line": 45 + "line": 46 }, "file": "src/components/settings/services/ServicesDashboard.js", "id": "settings.services.updatedInfo", "start": { "column": 15, - "line": 42 + "line": 43 } }, { "defaultMessage": "!!!Service has been deleted", "end": { "column": 3, - "line": 49 + "line": 50 }, "file": "src/components/settings/services/ServicesDashboard.js", "id": "settings.services.deletedInfo", "start": { "column": 15, - "line": 46 + "line": 47 } } ], @@ -3263,6 +3263,55 @@ ], "path": "src/features/delayApp/Component.json" }, + { + "descriptors": [ + { + "defaultMessage": "!!!Changes in Franz {version}", + "end": { + "column": 3, + "line": 23 + }, + "file": "src/features/serviceLimit/components/AnnouncementScreen.js", + "id": "feature.announcements.changelog.headline", + "start": { + "column": 12, + "line": 20 + } + } + ], + "path": "src/features/serviceLimit/components/AnnouncementScreen.json" + }, + { + "descriptors": [ + { + "defaultMessage": "!!!You have added {amount} of {amount} services. Please upgrade your account to add more services.", + "end": { + "column": 3, + "line": 16 + }, + "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", + "id": "feature.serviceLimit.limitReached", + "start": { + "column": 16, + "line": 13 + } + }, + { + "defaultMessage": "!!!Upgrade account", + "end": { + "column": 3, + "line": 20 + }, + "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", + "id": "premiumFeature.button.upgradeAccount", + "start": { + "column": 10, + "line": 17 + } + } + ], + "path": "src/features/serviceLimit/components/LimitReachedInfobox.json" + }, { "descriptors": [ { diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 6c2759dcc..1bc8fd2bf 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -5,6 +5,7 @@ "feature.delayApp.action": "Get a Franz Supporter License", "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", "feature.delayApp.text": "Franz will continue in {seconds} seconds.", + "feature.serviceLimit.limitReached": "You have added {amount} of {limit} services. Please upgrade your account to add more services.", "feature.shareFranz.action.email": "Send as email", "feature.shareFranz.action.facebook": "Share on Facebook", "feature.shareFranz.action.twitter": "Share on Twitter", @@ -328,4 +329,4 @@ "workspaceDrawer.workspaceFeatureInfo": "

Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

", "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", "workspaces.switchingIndicator.switchingTo": "Switching to" -} \ No newline at end of file +} -- cgit v1.2.3-70-g09d2 From fbff4ed90b0137088b1bb92e95f32fc1bfa7bb3e Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Thu, 2 May 2019 11:27:23 +0200 Subject: Add custom recipe limitation --- packages/ui/src/badge/ProBadge.tsx | 5 +- src/components/settings/recipes/RecipeItem.js | 2 +- .../settings/recipes/RecipesDashboard.js | 194 +++++++++++++++++---- src/config.js | 1 + src/containers/settings/RecipesScreen.js | 40 ++++- src/features/communityRecipes/index.js | 28 +++ src/features/communityRecipes/store.js | 31 ++++ src/i18n/locales/defaultMessages.json | 178 +++++++++++++++++-- src/i18n/locales/en-US.json | 8 +- .../settings/recipes/RecipesDashboard.json | 116 ++++++++++-- src/stores/FeaturesStore.js | 2 + src/stores/index.js | 2 + src/styles/recipes.scss | 2 +- 13 files changed, 526 insertions(+), 83 deletions(-) create mode 100644 src/features/communityRecipes/index.js create mode 100644 src/features/communityRecipes/store.js (limited to 'src/i18n/locales') diff --git a/packages/ui/src/badge/ProBadge.tsx b/packages/ui/src/badge/ProBadge.tsx index 612e23210..2dad7ef49 100644 --- a/packages/ui/src/badge/ProBadge.tsx +++ b/packages/ui/src/badge/ProBadge.tsx @@ -3,13 +3,14 @@ import classnames from 'classnames'; import React, { Component } from 'react'; import injectStyle from 'react-jss'; -import { Icon, Badge } from '../'; +import { Badge, Icon } from '../'; import { IWithStyle } from '../typings/generic'; interface IProps extends IWithStyle { badgeClasses?: string; iconClasses?: string; inverted?: boolean; + className?: string; } const styles = (theme: Theme) => ({ @@ -37,6 +38,7 @@ class ProBadgeComponent extends Component { badgeClasses, iconClasses, inverted, + className, } = this.props; return ( @@ -46,6 +48,7 @@ class ProBadgeComponent extends Component { classes.badge, inverted && classes.invertedBadge, badgeClasses, + className, ])} > - {recipe.local && ( + {recipe.isDevRecipe && ( dev )} div': { + fontFamily: 'SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace', + }, + }, + actionContainer: { + '& button': { + margin: [0, 10], + }, + }, + devRecipeList: { + marginTop: 20, + height: 'auto', + }, + proBadge: { + marginLeft: '10px !important', + }, +}; + +export default @injectSheet(styles) @observer class RecipesDashboard extends Component { static propTypes = { recipes: MobxPropTypes.arrayOrObservableArray.isRequired, isLoading: PropTypes.bool.isRequired, @@ -55,12 +111,19 @@ export default @observer class RecipesDashboard extends Component { searchRecipes: PropTypes.func.isRequired, resetSearch: PropTypes.func.isRequired, serviceStatus: MobxPropTypes.arrayOrObservableArray.isRequired, - devRecipesCount: PropTypes.number.isRequired, searchNeedle: PropTypes.string, + recipeFilter: PropTypes.string, + recipeDirectory: PropTypes.string.isRequired, + openRecipeDirectory: PropTypes.func.isRequired, + openDevDocs: PropTypes.func.isRequired, + classes: PropTypes.object.isRequired, + isCommunityRecipesPremiumFeature: PropTypes.bool.isRequired, + isUserPremiumUser: PropTypes.bool.isRequired, }; static defaultProps = { searchNeedle: '', + recipeFilter: 'all', } static contextTypes = { @@ -76,11 +139,21 @@ export default @observer class RecipesDashboard extends Component { searchRecipes, resetSearch, serviceStatus, - devRecipesCount, searchNeedle, + recipeFilter, + recipeDirectory, + openRecipeDirectory, + openDevDocs, + classes, + isCommunityRecipesPremiumFeature, + isUserPremiumUser, } = this.props; const { intl } = this.context; + + const communityRecipes = recipes.filter(r => !r.isDevRecipe); + const devRecipes = recipes.filter(r => r.isDevRecipe); + return (
@@ -122,20 +195,14 @@ export default @observer class RecipesDashboard extends Component { > {intl.formatMessage(messages.allRecipes)} - {devRecipesCount > 0 && ( - resetSearch()} - > - {intl.formatMessage(messages.devRecipes)} - {' '} -( - {devRecipesCount} -) - - )} + resetSearch()} + > + {intl.formatMessage(messages.customRecipes)} + {intl.formatMessage(messages.missingService)} {' '} @@ -146,23 +213,78 @@ export default @observer class RecipesDashboard extends Component { {isLoading ? ( ) : ( -
- {hasLoadedRecipes && recipes.length === 0 && ( -

- - - - {intl.formatMessage(messages.nothingFound)} -

+ <> + {recipeFilter === 'dev' && ( + <> +

+ {intl.formatMessage(messages.headlineCustomRecipes)} + {!isUserPremiumUser && ( + + )} +

+
+

+ {intl.formatMessage(messages.customRecipeIntro)} +

+ +
+
+
+ + )} + 0) && isCommunityRecipesPremiumFeature} + > + {recipeFilter === 'dev' && communityRecipes.length > 0 && ( +

{intl.formatMessage(messages.headlineCommunityRecipes)}

+ )} +
+ {hasLoadedRecipes && recipes.length === 0 && recipeFilter !== 'dev'( +

+ + + + {intl.formatMessage(messages.nothingFound)} +

, + )} + {communityRecipes.map(recipe => ( + showAddServiceInterface({ recipeId: recipe.id })} + /> + ))} +
+
+ {recipeFilter === 'dev' && devRecipes.length > 0 && ( +
+

{intl.formatMessage(messages.headlineDevRecipes)}

+
+ {devRecipes.map(recipe => ( + showAddServiceInterface({ recipeId: recipe.id })} + /> + ))} +
+
)} - {recipes.map(recipe => ( - showAddServiceInterface({ recipeId: recipe.id })} - /> - ))} -
+ )}
diff --git a/src/config.js b/src/config.js index 5bc318545..544f94fde 100644 --- a/src/config.js +++ b/src/config.js @@ -67,6 +67,7 @@ export const DEFAULT_WINDOW_OPTIONS = { export const FRANZ_SERVICE_REQUEST = 'https://bit.ly/franz-plugin-docs'; export const FRANZ_TRANSLATION = 'https://bit.ly/franz-translate'; +export const FRANZ_DEV_DOCS = 'http://bit.ly/franz-dev-hub'; export const FILE_SYSTEM_SETTINGS_TYPES = [ 'app', diff --git a/src/containers/settings/RecipesScreen.js b/src/containers/settings/RecipesScreen.js index eda5ae54c..57e879f42 100644 --- a/src/containers/settings/RecipesScreen.js +++ b/src/containers/settings/RecipesScreen.js @@ -1,7 +1,9 @@ +import { remote, shell } from 'electron'; import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { autorun } from 'mobx'; import { inject, observer } from 'mobx-react'; +import path from 'path'; import RecipePreviewsStore from '../../stores/RecipePreviewsStore'; import RecipeStore from '../../stores/RecipesStore'; @@ -10,6 +12,11 @@ import UserStore from '../../stores/UserStore'; import RecipesDashboard from '../../components/settings/recipes/RecipesDashboard'; import ErrorBoundary from '../../components/util/ErrorBoundary'; +import { FRANZ_DEV_DOCS } from '../../config'; +import { gaEvent } from '../../lib/analytics'; +import { communityRecipesStore } from '../../features/communityRecipes'; + +const { app } = remote; export default @inject('stores', 'actions') @observer class RecipesScreen extends Component { static propTypes = { @@ -67,9 +74,16 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend render() { const { - recipePreviews, recipes, services, user, + recipePreviews, + recipes, + services, + user, } = this.props.stores; - const { showAddServiceInterface } = this.props.actions.service; + + const { + app: appActions, + service: serviceActions, + } = this.props.actions; const { filter } = this.props.params; let recipeFilter; @@ -77,7 +91,7 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend if (filter === 'all') { recipeFilter = recipePreviews.all; } else if (filter === 'dev') { - recipeFilter = recipePreviews.dev; + recipeFilter = communityRecipesStore.communityRecipes; } else { recipeFilter = recipePreviews.featured; } @@ -89,6 +103,8 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend || recipes.installRecipeRequest.isExecuting || recipePreviews.searchRecipePreviewsRequest.isExecuting; + const recipeDirectory = path.join(app.getPath('userData'), 'recipes', 'dev'); + return ( this.searchRecipes(e)} resetSearch={() => this.resetSearch()} searchNeedle={this.state.needle} serviceStatus={services.actionStatus} - devRecipesCount={recipePreviews.dev.length} + recipeFilter={filter} + recipeDirectory={recipeDirectory} + openRecipeDirectory={() => { + shell.openItem(recipeDirectory); + gaEvent('Recipe', 'open-recipe-folder', 'Open Folder'); + }} + openDevDocs={() => { + appActions.openExternalUrl({ url: FRANZ_DEV_DOCS }); + gaEvent('Recipe', 'open-dev-docs', 'Developer Documentation'); + }} + isCommunityRecipesPremiumFeature={communityRecipesStore.isCommunityRecipesPremiumFeature} + isUserPremiumUser={user.isPremium} /> ); @@ -117,6 +144,9 @@ RecipesScreen.wrappedComponent.propTypes = { user: PropTypes.instanceOf(UserStore).isRequired, }).isRequired, actions: PropTypes.shape({ + app: PropTypes.shape({ + openExternalUrl: PropTypes.func.isRequired, + }).isRequired, service: PropTypes.shape({ showAddServiceInterface: PropTypes.func.isRequired, }).isRequired, diff --git a/src/features/communityRecipes/index.js b/src/features/communityRecipes/index.js new file mode 100644 index 000000000..78e87855e --- /dev/null +++ b/src/features/communityRecipes/index.js @@ -0,0 +1,28 @@ +import { reaction } from 'mobx'; +import { CommunityRecipesStore } from './store'; + +const debug = require('debug')('Franz:feature:communityRecipes'); + +export const DEFAULT_SERVICE_LIMIT = 3; + +export const communityRecipesStore = new CommunityRecipesStore(); + +export default function initCommunityRecipes(stores, actions) { + const { features } = stores; + + communityRecipesStore.start(stores, actions); + + // Toggle communityRecipe premium status + reaction( + () => ( + features.features.isCommunityRecipesPremiumFeature + ), + (isPremiumFeature) => { + debug('Community recipes is premium feature: ', isPremiumFeature); + communityRecipesStore.isCommunityRecipesPremiumFeature = isPremiumFeature; + }, + { + fireImmediately: true, + }, + ); +} diff --git a/src/features/communityRecipes/store.js b/src/features/communityRecipes/store.js new file mode 100644 index 000000000..165b753e8 --- /dev/null +++ b/src/features/communityRecipes/store.js @@ -0,0 +1,31 @@ +import { computed, observable } from 'mobx'; +import { FeatureStore } from '../utils/FeatureStore'; + +const debug = require('debug')('Franz:feature:communityRecipes:store'); + +export class CommunityRecipesStore extends FeatureStore { + @observable isCommunityRecipesPremiumFeature = false; + + start(stores, actions) { + debug('start'); + this.stores = stores; + this.actions = actions; + } + + stop() { + debug('stop'); + super.stop(); + } + + @computed get communityRecipes() { + if (!this.stores) return []; + + return this.stores.recipePreviews.dev.map((r) => { + r.isDevRecipe = !!r.author.find(a => a.email === this.stores.user.data.email); + + return r; + }); + } +} + +export default CommunityRecipesStore; diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index 632eb38fd..9be12d369 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -1411,104 +1411,182 @@ "defaultMessage": "!!!Available Services", "end": { "column": 3, - "line": 18 + "line": 22 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.headline", "start": { "column": 12, - "line": 15 + "line": 19 } }, { "defaultMessage": "!!!Search service", "end": { "column": 3, - "line": 22 + "line": 26 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.searchService", "start": { "column": 17, - "line": 19 + "line": 23 } }, { "defaultMessage": "!!!Most popular", "end": { "column": 3, - "line": 26 + "line": 30 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.mostPopular", "start": { "column": 22, - "line": 23 + "line": 27 } }, { "defaultMessage": "!!!All services", "end": { "column": 3, - "line": 30 + "line": 34 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.all", "start": { "column": 14, - "line": 27 + "line": 31 } }, { - "defaultMessage": "!!!Development", + "defaultMessage": "!!!Custom Services", "end": { "column": 3, - "line": 34 + "line": 38 }, "file": "src/components/settings/recipes/RecipesDashboard.js", - "id": "settings.recipes.dev", + "id": "settings.recipes.custom", "start": { - "column": 14, - "line": 31 + "column": 17, + "line": 35 } }, { "defaultMessage": "!!!Sorry, but no service matched your search term.", "end": { "column": 3, - "line": 38 + "line": 42 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.nothingFound", "start": { "column": 16, - "line": 35 + "line": 39 } }, { "defaultMessage": "!!!Service successfully added", "end": { "column": 3, - "line": 42 + "line": 46 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.servicesSuccessfulAddedInfo", "start": { "column": 31, - "line": 39 + "line": 43 } }, { "defaultMessage": "!!!Missing a service?", "end": { "column": 3, - "line": 46 + "line": 50 }, "file": "src/components/settings/recipes/RecipesDashboard.js", "id": "settings.recipes.missingService", "start": { "column": 18, - "line": 43 + "line": 47 + } + }, + { + "defaultMessage": "!!!To add a custom service, copy the recipe folder into:", + "end": { + "column": 3, + "line": 54 + }, + "file": "src/components/settings/recipes/RecipesDashboard.js", + "id": "settings.recipes.customService.intro", + "start": { + "column": 21, + "line": 51 + } + }, + { + "defaultMessage": "!!!Open directory", + "end": { + "column": 3, + "line": 58 + }, + "file": "src/components/settings/recipes/RecipesDashboard.js", + "id": "settings.recipes.customService.openFolder", + "start": { + "column": 14, + "line": 55 + } + }, + { + "defaultMessage": "!!!Developer Documentation", + "end": { + "column": 3, + "line": 62 + }, + "file": "src/components/settings/recipes/RecipesDashboard.js", + "id": "settings.recipes.customService.openDevDocs", + "start": { + "column": 15, + "line": 59 + } + }, + { + "defaultMessage": "!!!Custom Service Recipes", + "end": { + "column": 3, + "line": 66 + }, + "file": "src/components/settings/recipes/RecipesDashboard.js", + "id": "settings.recipes.customService.headline.customRecipes", + "start": { + "column": 25, + "line": 63 + } + }, + { + "defaultMessage": "!!!Community Services", + "end": { + "column": 3, + "line": 70 + }, + "file": "src/components/settings/recipes/RecipesDashboard.js", + "id": "settings.recipes.customService.headline.communityRecipes", + "start": { + "column": 28, + "line": 67 + } + }, + { + "defaultMessage": "!!!Your Development Service Recipes", + "end": { + "column": 3, + "line": 74 + }, + "file": "src/components/settings/recipes/RecipesDashboard.js", + "id": "settings.recipes.customService.headline.devRecipes", + "start": { + "column": 22, + "line": 71 } } ], @@ -3219,6 +3297,37 @@ ], "path": "src/features/announcements/components/AnnouncementScreen.json" }, + { + "descriptors": [ + { + "defaultMessage": "!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.", + "end": { + "column": 3, + "line": 14 + }, + "file": "src/features/communityRecipes/components/LimitReachedInfobox.js", + "id": "feature.serviceLimit.limitReached", + "start": { + "column": 16, + "line": 11 + } + }, + { + "defaultMessage": "!!!Upgrade account", + "end": { + "column": 3, + "line": 18 + }, + "file": "src/features/communityRecipes/components/LimitReachedInfobox.js", + "id": "premiumFeature.button.upgradeAccount", + "start": { + "column": 10, + "line": 15 + } + } + ], + "path": "src/features/communityRecipes/components/LimitReachedInfobox.json" + }, { "descriptors": [ { @@ -3359,6 +3468,37 @@ ], "path": "src/features/shareFranz/Component.json" }, + { + "descriptors": [ + { + "defaultMessage": "!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.", + "end": { + "column": 3, + "line": 14 + }, + "file": "src/features/unofficialRecipes/components/LimitReachedInfobox.js", + "id": "feature.serviceLimit.limitReached", + "start": { + "column": 16, + "line": 11 + } + }, + { + "defaultMessage": "!!!Upgrade account", + "end": { + "column": 3, + "line": 18 + }, + "file": "src/features/unofficialRecipes/components/LimitReachedInfobox.js", + "id": "premiumFeature.button.upgradeAccount", + "start": { + "column": 10, + "line": 15 + } + } + ], + "path": "src/features/unofficialRecipes/components/LimitReachedInfobox.json" + }, { "descriptors": [ { diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 6c2759dcc..8bffea63c 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -181,7 +181,13 @@ "settings.navigation.yourServices": "Your services", "settings.navigation.yourWorkspaces": "Your workspaces", "settings.recipes.all": "All services", - "settings.recipes.dev": "Development", + "settings.recipes.custom": "Custom Services", + "settings.recipes.customService.headline.communityRecipes": "Community Services", + "settings.recipes.customService.headline.customRecipes": "Custom Service Recipes", + "settings.recipes.customService.headline.devRecipes": "Your Development Service Recipes", + "settings.recipes.customService.intro": "To add a custom service, copy the service recipe to:", + "settings.recipes.customService.openDevDocs": "Developer Documentation", + "settings.recipes.customService.openFolder": "Open folder", "settings.recipes.headline": "Available services", "settings.recipes.missingService": "Missing a service?", "settings.recipes.mostPopular": "Most popular", diff --git a/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json b/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json index 7d9ed3283..26dcd3da5 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 @@ "defaultMessage": "!!!Available Services", "file": "src/components/settings/recipes/RecipesDashboard.js", "start": { - "line": 15, + "line": 19, "column": 12 }, "end": { - "line": 18, + "line": 22, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!Search service", "file": "src/components/settings/recipes/RecipesDashboard.js", "start": { - "line": 19, + "line": 23, "column": 17 }, "end": { - "line": 22, + "line": 26, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Most popular", "file": "src/components/settings/recipes/RecipesDashboard.js", "start": { - "line": 23, + "line": 27, "column": 22 }, "end": { - "line": 26, + "line": 30, "column": 3 } }, @@ -43,24 +43,24 @@ "defaultMessage": "!!!All services", "file": "src/components/settings/recipes/RecipesDashboard.js", "start": { - "line": 27, + "line": 31, "column": 14 }, "end": { - "line": 30, + "line": 34, "column": 3 } }, { - "id": "settings.recipes.dev", - "defaultMessage": "!!!Development", + "id": "settings.recipes.custom", + "defaultMessage": "!!!Custom Services", "file": "src/components/settings/recipes/RecipesDashboard.js", "start": { - "line": 31, - "column": 14 + "line": 35, + "column": 17 }, "end": { - "line": 34, + "line": 38, "column": 3 } }, @@ -69,11 +69,11 @@ "defaultMessage": "!!!Sorry, but no service matched your search term.", "file": "src/components/settings/recipes/RecipesDashboard.js", "start": { - "line": 35, + "line": 39, "column": 16 }, "end": { - "line": 38, + "line": 42, "column": 3 } }, @@ -82,11 +82,11 @@ "defaultMessage": "!!!Service successfully added", "file": "src/components/settings/recipes/RecipesDashboard.js", "start": { - "line": 39, + "line": 43, "column": 31 }, "end": { - "line": 42, + "line": 46, "column": 3 } }, @@ -95,11 +95,89 @@ "defaultMessage": "!!!Missing a service?", "file": "src/components/settings/recipes/RecipesDashboard.js", "start": { - "line": 43, + "line": 47, "column": 18 }, "end": { - "line": 46, + "line": 50, + "column": 3 + } + }, + { + "id": "settings.recipes.customService.intro", + "defaultMessage": "!!!To add a custom service, copy the recipe folder into:", + "file": "src/components/settings/recipes/RecipesDashboard.js", + "start": { + "line": 51, + "column": 21 + }, + "end": { + "line": 54, + "column": 3 + } + }, + { + "id": "settings.recipes.customService.openFolder", + "defaultMessage": "!!!Open directory", + "file": "src/components/settings/recipes/RecipesDashboard.js", + "start": { + "line": 55, + "column": 14 + }, + "end": { + "line": 58, + "column": 3 + } + }, + { + "id": "settings.recipes.customService.openDevDocs", + "defaultMessage": "!!!Developer Documentation", + "file": "src/components/settings/recipes/RecipesDashboard.js", + "start": { + "line": 59, + "column": 15 + }, + "end": { + "line": 62, + "column": 3 + } + }, + { + "id": "settings.recipes.customService.headline.customRecipes", + "defaultMessage": "!!!Custom Service Recipes", + "file": "src/components/settings/recipes/RecipesDashboard.js", + "start": { + "line": 63, + "column": 25 + }, + "end": { + "line": 66, + "column": 3 + } + }, + { + "id": "settings.recipes.customService.headline.communityRecipes", + "defaultMessage": "!!!Community Services", + "file": "src/components/settings/recipes/RecipesDashboard.js", + "start": { + "line": 67, + "column": 28 + }, + "end": { + "line": 70, + "column": 3 + } + }, + { + "id": "settings.recipes.customService.headline.devRecipes", + "defaultMessage": "!!!Your Development Service Recipes", + "file": "src/components/settings/recipes/RecipesDashboard.js", + "start": { + "line": 71, + "column": 22 + }, + "end": { + "line": 74, "column": 3 } } diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js index e7832088b..0f54a50af 100644 --- a/src/stores/FeaturesStore.js +++ b/src/stores/FeaturesStore.js @@ -16,6 +16,7 @@ import workspaces from '../features/workspaces'; import shareFranz from '../features/shareFranz'; import announcements from '../features/announcements'; import settingsWS from '../features/settingsWS'; +import communityRecipes from '../features/communityRecipes'; import { DEFAULT_FEATURES_CONFIG } from '../config'; @@ -75,5 +76,6 @@ export default class FeaturesStore extends Store { shareFranz(this.stores, this.actions); announcements(this.stores, this.actions); settingsWS(this.stores, this.actions); + communityRecipes(this.stores, this.actions); } } diff --git a/src/stores/index.js b/src/stores/index.js index 1912418a2..7f89bf1fb 100644 --- a/src/stores/index.js +++ b/src/stores/index.js @@ -12,6 +12,7 @@ import RequestStore from './RequestStore'; import GlobalErrorStore from './GlobalErrorStore'; import { workspaceStore } from '../features/workspaces'; import { announcementsStore } from '../features/announcements'; +import { communityRecipesStore } from '../features/communityRecipes'; export default (api, actions, router) => { const stores = {}; @@ -31,6 +32,7 @@ export default (api, actions, router) => { globalError: new GlobalErrorStore(stores, api, actions), workspaces: workspaceStore, announcements: announcementsStore, + communityRecipes: communityRecipesStore, }); // Initialize all stores Object.keys(stores).forEach((name) => { diff --git a/src/styles/recipes.scss b/src/styles/recipes.scss index 84222e1fe..56a248e98 100644 --- a/src/styles/recipes.scss +++ b/src/styles/recipes.scss @@ -12,7 +12,7 @@ display: flex; flex-flow: row wrap; height: auto; - min-height: 70%; + // min-height: 70%; &.recipes__list--disabled { filter: grayscale(100%); -- cgit v1.2.3-70-g09d2 From 66647005ae23bccf1691a43ea36565cae4ce9518 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Thu, 13 Jun 2019 15:15:38 +0200 Subject: Improve serviceLimit implementation --- src/components/settings/navigation/SettingsNavigation.js | 8 +++++++- src/features/serviceLimit/components/LimitReachedInfobox.js | 4 ++++ src/features/serviceLimit/index.js | 2 +- src/features/serviceLimit/store.js | 6 +++--- src/i18n/locales/en-US.json | 2 +- 5 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src/i18n/locales') 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'; import { workspaceStore } from '../../../features/workspaces'; import UIStore from '../../../stores/UIStore'; import UserStore from '../../../stores/UserStore'; +import { serviceLimitStore } from '../../../features/serviceLimit'; const messages = defineMessages({ availableServices: { @@ -80,7 +81,12 @@ export default @inject('stores') @observer class SettingsNavigation extends Comp > {intl.formatMessage(messages.yourServices)} {' '} - {serviceCount} + + {serviceCount} + {serviceLimitStore.serviceLimit !== 0 && ( + `/${serviceLimitStore.serviceLimit}` + )} + {workspaceStore.isFeatureEnabled ? ( ({ borderRadius: 0, marginBottom: 0, + '& > div': { + marginBottom: 0, + }, + '& button': { color: theme.styleTypes.primary.contrast, }, diff --git a/src/features/serviceLimit/index.js b/src/features/serviceLimit/index.js index 76f996195..92ad8bb98 100644 --- a/src/features/serviceLimit/index.js +++ b/src/features/serviceLimit/index.js @@ -15,7 +15,7 @@ export default function initServiceLimit(stores, actions) { // Toggle serviceLimit feature reaction( () => ( - features.features.hasServiceLimit + features.features.isServiceLimitEnabled ), (isEnabled) => { if (isEnabled) { diff --git a/src/features/serviceLimit/store.js b/src/features/serviceLimit/store.js index 752f71371..9836c5f51 100644 --- a/src/features/serviceLimit/store.js +++ b/src/features/serviceLimit/store.js @@ -24,12 +24,12 @@ export class ServiceLimitStore extends FeatureStore { @computed get userHasReachedServiceLimit() { if (!this.isServiceLimitEnabled) return false; - const { user } = this.stores; - - return !user.isPremium && this.serviceCount >= this.serviceLimit; + return this.serviceLimit !== 0 && this.serviceCount >= this.serviceLimit; } @computed get serviceLimit() { + if (!this.isServiceLimitEnabled || this.stores.features.features.serviceLimitCount === 0) return 0; + return this.stores.features.features.serviceLimitCount || DEFAULT_SERVICE_LIMIT; } diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index a821dbe39..eded7b79b 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -5,7 +5,7 @@ "feature.delayApp.action": "Get a Franz Supporter License", "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", "feature.delayApp.text": "Franz will continue in {seconds} seconds.", - "feature.serviceLimit.limitReached": "You have added {amount} of {limit} services. Please upgrade your account to add more services.", + "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.", "feature.shareFranz.action.email": "Send as email", "feature.shareFranz.action.facebook": "Share on Facebook", "feature.shareFranz.action.twitter": "Share on Twitter", -- cgit v1.2.3-70-g09d2 From 97852499feba82003021c501b97b075e11647f5e Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Thu, 13 Jun 2019 15:16:57 +0200 Subject: Add "service limit reached" screen --- .../services/content/ServiceRestricted.js | 54 +++++++ src/components/services/content/ServiceView.js | 25 ++- src/components/services/content/Services.js | 1 + src/i18n/locales/defaultMessages.json | 174 +++++++++++++-------- src/i18n/locales/en-US.json | 3 + .../services/content/ServiceRestricted.json | 41 +++++ .../settings/navigation/SettingsNavigation.json | 32 ++-- src/models/Service.js | 2 + src/stores/ServicesStore.js | 24 ++- 9 files changed, 268 insertions(+), 88 deletions(-) create mode 100644 src/components/services/content/ServiceRestricted.js create mode 100644 src/i18n/messages/src/components/services/content/ServiceRestricted.json (limited to 'src/i18n/locales') diff --git a/src/components/services/content/ServiceRestricted.js b/src/components/services/content/ServiceRestricted.js new file mode 100644 index 000000000..9fb7d0961 --- /dev/null +++ b/src/components/services/content/ServiceRestricted.js @@ -0,0 +1,54 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { observer } from 'mobx-react'; +import { defineMessages, intlShape } from 'react-intl'; + +import { serviceLimitStore } from '../../../features/serviceLimit'; +import Button from '../../ui/Button'; + +const messages = defineMessages({ + headline: { + id: 'service.restrictedHandler.headline', + defaultMessage: '!!!You have reached your service limit.', + }, + text: { + id: 'service.restrictedHandler.text', + defaultMessage: '!!!Please upgrade your account to use more than {count} services.', + }, + action: { + id: 'service.restrictedHandler.action', + defaultMessage: '!!!Upgrade Account', + }, +}); + +export default @observer class ServiceRestricted extends Component { + static propTypes = { + name: PropTypes.string.isRequired, + upgrade: PropTypes.func.isRequired, + }; + + static contextTypes = { + intl: intlShape, + }; + + countdownInterval = null; + + countdownIntervalTimeout = 1000; + + render() { + const { name, upgrade } = this.props; + const { intl } = this.context; + + return ( +
+

{intl.formatMessage(messages.headline)}

+

{intl.formatMessage(messages.text, { count: serviceLimitStore.serviceLimit })}

+
+ ); + } +} diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js index 13148b9b3..18279fd06 100644 --- a/src/components/services/content/ServiceView.js +++ b/src/components/services/content/ServiceView.js @@ -10,6 +10,7 @@ import WebviewLoader from '../../ui/WebviewLoader'; import WebviewCrashHandler from './WebviewCrashHandler'; import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; import ServiceDisabled from './ServiceDisabled'; +import ServiceRestricted from './ServiceRestricted'; import ServiceWebview from './ServiceWebview'; export default @observer class ServiceView extends Component { @@ -21,6 +22,7 @@ export default @observer class ServiceView extends Component { edit: PropTypes.func.isRequired, enable: PropTypes.func.isRequired, isActive: PropTypes.bool, + upgrade: PropTypes.func.isRequired, }; static defaultProps = { @@ -72,6 +74,7 @@ export default @observer class ServiceView extends Component { reload, edit, enable, + upgrade, } = this.props; const webviewClasses = classnames({ @@ -99,7 +102,7 @@ export default @observer class ServiceView extends Component { reload={reload} /> )} - {service.isEnabled && service.isLoading && service.isFirstLoad && ( + {service.isEnabled && service.isLoading && service.isFirstLoad && !service.isServiceAccessRestricted && ( ) : ( - + <> + {service.isServiceAccessRestricted ? ( + + ) : ( + + )} + )} {statusBar} diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js index 8f8c38a11..48de0ebaa 100644 --- a/src/components/services/content/Services.js +++ b/src/components/services/content/Services.js @@ -89,6 +89,7 @@ export default @observer class Services extends Component { }, redirect: false, })} + upgrade={() => openSettings({ path: 'user' })} /> ))} diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index a5572bd32..533944fd0 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -891,6 +891,50 @@ ], "path": "src/components/services/content/ServiceDisabled.json" }, + { + "descriptors": [ + { + "defaultMessage": "!!!You have reached your service limit.", + "end": { + "column": 3, + "line": 13 + }, + "file": "src/components/services/content/ServiceRestricted.js", + "id": "service.restrictedHandler.headline", + "start": { + "column": 12, + "line": 10 + } + }, + { + "defaultMessage": "!!!Please upgrade your account to use more than {count} services.", + "end": { + "column": 3, + "line": 17 + }, + "file": "src/components/services/content/ServiceRestricted.js", + "id": "service.restrictedHandler.text", + "start": { + "column": 8, + "line": 14 + } + }, + { + "defaultMessage": "!!!Upgrade Account", + "end": { + "column": 3, + "line": 21 + }, + "file": "src/components/services/content/ServiceRestricted.js", + "id": "service.restrictedHandler.action", + "start": { + "column": 10, + "line": 18 + } + } + ], + "path": "src/components/services/content/ServiceRestricted.json" + }, { "descriptors": [ { @@ -1307,104 +1351,104 @@ "defaultMessage": "!!!Available services", "end": { "column": 3, - "line": 16 + "line": 17 }, "file": "src/components/settings/navigation/SettingsNavigation.js", "id": "settings.navigation.availableServices", "start": { "column": 21, - "line": 13 + "line": 14 } }, { "defaultMessage": "!!!Your services", "end": { "column": 3, - "line": 20 + "line": 21 }, "file": "src/components/settings/navigation/SettingsNavigation.js", "id": "settings.navigation.yourServices", "start": { "column": 16, - "line": 17 + "line": 18 } }, { "defaultMessage": "!!!Your workspaces", "end": { "column": 3, - "line": 24 + "line": 25 }, "file": "src/components/settings/navigation/SettingsNavigation.js", "id": "settings.navigation.yourWorkspaces", "start": { "column": 18, - "line": 21 + "line": 22 } }, { "defaultMessage": "!!!Account", "end": { "column": 3, - "line": 28 + "line": 29 }, "file": "src/components/settings/navigation/SettingsNavigation.js", "id": "settings.navigation.account", "start": { "column": 11, - "line": 25 + "line": 26 } }, { "defaultMessage": "!!!Manage Team", "end": { "column": 3, - "line": 32 + "line": 33 }, "file": "src/components/settings/navigation/SettingsNavigation.js", "id": "settings.navigation.team", "start": { "column": 8, - "line": 29 + "line": 30 } }, { "defaultMessage": "!!!Settings", "end": { "column": 3, - "line": 36 + "line": 37 }, "file": "src/components/settings/navigation/SettingsNavigation.js", "id": "settings.navigation.settings", "start": { "column": 12, - "line": 33 + "line": 34 } }, { "defaultMessage": "!!!Invite Friends", "end": { "column": 3, - "line": 40 + "line": 41 }, "file": "src/components/settings/navigation/SettingsNavigation.js", "id": "settings.navigation.inviteFriends", "start": { "column": 17, - "line": 37 + "line": 38 } }, { "defaultMessage": "!!!Logout", "end": { "column": 3, - "line": 44 + "line": 45 }, "file": "src/components/settings/navigation/SettingsNavigation.js", "id": "settings.navigation.logout", "start": { "column": 10, - "line": 41 + "line": 42 } } ], @@ -1525,286 +1569,286 @@ "defaultMessage": "!!!Save service", "end": { "column": 3, - "line": 26 + "line": 27 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.saveButton", "start": { "column": 15, - "line": 23 + "line": 24 } }, { "defaultMessage": "!!!Delete Service", "end": { "column": 3, - "line": 30 + "line": 31 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.deleteButton", "start": { "column": 17, - "line": 27 + "line": 28 } }, { "defaultMessage": "!!!Available services", "end": { "column": 3, - "line": 34 + "line": 35 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.availableServices", "start": { "column": 21, - "line": 31 + "line": 32 } }, { "defaultMessage": "!!!Your services", "end": { "column": 3, - "line": 38 + "line": 39 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.yourServices", "start": { "column": 16, - "line": 35 + "line": 36 } }, { "defaultMessage": "!!!Add {name}", "end": { "column": 3, - "line": 42 + "line": 43 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.addServiceHeadline", "start": { "column": 22, - "line": 39 + "line": 40 } }, { "defaultMessage": "!!!Edit {name}", "end": { "column": 3, - "line": 46 + "line": 47 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.editServiceHeadline", "start": { "column": 23, - "line": 43 + "line": 44 } }, { "defaultMessage": "!!!Hosted", "end": { "column": 3, - "line": 50 + "line": 51 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.tabHosted", "start": { "column": 13, - "line": 47 + "line": 48 } }, { "defaultMessage": "!!!Self hosted ⭐️", "end": { "column": 3, - "line": 54 + "line": 55 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.tabOnPremise", "start": { "column": 16, - "line": 51 + "line": 52 } }, { "defaultMessage": "!!!Use the hosted {name} service.", "end": { "column": 3, - "line": 58 + "line": 59 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.useHostedService", "start": { "column": 20, - "line": 55 + "line": 56 } }, { "defaultMessage": "!!!Could not validate custom {name} server.", "end": { "column": 3, - "line": 62 + "line": 63 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.customUrlValidationError", "start": { "column": 28, - "line": 59 + "line": 60 } }, { "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", "end": { "column": 3, - "line": 66 + "line": 67 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.customUrlPremiumInfo", "start": { "column": 24, - "line": 63 + "line": 64 } }, { "defaultMessage": "!!!Upgrade your account", "end": { "column": 3, - "line": 70 + "line": 71 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.customUrlUpgradeAccount", "start": { "column": 27, - "line": 67 + "line": 68 } }, { "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", "end": { "column": 3, - "line": 74 + "line": 75 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.indirectMessageInfo", "start": { "column": 23, - "line": 71 + "line": 72 } }, { "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", "end": { "column": 3, - "line": 78 + "line": 79 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.isMutedInfo", "start": { "column": 15, - "line": 75 + "line": 76 } }, { "defaultMessage": "!!!Notifications", "end": { "column": 3, - "line": 82 + "line": 83 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.headlineNotifications", "start": { "column": 25, - "line": 79 + "line": 80 } }, { "defaultMessage": "!!!Unread message badges", "end": { "column": 3, - "line": 86 + "line": 87 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.headlineBadges", "start": { "column": 18, - "line": 83 + "line": 84 } }, { "defaultMessage": "!!!General", "end": { "column": 3, - "line": 90 + "line": 91 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.headlineGeneral", "start": { "column": 19, - "line": 87 + "line": 88 } }, { "defaultMessage": "!!!Delete", "end": { "column": 3, - "line": 94 + "line": 95 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.iconDelete", "start": { "column": 14, - "line": 91 + "line": 92 } }, { "defaultMessage": "!!!Drop your image, or click here", "end": { "column": 3, - "line": 98 + "line": 99 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.iconUpload", "start": { "column": 14, - "line": 95 + "line": 96 } }, { "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", "end": { "column": 3, - "line": 102 + "line": 103 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.proxy.headline", "start": { "column": 17, - "line": 99 + "line": 100 } }, { "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", "end": { "column": 3, - "line": 106 + "line": 107 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.proxy.restartInfo", "start": { "column": 20, - "line": 103 + "line": 104 } }, { "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", "end": { "column": 3, - "line": 110 + "line": 111 }, "file": "src/components/settings/services/EditServiceForm.js", "id": "settings.service.form.proxy.info", "start": { "column": 13, - "line": 107 + "line": 108 } } ], @@ -3289,29 +3333,29 @@ { "descriptors": [ { - "defaultMessage": "!!!You have added {amount} of {amount} services. Please upgrade your account to add more services.", + "defaultMessage": "!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.", "end": { "column": 3, - "line": 16 + "line": 14 }, "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", "id": "feature.serviceLimit.limitReached", "start": { "column": 16, - "line": 13 + "line": 11 } }, { "defaultMessage": "!!!Upgrade account", "end": { "column": 3, - "line": 20 + "line": 18 }, "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", "id": "premiumFeature.button.upgradeAccount", "start": { "column": 10, - "line": 17 + "line": 15 } } ], diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index eded7b79b..d83ce37b0 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -119,6 +119,9 @@ "service.errorHandler.headline": "Oh no!", "service.errorHandler.message": "Error", "service.errorHandler.text": "{name} has failed to load.", + "service.restrictedHandler.action": "Upgrade Account", + "service.restrictedHandler.headline": "You have reached your service limit.", + "service.restrictedHandler.text": "Please upgrade your account to use more than {count} services.", "service.webviewLoader.loading": "Loading", "services.getStarted": "Get started", "services.welcome": "Welcome to Franz", 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..30ecd4d75 --- /dev/null +++ b/src/i18n/messages/src/components/services/content/ServiceRestricted.json @@ -0,0 +1,41 @@ +[ + { + "id": "service.restrictedHandler.headline", + "defaultMessage": "!!!You have reached your service limit.", + "file": "src/components/services/content/ServiceRestricted.js", + "start": { + "line": 10, + "column": 12 + }, + "end": { + "line": 13, + "column": 3 + } + }, + { + "id": "service.restrictedHandler.text", + "defaultMessage": "!!!Please upgrade your account to use more than {count} services.", + "file": "src/components/services/content/ServiceRestricted.js", + "start": { + "line": 14, + "column": 8 + }, + "end": { + "line": 17, + "column": 3 + } + }, + { + "id": "service.restrictedHandler.action", + "defaultMessage": "!!!Upgrade Account", + "file": "src/components/services/content/ServiceRestricted.js", + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 21, + "column": 3 + } + } +] \ No newline at end of file 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 @@ "defaultMessage": "!!!Available services", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 13, + "line": 14, "column": 21 }, "end": { - "line": 16, + "line": 17, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!Your services", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 17, + "line": 18, "column": 16 }, "end": { - "line": 20, + "line": 21, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Your workspaces", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 21, + "line": 22, "column": 18 }, "end": { - "line": 24, + "line": 25, "column": 3 } }, @@ -43,11 +43,11 @@ "defaultMessage": "!!!Account", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 25, + "line": 26, "column": 11 }, "end": { - "line": 28, + "line": 29, "column": 3 } }, @@ -56,11 +56,11 @@ "defaultMessage": "!!!Manage Team", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 29, + "line": 30, "column": 8 }, "end": { - "line": 32, + "line": 33, "column": 3 } }, @@ -69,11 +69,11 @@ "defaultMessage": "!!!Settings", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 33, + "line": 34, "column": 12 }, "end": { - "line": 36, + "line": 37, "column": 3 } }, @@ -82,11 +82,11 @@ "defaultMessage": "!!!Invite Friends", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 37, + "line": 38, "column": 17 }, "end": { - "line": 40, + "line": 41, "column": 3 } }, @@ -95,11 +95,11 @@ "defaultMessage": "!!!Logout", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 41, + "line": 42, "column": 10 }, "end": { - "line": 44, + "line": 45, "column": 3 } } diff --git a/src/models/Service.js b/src/models/Service.js index 88bce3360..fa3648a39 100644 --- a/src/models/Service.js +++ b/src/models/Service.js @@ -104,6 +104,8 @@ export default class Service { this.recipe = recipe; + this.isServiceAccessRestricted = false; + autorun(() => { if (!this.isEnabled) { this.webview = null; diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index ee47bf6db..79d1a0ea1 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js @@ -93,13 +93,21 @@ export default class ServicesStore extends Store { () => this.stores.settings.app.spellcheckerLanguage, () => this._shareSettingsWithServiceProcess(), ); + + reaction( + () => this.all, + () => this._restrictServiceAccess(), + ); } @computed get all() { if (this.stores.user.isLoggedIn) { const services = this.allServicesRequest.execute().result; if (services) { - return observable(services.slice().slice().sort((a, b) => a.order - b.order)); + return observable(services.slice().slice().sort((a, b) => a.order - b.order).map((s, index) => { + s.index = index; + return s; + })); } } return []; @@ -681,6 +689,20 @@ export default class ServicesStore extends Store { return serviceData; } + _restrictServiceAccess() { + const services = this.all; + const { userHasReachedServiceLimit, serviceLimit } = this.stores.serviceLimit; + + if (userHasReachedServiceLimit) { + services.map((service, index) => { + console.log('restrictServiceAcceess', index >= serviceLimit); + service.isServiceAccessRestricted = index >= serviceLimit; + + return service; + }); + } + } + // Helper _initializeServiceRecipeInWebview(serviceId) { const service = this.one(serviceId); -- cgit v1.2.3-70-g09d2 From bbfb750bafadae49116b1a420664ea753cd9b50b Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 14 Jun 2019 15:29:04 +0200 Subject: Restrict services with customURL when not premium user --- .../services/content/ServiceRestricted.js | 38 ++++++++++++++---- src/components/services/content/ServiceView.js | 2 +- src/i18n/locales/defaultMessages.json | 46 +++++++++++++++++----- src/i18n/locales/en-US.json | 6 ++- .../services/content/ServiceRestricted.json | 46 +++++++++++++++++----- src/models/Service.js | 17 +++++++- src/stores/ServicesStore.js | 34 ++++++++++------ 7 files changed, 145 insertions(+), 44 deletions(-) (limited to 'src/i18n/locales') diff --git a/src/components/services/content/ServiceRestricted.js b/src/components/services/content/ServiceRestricted.js index 9fb7d0961..4b8d926aa 100644 --- a/src/components/services/content/ServiceRestricted.js +++ b/src/components/services/content/ServiceRestricted.js @@ -5,16 +5,25 @@ import { defineMessages, intlShape } from 'react-intl'; import { serviceLimitStore } from '../../../features/serviceLimit'; import Button from '../../ui/Button'; +import { RESTRICTION_TYPES } from '../../../models/Service'; const messages = defineMessages({ - headline: { - id: 'service.restrictedHandler.headline', + headlineServiceLimit: { + id: 'service.restrictedHandler.serviceLimit.headline', defaultMessage: '!!!You have reached your service limit.', }, - text: { - id: 'service.restrictedHandler.text', + textServiceLimit: { + id: 'service.restrictedHandler.serviceLimit.text', defaultMessage: '!!!Please upgrade your account to use more than {count} services.', }, + headlineCustomUrl: { + id: 'service.restrictedHandler.customUrl.headline', + defaultMessage: '!!!Franz Professional Plan required', + }, + textCustomUrl: { + id: 'service.restrictedHandler.customUrl.text', + defaultMessage: '!!!Please upgrade to the Franz Professional plan to use custom urls & self hosted services.', + }, action: { id: 'service.restrictedHandler.action', defaultMessage: '!!!Upgrade Account', @@ -25,6 +34,7 @@ export default @observer class ServiceRestricted extends Component { static propTypes = { name: PropTypes.string.isRequired, upgrade: PropTypes.func.isRequired, + type: PropTypes.number.isRequired, }; static contextTypes = { @@ -36,13 +46,27 @@ export default @observer class ServiceRestricted extends Component { countdownIntervalTimeout = 1000; render() { - const { name, upgrade } = this.props; + const { + name, + upgrade, + type, + } = this.props; const { intl } = this.context; return (
-

{intl.formatMessage(messages.headline)}

-

{intl.formatMessage(messages.text, { count: serviceLimitStore.serviceLimit })}

+ {type === RESTRICTION_TYPES.SERVICE_LIMIT && ( + <> +

{intl.formatMessage(messages.headlineServiceLimit)}

+

{intl.formatMessage(messages.textServiceLimit, { count: serviceLimitStore.serviceLimit })}

+ + )} + {type === RESTRICTION_TYPES.CUSTOM_URL && ( + <> +

{intl.formatMessage(messages.headlineCustomUrl)}

+

{intl.formatMessage(messages.textCustomUrl)}

+ + )}
+ diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index d290a6094..473280c54 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js @@ -12,6 +12,7 @@ import NewsStore from '../../stores/NewsStore'; import SettingsStore from '../../stores/SettingsStore'; import RequestStore from '../../stores/RequestStore'; import GlobalErrorStore from '../../stores/GlobalErrorStore'; +import UserStore from '../../stores/UserStore'; import { oneOrManyChildElements } from '../../prop-types'; import AppLayout from '../../components/layout/AppLayout'; @@ -39,6 +40,7 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e settings, globalError, requests, + user, } = this.props.stores; const { @@ -131,6 +133,7 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e return ( ({ + root: { + background: theme.colorBackground, + height: '100%', + width: 300, + position: 'absolute', + top: 0, + right: 0, + }, + webview: { + height: '100%', + }, +}); + +@injectSheet(styles) @observer +class TodosWebview extends Component { + static propTypes = { + classes: PropTypes.object.isRequired, + authToken: PropTypes.string.isRequired, + }; + + render() { + const { authToken, classes } = this.props; + return ( +
+ +
+ ); + } +} + +export default TodosWebview; diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index d517b456b..1c7f5a7dd 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -669,39 +669,39 @@ "defaultMessage": "!!!Your services have been updated.", "end": { "column": 3, - "line": 29 + "line": 30 }, "file": "src/components/layout/AppLayout.js", "id": "infobar.servicesUpdated", "start": { "column": 19, - "line": 26 + "line": 27 } }, { "defaultMessage": "!!!Reload services", "end": { "column": 3, - "line": 33 + "line": 34 }, "file": "src/components/layout/AppLayout.js", "id": "infobar.buttonReloadServices", "start": { "column": 24, - "line": 30 + "line": 31 } }, { "defaultMessage": "!!!Could not load services and user information", "end": { "column": 3, - "line": 37 + "line": 38 }, "file": "src/components/layout/AppLayout.js", "id": "infobar.requiredRequestsFailed", "start": { "column": 26, - "line": 34 + "line": 35 } } ], diff --git a/src/i18n/messages/src/components/layout/AppLayout.json b/src/i18n/messages/src/components/layout/AppLayout.json index 190c5dff7..b71889155 100644 --- a/src/i18n/messages/src/components/layout/AppLayout.json +++ b/src/i18n/messages/src/components/layout/AppLayout.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Your services have been updated.", "file": "src/components/layout/AppLayout.js", "start": { - "line": 26, + "line": 27, "column": 19 }, "end": { - "line": 29, + "line": 30, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!Reload services", "file": "src/components/layout/AppLayout.js", "start": { - "line": 30, + "line": 31, "column": 24 }, "end": { - "line": 33, + "line": 34, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Could not load services and user information", "file": "src/components/layout/AppLayout.js", "start": { - "line": 34, + "line": 35, "column": 26 }, "end": { - "line": 37, + "line": 38, "column": 3 } } diff --git a/src/styles/layout.scss b/src/styles/layout.scss index e858b7904..c9cc94e15 100644 --- a/src/styles/layout.scss +++ b/src/styles/layout.scss @@ -33,10 +33,11 @@ html { overflow: hidden; } } .app { - display: flex; - flex-direction: column; + //display: flex; - .app__content { display: flex; } + .app__content { + display: flex; + } .app__service { position: relative; -- cgit v1.2.3-70-g09d2 From 39d56b5672aa0fdda259a8299c4d658d5e8f0da2 Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Wed, 31 Jul 2019 17:09:27 +0200 Subject: add updated i18n messages --- src/i18n/locales/defaultMessages.json | 157 ++++++++++++++++++---------------- src/i18n/locales/en-US.json | 3 +- 2 files changed, 87 insertions(+), 73 deletions(-) (limited to 'src/i18n/locales') diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index 015987b8a..a0654027b 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -4187,471 +4187,484 @@ } }, { - "defaultMessage": "!!!Toggle Service Developer Tools", + "defaultMessage": "!!!Toggle Todos Developer Tools", "end": { "column": 3, "line": 102 }, "file": "src/lib/Menu.js", + "id": "menu.view.toggleTodosDevTools", + "start": { + "column": 23, + "line": 99 + } + }, + { + "defaultMessage": "!!!Toggle Service Developer Tools", + "end": { + "column": 3, + "line": 106 + }, + "file": "src/lib/Menu.js", "id": "menu.view.toggleServiceDevTools", "start": { "column": 25, - "line": 99 + "line": 103 } }, { "defaultMessage": "!!!Reload Service", "end": { "column": 3, - "line": 106 + "line": 110 }, "file": "src/lib/Menu.js", "id": "menu.view.reloadService", "start": { "column": 17, - "line": 103 + "line": 107 } }, { "defaultMessage": "!!!Reload Franz", "end": { "column": 3, - "line": 110 + "line": 114 }, "file": "src/lib/Menu.js", "id": "menu.view.reloadFranz", "start": { "column": 15, - "line": 107 + "line": 111 } }, { "defaultMessage": "!!!Minimize", "end": { "column": 3, - "line": 114 + "line": 118 }, "file": "src/lib/Menu.js", "id": "menu.window.minimize", "start": { "column": 12, - "line": 111 + "line": 115 } }, { "defaultMessage": "!!!Close", "end": { "column": 3, - "line": 118 + "line": 122 }, "file": "src/lib/Menu.js", "id": "menu.window.close", "start": { "column": 9, - "line": 115 + "line": 119 } }, { "defaultMessage": "!!!Learn More", "end": { "column": 3, - "line": 122 + "line": 126 }, "file": "src/lib/Menu.js", "id": "menu.help.learnMore", "start": { "column": 13, - "line": 119 + "line": 123 } }, { "defaultMessage": "!!!Changelog", "end": { "column": 3, - "line": 126 + "line": 130 }, "file": "src/lib/Menu.js", "id": "menu.help.changelog", "start": { "column": 13, - "line": 123 + "line": 127 } }, { "defaultMessage": "!!!Support", "end": { "column": 3, - "line": 130 + "line": 134 }, "file": "src/lib/Menu.js", "id": "menu.help.support", "start": { "column": 11, - "line": 127 + "line": 131 } }, { "defaultMessage": "!!!Copy Debug Information", "end": { "column": 3, - "line": 134 + "line": 138 }, "file": "src/lib/Menu.js", "id": "menu.help.debugInfo", "start": { "column": 13, - "line": 131 + "line": 135 } }, { "defaultMessage": "!!!Franz Debug Information", "end": { "column": 3, - "line": 138 + "line": 142 }, "file": "src/lib/Menu.js", "id": "menu.help.debugInfoCopiedHeadline", "start": { "column": 27, - "line": 135 + "line": 139 } }, { "defaultMessage": "!!!Your Debug Information has been copied to your clipboard.", "end": { "column": 3, - "line": 142 + "line": 146 }, "file": "src/lib/Menu.js", "id": "menu.help.debugInfoCopiedBody", "start": { "column": 23, - "line": 139 + "line": 143 } }, { "defaultMessage": "!!!Terms of Service", "end": { "column": 3, - "line": 146 + "line": 150 }, "file": "src/lib/Menu.js", "id": "menu.help.tos", "start": { "column": 7, - "line": 143 + "line": 147 } }, { "defaultMessage": "!!!Privacy Statement", "end": { "column": 3, - "line": 150 + "line": 154 }, "file": "src/lib/Menu.js", "id": "menu.help.privacy", "start": { "column": 11, - "line": 147 + "line": 151 } }, { "defaultMessage": "!!!File", "end": { "column": 3, - "line": 154 + "line": 158 }, "file": "src/lib/Menu.js", "id": "menu.file", "start": { "column": 8, - "line": 151 + "line": 155 } }, { "defaultMessage": "!!!View", "end": { "column": 3, - "line": 158 + "line": 162 }, "file": "src/lib/Menu.js", "id": "menu.view", "start": { "column": 8, - "line": 155 + "line": 159 } }, { "defaultMessage": "!!!Services", "end": { "column": 3, - "line": 162 + "line": 166 }, "file": "src/lib/Menu.js", "id": "menu.services", "start": { "column": 12, - "line": 159 + "line": 163 } }, { "defaultMessage": "!!!Window", "end": { "column": 3, - "line": 166 + "line": 170 }, "file": "src/lib/Menu.js", "id": "menu.window", "start": { "column": 10, - "line": 163 + "line": 167 } }, { "defaultMessage": "!!!Help", "end": { "column": 3, - "line": 170 + "line": 174 }, "file": "src/lib/Menu.js", "id": "menu.help", "start": { "column": 8, - "line": 167 + "line": 171 } }, { "defaultMessage": "!!!About Franz", "end": { "column": 3, - "line": 174 + "line": 178 }, "file": "src/lib/Menu.js", "id": "menu.app.about", "start": { "column": 9, - "line": 171 + "line": 175 } }, { "defaultMessage": "!!!What's new?", "end": { "column": 3, - "line": 178 + "line": 182 }, "file": "src/lib/Menu.js", "id": "menu.app.announcement", "start": { "column": 16, - "line": 175 + "line": 179 } }, { "defaultMessage": "!!!Settings", "end": { "column": 3, - "line": 182 + "line": 186 }, "file": "src/lib/Menu.js", "id": "menu.app.settings", "start": { "column": 12, - "line": 179 + "line": 183 } }, { "defaultMessage": "!!!Check for updates", "end": { "column": 3, - "line": 186 + "line": 190 }, "file": "src/lib/Menu.js", "id": "menu.app.checkForUpdates", "start": { "column": 19, - "line": 183 + "line": 187 } }, { "defaultMessage": "!!!Hide", "end": { "column": 3, - "line": 190 + "line": 194 }, "file": "src/lib/Menu.js", "id": "menu.app.hide", "start": { "column": 8, - "line": 187 + "line": 191 } }, { "defaultMessage": "!!!Hide Others", "end": { "column": 3, - "line": 194 + "line": 198 }, "file": "src/lib/Menu.js", "id": "menu.app.hideOthers", "start": { "column": 14, - "line": 191 + "line": 195 } }, { "defaultMessage": "!!!Unhide", "end": { "column": 3, - "line": 198 + "line": 202 }, "file": "src/lib/Menu.js", "id": "menu.app.unhide", "start": { "column": 10, - "line": 195 + "line": 199 } }, { "defaultMessage": "!!!Quit", "end": { "column": 3, - "line": 202 + "line": 206 }, "file": "src/lib/Menu.js", "id": "menu.app.quit", "start": { "column": 8, - "line": 199 + "line": 203 } }, { "defaultMessage": "!!!Add New Service...", "end": { "column": 3, - "line": 206 + "line": 210 }, "file": "src/lib/Menu.js", "id": "menu.services.addNewService", "start": { "column": 17, - "line": 203 + "line": 207 } }, { "defaultMessage": "!!!Add New Workspace...", "end": { "column": 3, - "line": 210 + "line": 214 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.addNewWorkspace", "start": { "column": 19, - "line": 207 + "line": 211 } }, { "defaultMessage": "!!!Open workspace drawer", "end": { "column": 3, - "line": 214 + "line": 218 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.openWorkspaceDrawer", "start": { "column": 23, - "line": 211 + "line": 215 } }, { "defaultMessage": "!!!Close workspace drawer", "end": { "column": 3, - "line": 218 + "line": 222 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.closeWorkspaceDrawer", "start": { "column": 24, - "line": 215 + "line": 219 } }, { "defaultMessage": "!!!Activate next service...", "end": { "column": 3, - "line": 222 + "line": 226 }, "file": "src/lib/Menu.js", "id": "menu.services.setNextServiceActive", "start": { "column": 23, - "line": 219 + "line": 223 } }, { "defaultMessage": "!!!Activate previous service...", "end": { "column": 3, - "line": 226 + "line": 230 }, "file": "src/lib/Menu.js", "id": "menu.services.activatePreviousService", "start": { "column": 27, - "line": 223 + "line": 227 } }, { "defaultMessage": "!!!Disable notifications & audio", "end": { "column": 3, - "line": 230 + "line": 234 }, "file": "src/lib/Menu.js", "id": "sidebar.muteApp", "start": { "column": 11, - "line": 227 + "line": 231 } }, { "defaultMessage": "!!!Enable notifications & audio", "end": { "column": 3, - "line": 234 + "line": 238 }, "file": "src/lib/Menu.js", "id": "sidebar.unmuteApp", "start": { "column": 13, - "line": 231 + "line": 235 } }, { "defaultMessage": "!!!Workspaces", "end": { "column": 3, - "line": 238 + "line": 242 }, "file": "src/lib/Menu.js", "id": "menu.workspaces", "start": { "column": 14, - "line": 235 + "line": 239 } }, { "defaultMessage": "!!!Default", "end": { "column": 3, - "line": 242 + "line": 246 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.defaultWorkspace", "start": { "column": 20, - "line": 239 + "line": 243 } } ], diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 27987e5b7..235d638b4 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -88,6 +88,7 @@ "menu.view.toggleDevTools": "Toggle Developer Tools", "menu.view.toggleFullScreen": "Toggle Full Screen", "menu.view.toggleServiceDevTools": "Toggle Service Developer Tools", + "menu.view.toggleTodosDevTools": "!!!Toggle Todos Developer Tools", "menu.view.zoomIn": "Zoom In", "menu.view.zoomOut": "Zoom Out", "menu.window": "Window", @@ -332,4 +333,4 @@ "workspaceDrawer.workspaceFeatureInfo": "

Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

", "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", "workspaces.switchingIndicator.switchingTo": "Switching to" -} +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 6297d46f370092598d2ebb973bb69f2c368d7904 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 2 Aug 2019 11:41:51 +0200 Subject: Add option to toggle the Todos panel --- packages/theme/src/themes/dark/index.ts | 5 + packages/theme/src/themes/default/index.ts | 7 +- src/features/todos/actions.js | 1 + src/features/todos/components/TodosWebview.js | 56 +++++- src/features/todos/containers/TodosScreen.js | 2 + src/features/todos/index.js | 1 + src/features/todos/store.js | 15 +- src/i18n/locales/defaultMessages.json | 271 +++++++++++++++----------- src/i18n/locales/en-US.json | 5 +- src/i18n/messages/src/lib/Menu.json | 271 +++++++++++++++----------- src/lib/Menu.js | 50 ++++- 11 files changed, 446 insertions(+), 238 deletions(-) (limited to 'src/i18n/locales') diff --git a/packages/theme/src/themes/dark/index.ts b/packages/theme/src/themes/dark/index.ts index cb1b33f2d..d29345298 100644 --- a/packages/theme/src/themes/dark/index.ts +++ b/packages/theme/src/themes/dark/index.ts @@ -124,6 +124,11 @@ export const todos = merge({}, defaultStyles.todos, { todosLayer: { borderLeftColor: legacyStyles.darkThemeGrayDarker, }, + toggleButton: { + background: defaultStyles.styleTypes.primary.accent, + textColor: defaultStyles.styleTypes.primary.contrast, + shadowColor: 'rgba(0, 0, 0, 0.2)', + }, dragIndicator: { background: legacyStyles.themeGrayLight, }, diff --git a/packages/theme/src/themes/default/index.ts b/packages/theme/src/themes/default/index.ts index d524b8ea7..ac6e3f7c7 100644 --- a/packages/theme/src/themes/default/index.ts +++ b/packages/theme/src/themes/default/index.ts @@ -211,7 +211,12 @@ export const announcements = { // Todos export const todos = { todosLayer: { - borderLeftColor: legacyStyles.themeGrayDark, + borderLeftColor: legacyStyles.themeGrayLighter, + }, + toggleButton: { + background: styleTypes.primary.accent, + textColor: styleTypes.primary.contrast, + shadowColor: 'rgba(0, 0, 0, 0.2)', }, dragIndicator: { background: legacyStyles.themeGrayLight, diff --git a/src/features/todos/actions.js b/src/features/todos/actions.js index a6090a259..dc63d5fcd 100644 --- a/src/features/todos/actions.js +++ b/src/features/todos/actions.js @@ -5,6 +5,7 @@ export const todoActions = createActionsFromDefinitions({ resize: { width: PropTypes.number.isRequired, }, + toggleTodosPanel: {}, setTodosWebview: { webview: PropTypes.instanceOf(Element).isRequired, }, diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index bc32ae728..819e599ca 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js @@ -3,16 +3,31 @@ import PropTypes from 'prop-types'; import { observer } from 'mobx-react'; import injectSheet from 'react-jss'; import Webview from 'react-electron-web-view'; +import { Icon } from '@meetfranz/ui'; import * as environment from '../../../environment'; +const TOGGLE_SIZE = 45; + const styles = theme => ({ root: { background: theme.colorBackground, position: 'relative', borderLeft: [1, 'solid', theme.todos.todosLayer.borderLeftColor], + zIndex: 300, + + transition: 'all 0.5s', + transform: props => `translateX(${props.isVisible ? 0 : props.width}px)`, + + '&:hover $toggleTodosButton': { + opacity: 1, + }, }, webview: { height: '100%', + + '& webview': { + height: '100%', + }, }, resizeHandler: { position: 'absolute', @@ -29,6 +44,31 @@ const styles = theme => ({ zIndex: 400, background: theme.todos.dragIndicator.background, }, + toggleTodosButton: { + width: TOGGLE_SIZE, + height: TOGGLE_SIZE, + background: theme.todos.toggleButton.background, + position: 'absolute', + bottom: 80, + right: props => (props.width + (props.isVisible ? -TOGGLE_SIZE / 2 : 0)), + borderRadius: TOGGLE_SIZE / 2, + opacity: props => (props.isVisible ? 0 : 1), + transition: 'all 0.5s', + zIndex: 600, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + boxShadow: [0, 0, 10, theme.todos.toggleButton.shadowColor], + // border: [1, 'solid', theme.todos.toggleButton.borderColor], + + borderTopRightRadius: props => (props.isVisible ? null : 0), + borderBottomRightRadius: props => (props.isVisible ? null : 0), + + '& svg': { + fill: theme.todos.toggleButton.textColor, + transition: 'all 0.5s', + }, + }, }); @injectSheet(styles) @observer @@ -36,6 +76,8 @@ class TodosWebview extends Component { static propTypes = { classes: PropTypes.object.isRequired, authToken: PropTypes.string.isRequired, + isVisible: PropTypes.bool.isRequired, + togglePanel: PropTypes.func.isRequired, handleClientMessage: PropTypes.func.isRequired, setTodosWebview: PropTypes.func.isRequired, resize: PropTypes.func.isRequired, @@ -123,16 +165,26 @@ class TodosWebview extends Component { } render() { - const { authToken, classes } = this.props; + const { + authToken, classes, isVisible, togglePanel, + } = this.props; const { width, delta, isDragging } = this.state; + return ( <>
this.stopResize()} ref={(node) => { this.node = node; }} > +
todoActions.setTodosWebview({ webview })} width={todosStore.width} diff --git a/src/features/todos/index.js b/src/features/todos/index.js index f741561d6..00b165cc5 100644 --- a/src/features/todos/index.js +++ b/src/features/todos/index.js @@ -7,6 +7,7 @@ export const GA_CATEGORY_TODOS = 'Todos'; export const DEFAULT_TODOS_WIDTH = 300; export const TODOS_MIN_WIDTH = 200; +export const DEFAULT_TODOS_VISIBLE = true; export const todosStore = new TodoStore(); diff --git a/src/features/todos/store.js b/src/features/todos/store.js index cd9c8e5f6..79c218b65 100644 --- a/src/features/todos/store.js +++ b/src/features/todos/store.js @@ -9,7 +9,7 @@ import { todoActions } from './actions'; import { FeatureStore } from '../utils/FeatureStore'; import { createReactions } from '../../stores/lib/Reaction'; import { createActionBindings } from '../utils/ActionBinding'; -import { DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH } from '.'; +import { DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH, DEFAULT_TODOS_VISIBLE } from '.'; const debug = require('debug')('Franz:feature:todos:store'); @@ -26,6 +26,12 @@ export default class TodoStore extends FeatureStore { return width < TODOS_MIN_WIDTH ? TODOS_MIN_WIDTH : width; } + @computed get isTodosPanelVisible() { + if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; + + return this.settings.isTodosPanelVisible; + } + @computed get settings() { return localStorage.getItem('todos') || {}; } @@ -41,6 +47,7 @@ export default class TodoStore extends FeatureStore { this._registerActions(createActionBindings([ [todoActions.resize, this._resize], + [todoActions.toggleTodosPanel, this._toggleTodosPanel], [todoActions.setTodosWebview, this._setTodosWebview], [todoActions.handleHostMessage, this._handleHostMessage], [todoActions.handleClientMessage, this._handleClientMessage], @@ -81,6 +88,12 @@ export default class TodoStore extends FeatureStore { }); }; + @action _toggleTodosPanel = () => { + this._updateSettings({ + isTodosPanelVisible: !this.isTodosPanelVisible, + }); + }; + @action _setTodosWebview = ({ webview }) => { debug('_setTodosWebview', webview); this.webview = webview; diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index a0654027b..5959fb059 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -3917,754 +3917,793 @@ "defaultMessage": "!!!Edit", "end": { "column": 3, - "line": 18 + "line": 21 }, "file": "src/lib/Menu.js", "id": "menu.edit", "start": { "column": 8, - "line": 15 + "line": 18 } }, { "defaultMessage": "!!!Undo", "end": { "column": 3, - "line": 22 + "line": 25 }, "file": "src/lib/Menu.js", "id": "menu.edit.undo", "start": { "column": 8, - "line": 19 + "line": 22 } }, { "defaultMessage": "!!!Redo", "end": { "column": 3, - "line": 26 + "line": 29 }, "file": "src/lib/Menu.js", "id": "menu.edit.redo", "start": { "column": 8, - "line": 23 + "line": 26 } }, { "defaultMessage": "!!!Cut", "end": { "column": 3, - "line": 30 + "line": 33 }, "file": "src/lib/Menu.js", "id": "menu.edit.cut", "start": { "column": 7, - "line": 27 + "line": 30 } }, { "defaultMessage": "!!!Copy", "end": { "column": 3, - "line": 34 + "line": 37 }, "file": "src/lib/Menu.js", "id": "menu.edit.copy", "start": { "column": 8, - "line": 31 + "line": 34 } }, { "defaultMessage": "!!!Paste", "end": { "column": 3, - "line": 38 + "line": 41 }, "file": "src/lib/Menu.js", "id": "menu.edit.paste", "start": { "column": 9, - "line": 35 + "line": 38 } }, { "defaultMessage": "!!!Paste And Match Style", "end": { "column": 3, - "line": 42 + "line": 45 }, "file": "src/lib/Menu.js", "id": "menu.edit.pasteAndMatchStyle", "start": { "column": 22, - "line": 39 + "line": 42 } }, { "defaultMessage": "!!!Delete", "end": { "column": 3, - "line": 46 + "line": 49 }, "file": "src/lib/Menu.js", "id": "menu.edit.delete", "start": { "column": 10, - "line": 43 + "line": 46 } }, { "defaultMessage": "!!!Select All", "end": { "column": 3, - "line": 50 + "line": 53 }, "file": "src/lib/Menu.js", "id": "menu.edit.selectAll", "start": { "column": 13, - "line": 47 + "line": 50 } }, { "defaultMessage": "!!!Speech", "end": { "column": 3, - "line": 54 + "line": 57 }, "file": "src/lib/Menu.js", "id": "menu.edit.speech", "start": { "column": 10, - "line": 51 + "line": 54 } }, { "defaultMessage": "!!!Start Speaking", "end": { "column": 3, - "line": 58 + "line": 61 }, "file": "src/lib/Menu.js", "id": "menu.edit.startSpeaking", "start": { "column": 17, - "line": 55 + "line": 58 } }, { "defaultMessage": "!!!Stop Speaking", "end": { "column": 3, - "line": 62 + "line": 65 }, "file": "src/lib/Menu.js", "id": "menu.edit.stopSpeaking", "start": { "column": 16, - "line": 59 + "line": 62 } }, { "defaultMessage": "!!!Start Dictation", "end": { "column": 3, - "line": 66 + "line": 69 }, "file": "src/lib/Menu.js", "id": "menu.edit.startDictation", "start": { "column": 18, - "line": 63 + "line": 66 } }, { "defaultMessage": "!!!Emoji & Symbols", "end": { "column": 3, - "line": 70 + "line": 73 }, "file": "src/lib/Menu.js", "id": "menu.edit.emojiSymbols", "start": { "column": 16, - "line": 67 + "line": 70 } }, { "defaultMessage": "!!!Actual Size", "end": { "column": 3, - "line": 74 + "line": 77 }, "file": "src/lib/Menu.js", "id": "menu.view.resetZoom", "start": { "column": 13, - "line": 71 + "line": 74 } }, { "defaultMessage": "!!!Zoom In", "end": { "column": 3, - "line": 78 + "line": 81 }, "file": "src/lib/Menu.js", "id": "menu.view.zoomIn", "start": { "column": 10, - "line": 75 + "line": 78 } }, { "defaultMessage": "!!!Zoom Out", "end": { "column": 3, - "line": 82 + "line": 85 }, "file": "src/lib/Menu.js", "id": "menu.view.zoomOut", "start": { "column": 11, - "line": 79 + "line": 82 } }, { "defaultMessage": "!!!Enter Full Screen", "end": { "column": 3, - "line": 86 + "line": 89 }, "file": "src/lib/Menu.js", "id": "menu.view.enterFullScreen", "start": { "column": 19, - "line": 83 + "line": 86 } }, { "defaultMessage": "!!!Exit Full Screen", "end": { "column": 3, - "line": 90 + "line": 93 }, "file": "src/lib/Menu.js", "id": "menu.view.exitFullScreen", "start": { "column": 18, - "line": 87 + "line": 90 } }, { "defaultMessage": "!!!Toggle Full Screen", "end": { "column": 3, - "line": 94 + "line": 97 }, "file": "src/lib/Menu.js", "id": "menu.view.toggleFullScreen", "start": { "column": 20, - "line": 91 + "line": 94 } }, { "defaultMessage": "!!!Toggle Developer Tools", "end": { "column": 3, - "line": 98 + "line": 101 }, "file": "src/lib/Menu.js", "id": "menu.view.toggleDevTools", "start": { "column": 18, - "line": 95 + "line": 98 } }, { "defaultMessage": "!!!Toggle Todos Developer Tools", "end": { "column": 3, - "line": 102 + "line": 105 }, "file": "src/lib/Menu.js", "id": "menu.view.toggleTodosDevTools", "start": { "column": 23, - "line": 99 + "line": 102 } }, { "defaultMessage": "!!!Toggle Service Developer Tools", "end": { "column": 3, - "line": 106 + "line": 109 }, "file": "src/lib/Menu.js", "id": "menu.view.toggleServiceDevTools", "start": { "column": 25, - "line": 103 + "line": 106 } }, { "defaultMessage": "!!!Reload Service", "end": { "column": 3, - "line": 110 + "line": 113 }, "file": "src/lib/Menu.js", "id": "menu.view.reloadService", "start": { "column": 17, - "line": 107 + "line": 110 } }, { "defaultMessage": "!!!Reload Franz", "end": { "column": 3, - "line": 114 + "line": 117 }, "file": "src/lib/Menu.js", "id": "menu.view.reloadFranz", "start": { "column": 15, - "line": 111 + "line": 114 } }, { "defaultMessage": "!!!Minimize", "end": { "column": 3, - "line": 118 + "line": 121 }, "file": "src/lib/Menu.js", "id": "menu.window.minimize", "start": { "column": 12, - "line": 115 + "line": 118 } }, { "defaultMessage": "!!!Close", "end": { "column": 3, - "line": 122 + "line": 125 }, "file": "src/lib/Menu.js", "id": "menu.window.close", "start": { "column": 9, - "line": 119 + "line": 122 } }, { "defaultMessage": "!!!Learn More", "end": { "column": 3, - "line": 126 + "line": 129 }, "file": "src/lib/Menu.js", "id": "menu.help.learnMore", "start": { "column": 13, - "line": 123 + "line": 126 } }, { "defaultMessage": "!!!Changelog", "end": { "column": 3, - "line": 130 + "line": 133 }, "file": "src/lib/Menu.js", "id": "menu.help.changelog", "start": { "column": 13, - "line": 127 + "line": 130 } }, { "defaultMessage": "!!!Support", "end": { "column": 3, - "line": 134 + "line": 137 }, "file": "src/lib/Menu.js", "id": "menu.help.support", "start": { "column": 11, - "line": 131 + "line": 134 } }, { "defaultMessage": "!!!Copy Debug Information", "end": { "column": 3, - "line": 138 + "line": 141 }, "file": "src/lib/Menu.js", "id": "menu.help.debugInfo", "start": { "column": 13, - "line": 135 + "line": 138 } }, { "defaultMessage": "!!!Franz Debug Information", "end": { "column": 3, - "line": 142 + "line": 145 }, "file": "src/lib/Menu.js", "id": "menu.help.debugInfoCopiedHeadline", "start": { "column": 27, - "line": 139 + "line": 142 } }, { "defaultMessage": "!!!Your Debug Information has been copied to your clipboard.", "end": { "column": 3, - "line": 146 + "line": 149 }, "file": "src/lib/Menu.js", "id": "menu.help.debugInfoCopiedBody", "start": { "column": 23, - "line": 143 + "line": 146 } }, { "defaultMessage": "!!!Terms of Service", "end": { "column": 3, - "line": 150 + "line": 153 }, "file": "src/lib/Menu.js", "id": "menu.help.tos", "start": { "column": 7, - "line": 147 + "line": 150 } }, { "defaultMessage": "!!!Privacy Statement", "end": { "column": 3, - "line": 154 + "line": 157 }, "file": "src/lib/Menu.js", "id": "menu.help.privacy", "start": { "column": 11, - "line": 151 + "line": 154 } }, { "defaultMessage": "!!!File", "end": { "column": 3, - "line": 158 + "line": 161 }, "file": "src/lib/Menu.js", "id": "menu.file", "start": { "column": 8, - "line": 155 + "line": 158 } }, { "defaultMessage": "!!!View", "end": { "column": 3, - "line": 162 + "line": 165 }, "file": "src/lib/Menu.js", "id": "menu.view", "start": { "column": 8, - "line": 159 + "line": 162 } }, { "defaultMessage": "!!!Services", "end": { "column": 3, - "line": 166 + "line": 169 }, "file": "src/lib/Menu.js", "id": "menu.services", "start": { "column": 12, - "line": 163 + "line": 166 } }, { "defaultMessage": "!!!Window", "end": { "column": 3, - "line": 170 + "line": 173 }, "file": "src/lib/Menu.js", "id": "menu.window", "start": { "column": 10, - "line": 167 + "line": 170 } }, { "defaultMessage": "!!!Help", "end": { "column": 3, - "line": 174 + "line": 177 }, "file": "src/lib/Menu.js", "id": "menu.help", "start": { "column": 8, - "line": 171 + "line": 174 } }, { "defaultMessage": "!!!About Franz", "end": { "column": 3, - "line": 178 + "line": 181 }, "file": "src/lib/Menu.js", "id": "menu.app.about", "start": { "column": 9, - "line": 175 + "line": 178 } }, { "defaultMessage": "!!!What's new?", "end": { "column": 3, - "line": 182 + "line": 185 }, "file": "src/lib/Menu.js", "id": "menu.app.announcement", "start": { "column": 16, - "line": 179 + "line": 182 } }, { "defaultMessage": "!!!Settings", "end": { "column": 3, - "line": 186 + "line": 189 }, "file": "src/lib/Menu.js", "id": "menu.app.settings", "start": { "column": 12, - "line": 183 + "line": 186 } }, { "defaultMessage": "!!!Check for updates", "end": { "column": 3, - "line": 190 + "line": 193 }, "file": "src/lib/Menu.js", "id": "menu.app.checkForUpdates", "start": { "column": 19, - "line": 187 + "line": 190 } }, { "defaultMessage": "!!!Hide", "end": { "column": 3, - "line": 194 + "line": 197 }, "file": "src/lib/Menu.js", "id": "menu.app.hide", "start": { "column": 8, - "line": 191 + "line": 194 } }, { "defaultMessage": "!!!Hide Others", "end": { "column": 3, - "line": 198 + "line": 201 }, "file": "src/lib/Menu.js", "id": "menu.app.hideOthers", "start": { "column": 14, - "line": 195 + "line": 198 } }, { "defaultMessage": "!!!Unhide", "end": { "column": 3, - "line": 202 + "line": 205 }, "file": "src/lib/Menu.js", "id": "menu.app.unhide", "start": { "column": 10, - "line": 199 + "line": 202 } }, { "defaultMessage": "!!!Quit", "end": { "column": 3, - "line": 206 + "line": 209 }, "file": "src/lib/Menu.js", "id": "menu.app.quit", "start": { "column": 8, - "line": 203 + "line": 206 } }, { "defaultMessage": "!!!Add New Service...", "end": { "column": 3, - "line": 210 + "line": 213 }, "file": "src/lib/Menu.js", "id": "menu.services.addNewService", "start": { "column": 17, - "line": 207 + "line": 210 } }, { "defaultMessage": "!!!Add New Workspace...", "end": { "column": 3, - "line": 214 + "line": 217 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.addNewWorkspace", "start": { "column": 19, - "line": 211 + "line": 214 } }, { "defaultMessage": "!!!Open workspace drawer", "end": { "column": 3, - "line": 218 + "line": 221 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.openWorkspaceDrawer", "start": { "column": 23, - "line": 215 + "line": 218 } }, { "defaultMessage": "!!!Close workspace drawer", "end": { "column": 3, - "line": 222 + "line": 225 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.closeWorkspaceDrawer", "start": { "column": 24, - "line": 219 + "line": 222 } }, { "defaultMessage": "!!!Activate next service...", "end": { "column": 3, - "line": 226 + "line": 229 }, "file": "src/lib/Menu.js", "id": "menu.services.setNextServiceActive", "start": { "column": 23, - "line": 223 + "line": 226 } }, { "defaultMessage": "!!!Activate previous service...", "end": { "column": 3, - "line": 230 + "line": 233 }, "file": "src/lib/Menu.js", "id": "menu.services.activatePreviousService", "start": { "column": 27, - "line": 227 + "line": 230 } }, { "defaultMessage": "!!!Disable notifications & audio", "end": { "column": 3, - "line": 234 + "line": 237 }, "file": "src/lib/Menu.js", "id": "sidebar.muteApp", "start": { "column": 11, - "line": 231 + "line": 234 } }, { "defaultMessage": "!!!Enable notifications & audio", "end": { "column": 3, - "line": 238 + "line": 241 }, "file": "src/lib/Menu.js", "id": "sidebar.unmuteApp", "start": { "column": 13, - "line": 235 + "line": 238 } }, { "defaultMessage": "!!!Workspaces", "end": { "column": 3, - "line": 242 + "line": 245 }, "file": "src/lib/Menu.js", "id": "menu.workspaces", "start": { "column": 14, - "line": 239 + "line": 242 } }, { "defaultMessage": "!!!Default", "end": { "column": 3, - "line": 246 + "line": 249 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.defaultWorkspace", "start": { "column": 20, - "line": 243 + "line": 246 + } + }, + { + "defaultMessage": "!!!Todos", + "end": { + "column": 3, + "line": 253 + }, + "file": "src/lib/Menu.js", + "id": "menu.todos", + "start": { + "column": 9, + "line": 250 + } + }, + { + "defaultMessage": "!!!Open Todos drawer", + "end": { + "column": 3, + "line": 257 + }, + "file": "src/lib/Menu.js", + "id": "menu.Todoss.openTodosDrawer", + "start": { + "column": 19, + "line": 254 + } + }, + { + "defaultMessage": "!!!Close Todos drawer", + "end": { + "column": 3, + "line": 261 + }, + "file": "src/lib/Menu.js", + "id": "menu.Todoss.closeTodosDrawer", + "start": { + "column": 20, + "line": 258 } } ], diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 235d638b4..3cec9960e 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -43,6 +43,8 @@ "login.serverLogout": "Your session expired, please login again.", "login.submit.label": "Sign in", "login.tokenExpired": "Your session expired, please login again.", + "menu.Todoss.closeTodosDrawer": "Close Todos drawer", + "menu.Todoss.openTodosDrawer": "Open Todos drawer", "menu.app.about": "About Franz", "menu.app.announcement": "What's new?", "menu.app.checkForUpdates": "Check for updates", @@ -79,6 +81,7 @@ "menu.services.activatePreviousService": "Activate previous service", "menu.services.addNewService": "Add New Service...", "menu.services.setNextServiceActive": "Activate next service", + "menu.todos": "Todos", "menu.view": "View", "menu.view.enterFullScreen": "Enter Full Screen", "menu.view.exitFullScreen": "Exit Full Screen", @@ -333,4 +336,4 @@ "workspaceDrawer.workspaceFeatureInfo": "

Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

", "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", "workspaces.switchingIndicator.switchingTo": "Switching to" -} \ 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 fa9509cbf..cee46608c 100644 --- a/src/i18n/messages/src/lib/Menu.json +++ b/src/i18n/messages/src/lib/Menu.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Edit", "file": "src/lib/Menu.js", "start": { - "line": 15, + "line": 18, "column": 8 }, "end": { - "line": 18, + "line": 21, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!Undo", "file": "src/lib/Menu.js", "start": { - "line": 19, + "line": 22, "column": 8 }, "end": { - "line": 22, + "line": 25, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Redo", "file": "src/lib/Menu.js", "start": { - "line": 23, + "line": 26, "column": 8 }, "end": { - "line": 26, + "line": 29, "column": 3 } }, @@ -43,11 +43,11 @@ "defaultMessage": "!!!Cut", "file": "src/lib/Menu.js", "start": { - "line": 27, + "line": 30, "column": 7 }, "end": { - "line": 30, + "line": 33, "column": 3 } }, @@ -56,11 +56,11 @@ "defaultMessage": "!!!Copy", "file": "src/lib/Menu.js", "start": { - "line": 31, + "line": 34, "column": 8 }, "end": { - "line": 34, + "line": 37, "column": 3 } }, @@ -69,11 +69,11 @@ "defaultMessage": "!!!Paste", "file": "src/lib/Menu.js", "start": { - "line": 35, + "line": 38, "column": 9 }, "end": { - "line": 38, + "line": 41, "column": 3 } }, @@ -82,11 +82,11 @@ "defaultMessage": "!!!Paste And Match Style", "file": "src/lib/Menu.js", "start": { - "line": 39, + "line": 42, "column": 22 }, "end": { - "line": 42, + "line": 45, "column": 3 } }, @@ -95,11 +95,11 @@ "defaultMessage": "!!!Delete", "file": "src/lib/Menu.js", "start": { - "line": 43, + "line": 46, "column": 10 }, "end": { - "line": 46, + "line": 49, "column": 3 } }, @@ -108,11 +108,11 @@ "defaultMessage": "!!!Select All", "file": "src/lib/Menu.js", "start": { - "line": 47, + "line": 50, "column": 13 }, "end": { - "line": 50, + "line": 53, "column": 3 } }, @@ -121,11 +121,11 @@ "defaultMessage": "!!!Speech", "file": "src/lib/Menu.js", "start": { - "line": 51, + "line": 54, "column": 10 }, "end": { - "line": 54, + "line": 57, "column": 3 } }, @@ -134,11 +134,11 @@ "defaultMessage": "!!!Start Speaking", "file": "src/lib/Menu.js", "start": { - "line": 55, + "line": 58, "column": 17 }, "end": { - "line": 58, + "line": 61, "column": 3 } }, @@ -147,11 +147,11 @@ "defaultMessage": "!!!Stop Speaking", "file": "src/lib/Menu.js", "start": { - "line": 59, + "line": 62, "column": 16 }, "end": { - "line": 62, + "line": 65, "column": 3 } }, @@ -160,11 +160,11 @@ "defaultMessage": "!!!Start Dictation", "file": "src/lib/Menu.js", "start": { - "line": 63, + "line": 66, "column": 18 }, "end": { - "line": 66, + "line": 69, "column": 3 } }, @@ -173,11 +173,11 @@ "defaultMessage": "!!!Emoji & Symbols", "file": "src/lib/Menu.js", "start": { - "line": 67, + "line": 70, "column": 16 }, "end": { - "line": 70, + "line": 73, "column": 3 } }, @@ -186,11 +186,11 @@ "defaultMessage": "!!!Actual Size", "file": "src/lib/Menu.js", "start": { - "line": 71, + "line": 74, "column": 13 }, "end": { - "line": 74, + "line": 77, "column": 3 } }, @@ -199,11 +199,11 @@ "defaultMessage": "!!!Zoom In", "file": "src/lib/Menu.js", "start": { - "line": 75, + "line": 78, "column": 10 }, "end": { - "line": 78, + "line": 81, "column": 3 } }, @@ -212,11 +212,11 @@ "defaultMessage": "!!!Zoom Out", "file": "src/lib/Menu.js", "start": { - "line": 79, + "line": 82, "column": 11 }, "end": { - "line": 82, + "line": 85, "column": 3 } }, @@ -225,11 +225,11 @@ "defaultMessage": "!!!Enter Full Screen", "file": "src/lib/Menu.js", "start": { - "line": 83, + "line": 86, "column": 19 }, "end": { - "line": 86, + "line": 89, "column": 3 } }, @@ -238,11 +238,11 @@ "defaultMessage": "!!!Exit Full Screen", "file": "src/lib/Menu.js", "start": { - "line": 87, + "line": 90, "column": 18 }, "end": { - "line": 90, + "line": 93, "column": 3 } }, @@ -251,11 +251,11 @@ "defaultMessage": "!!!Toggle Full Screen", "file": "src/lib/Menu.js", "start": { - "line": 91, + "line": 94, "column": 20 }, "end": { - "line": 94, + "line": 97, "column": 3 } }, @@ -264,11 +264,11 @@ "defaultMessage": "!!!Toggle Developer Tools", "file": "src/lib/Menu.js", "start": { - "line": 95, + "line": 98, "column": 18 }, "end": { - "line": 98, + "line": 101, "column": 3 } }, @@ -277,11 +277,11 @@ "defaultMessage": "!!!Toggle Todos Developer Tools", "file": "src/lib/Menu.js", "start": { - "line": 99, + "line": 102, "column": 23 }, "end": { - "line": 102, + "line": 105, "column": 3 } }, @@ -290,11 +290,11 @@ "defaultMessage": "!!!Toggle Service Developer Tools", "file": "src/lib/Menu.js", "start": { - "line": 103, + "line": 106, "column": 25 }, "end": { - "line": 106, + "line": 109, "column": 3 } }, @@ -303,11 +303,11 @@ "defaultMessage": "!!!Reload Service", "file": "src/lib/Menu.js", "start": { - "line": 107, + "line": 110, "column": 17 }, "end": { - "line": 110, + "line": 113, "column": 3 } }, @@ -316,11 +316,11 @@ "defaultMessage": "!!!Reload Franz", "file": "src/lib/Menu.js", "start": { - "line": 111, + "line": 114, "column": 15 }, "end": { - "line": 114, + "line": 117, "column": 3 } }, @@ -329,11 +329,11 @@ "defaultMessage": "!!!Minimize", "file": "src/lib/Menu.js", "start": { - "line": 115, + "line": 118, "column": 12 }, "end": { - "line": 118, + "line": 121, "column": 3 } }, @@ -342,11 +342,11 @@ "defaultMessage": "!!!Close", "file": "src/lib/Menu.js", "start": { - "line": 119, + "line": 122, "column": 9 }, "end": { - "line": 122, + "line": 125, "column": 3 } }, @@ -355,11 +355,11 @@ "defaultMessage": "!!!Learn More", "file": "src/lib/Menu.js", "start": { - "line": 123, + "line": 126, "column": 13 }, "end": { - "line": 126, + "line": 129, "column": 3 } }, @@ -368,11 +368,11 @@ "defaultMessage": "!!!Changelog", "file": "src/lib/Menu.js", "start": { - "line": 127, + "line": 130, "column": 13 }, "end": { - "line": 130, + "line": 133, "column": 3 } }, @@ -381,11 +381,11 @@ "defaultMessage": "!!!Support", "file": "src/lib/Menu.js", "start": { - "line": 131, + "line": 134, "column": 11 }, "end": { - "line": 134, + "line": 137, "column": 3 } }, @@ -394,11 +394,11 @@ "defaultMessage": "!!!Copy Debug Information", "file": "src/lib/Menu.js", "start": { - "line": 135, + "line": 138, "column": 13 }, "end": { - "line": 138, + "line": 141, "column": 3 } }, @@ -407,11 +407,11 @@ "defaultMessage": "!!!Franz Debug Information", "file": "src/lib/Menu.js", "start": { - "line": 139, + "line": 142, "column": 27 }, "end": { - "line": 142, + "line": 145, "column": 3 } }, @@ -420,11 +420,11 @@ "defaultMessage": "!!!Your Debug Information has been copied to your clipboard.", "file": "src/lib/Menu.js", "start": { - "line": 143, + "line": 146, "column": 23 }, "end": { - "line": 146, + "line": 149, "column": 3 } }, @@ -433,11 +433,11 @@ "defaultMessage": "!!!Terms of Service", "file": "src/lib/Menu.js", "start": { - "line": 147, + "line": 150, "column": 7 }, "end": { - "line": 150, + "line": 153, "column": 3 } }, @@ -446,11 +446,11 @@ "defaultMessage": "!!!Privacy Statement", "file": "src/lib/Menu.js", "start": { - "line": 151, + "line": 154, "column": 11 }, "end": { - "line": 154, + "line": 157, "column": 3 } }, @@ -459,11 +459,11 @@ "defaultMessage": "!!!File", "file": "src/lib/Menu.js", "start": { - "line": 155, + "line": 158, "column": 8 }, "end": { - "line": 158, + "line": 161, "column": 3 } }, @@ -472,11 +472,11 @@ "defaultMessage": "!!!View", "file": "src/lib/Menu.js", "start": { - "line": 159, + "line": 162, "column": 8 }, "end": { - "line": 162, + "line": 165, "column": 3 } }, @@ -485,11 +485,11 @@ "defaultMessage": "!!!Services", "file": "src/lib/Menu.js", "start": { - "line": 163, + "line": 166, "column": 12 }, "end": { - "line": 166, + "line": 169, "column": 3 } }, @@ -498,11 +498,11 @@ "defaultMessage": "!!!Window", "file": "src/lib/Menu.js", "start": { - "line": 167, + "line": 170, "column": 10 }, "end": { - "line": 170, + "line": 173, "column": 3 } }, @@ -511,11 +511,11 @@ "defaultMessage": "!!!Help", "file": "src/lib/Menu.js", "start": { - "line": 171, + "line": 174, "column": 8 }, "end": { - "line": 174, + "line": 177, "column": 3 } }, @@ -524,11 +524,11 @@ "defaultMessage": "!!!About Franz", "file": "src/lib/Menu.js", "start": { - "line": 175, + "line": 178, "column": 9 }, "end": { - "line": 178, + "line": 181, "column": 3 } }, @@ -537,11 +537,11 @@ "defaultMessage": "!!!What's new?", "file": "src/lib/Menu.js", "start": { - "line": 179, + "line": 182, "column": 16 }, "end": { - "line": 182, + "line": 185, "column": 3 } }, @@ -550,11 +550,11 @@ "defaultMessage": "!!!Settings", "file": "src/lib/Menu.js", "start": { - "line": 183, + "line": 186, "column": 12 }, "end": { - "line": 186, + "line": 189, "column": 3 } }, @@ -563,11 +563,11 @@ "defaultMessage": "!!!Check for updates", "file": "src/lib/Menu.js", "start": { - "line": 187, + "line": 190, "column": 19 }, "end": { - "line": 190, + "line": 193, "column": 3 } }, @@ -576,11 +576,11 @@ "defaultMessage": "!!!Hide", "file": "src/lib/Menu.js", "start": { - "line": 191, + "line": 194, "column": 8 }, "end": { - "line": 194, + "line": 197, "column": 3 } }, @@ -589,11 +589,11 @@ "defaultMessage": "!!!Hide Others", "file": "src/lib/Menu.js", "start": { - "line": 195, + "line": 198, "column": 14 }, "end": { - "line": 198, + "line": 201, "column": 3 } }, @@ -602,11 +602,11 @@ "defaultMessage": "!!!Unhide", "file": "src/lib/Menu.js", "start": { - "line": 199, + "line": 202, "column": 10 }, "end": { - "line": 202, + "line": 205, "column": 3 } }, @@ -615,11 +615,11 @@ "defaultMessage": "!!!Quit", "file": "src/lib/Menu.js", "start": { - "line": 203, + "line": 206, "column": 8 }, "end": { - "line": 206, + "line": 209, "column": 3 } }, @@ -628,11 +628,11 @@ "defaultMessage": "!!!Add New Service...", "file": "src/lib/Menu.js", "start": { - "line": 207, + "line": 210, "column": 17 }, "end": { - "line": 210, + "line": 213, "column": 3 } }, @@ -641,11 +641,11 @@ "defaultMessage": "!!!Add New Workspace...", "file": "src/lib/Menu.js", "start": { - "line": 211, + "line": 214, "column": 19 }, "end": { - "line": 214, + "line": 217, "column": 3 } }, @@ -654,11 +654,11 @@ "defaultMessage": "!!!Open workspace drawer", "file": "src/lib/Menu.js", "start": { - "line": 215, + "line": 218, "column": 23 }, "end": { - "line": 218, + "line": 221, "column": 3 } }, @@ -667,11 +667,11 @@ "defaultMessage": "!!!Close workspace drawer", "file": "src/lib/Menu.js", "start": { - "line": 219, + "line": 222, "column": 24 }, "end": { - "line": 222, + "line": 225, "column": 3 } }, @@ -680,11 +680,11 @@ "defaultMessage": "!!!Activate next service...", "file": "src/lib/Menu.js", "start": { - "line": 223, + "line": 226, "column": 23 }, "end": { - "line": 226, + "line": 229, "column": 3 } }, @@ -693,11 +693,11 @@ "defaultMessage": "!!!Activate previous service...", "file": "src/lib/Menu.js", "start": { - "line": 227, + "line": 230, "column": 27 }, "end": { - "line": 230, + "line": 233, "column": 3 } }, @@ -706,11 +706,11 @@ "defaultMessage": "!!!Disable notifications & audio", "file": "src/lib/Menu.js", "start": { - "line": 231, + "line": 234, "column": 11 }, "end": { - "line": 234, + "line": 237, "column": 3 } }, @@ -719,11 +719,11 @@ "defaultMessage": "!!!Enable notifications & audio", "file": "src/lib/Menu.js", "start": { - "line": 235, + "line": 238, "column": 13 }, "end": { - "line": 238, + "line": 241, "column": 3 } }, @@ -732,11 +732,11 @@ "defaultMessage": "!!!Workspaces", "file": "src/lib/Menu.js", "start": { - "line": 239, + "line": 242, "column": 14 }, "end": { - "line": 242, + "line": 245, "column": 3 } }, @@ -745,11 +745,50 @@ "defaultMessage": "!!!Default", "file": "src/lib/Menu.js", "start": { - "line": 243, + "line": 246, "column": 20 }, "end": { - "line": 246, + "line": 249, + "column": 3 + } + }, + { + "id": "menu.todos", + "defaultMessage": "!!!Todos", + "file": "src/lib/Menu.js", + "start": { + "line": 250, + "column": 9 + }, + "end": { + "line": 253, + "column": 3 + } + }, + { + "id": "menu.Todoss.openTodosDrawer", + "defaultMessage": "!!!Open Todos drawer", + "file": "src/lib/Menu.js", + "start": { + "line": 254, + "column": 19 + }, + "end": { + "line": 257, + "column": 3 + } + }, + { + "id": "menu.Todoss.closeTodosDrawer", + "defaultMessage": "!!!Close Todos drawer", + "file": "src/lib/Menu.js", + "start": { + "line": 258, + "column": 20 + }, + "end": { + "line": 261, "column": 3 } } diff --git a/src/lib/Menu.js b/src/lib/Menu.js index 9e491e151..81efaf18f 100644 --- a/src/lib/Menu.js +++ b/src/lib/Menu.js @@ -8,6 +8,9 @@ import { workspaceActions } from '../features/workspaces/actions'; import { gaEvent } from './analytics'; import { announcementActions } from '../features/announcements/actions'; import { announcementsStore } from '../features/announcements'; +import TodoStore from '../features/todos/store'; +import { GA_CATEGORY_TODOS, todosStore } from '../features/todos'; +import { todoActions } from '../features/todos/actions'; const { app, Menu, dialog } = remote; @@ -244,7 +247,18 @@ const menuItems = defineMessages({ id: 'menu.workspaces.defaultWorkspace', defaultMessage: '!!!Default', }, - + todos: { + id: 'menu.todos', + defaultMessage: '!!!Todos', + }, + openTodosDrawer: { + id: 'menu.Todoss.openTodosDrawer', + defaultMessage: '!!!Open Todos drawer', + }, + closeTodosDrawer: { + id: 'menu.Todoss.closeTodosDrawer', + defaultMessage: '!!!Close Todos drawer', + }, }); function getActiveWebview() { @@ -352,6 +366,11 @@ const _templateFactory = intl => [ submenu: [], visible: workspaceStore.isFeatureEnabled, }, + { + label: intl.formatMessage(menuItems.todos), + submenu: [], + visible: todosStore.isFeatureEnabled, + }, { label: intl.formatMessage(menuItems.window), role: 'window', @@ -788,6 +807,10 @@ export default class FranzMenu { tpl[4].submenu = this.workspacesMenu(); } + if (todosStore.isFeatureEnabled) { + tpl[5].submenu = this.todosMenu(); + } + tpl[tpl.length - 1].submenu.push({ type: 'separator', }, this.debugMenu()); @@ -902,6 +925,31 @@ export default class FranzMenu { return menu; } + todosMenu() { + const { isTodosPanelVisible } = TodoStore; + const { intl } = window.franz; + const menu = []; + + // Open todos drawer: + const drawerLabel = ( + isTodosPanelVisible ? menuItems.closeTodosDrawer : menuItems.openTodosDrawer + ); + menu.push({ + label: intl.formatMessage(drawerLabel), + accelerator: `${cmdKey}+T`, + click: () => { + todoActions.toggleTodosPanel(); + gaEvent(GA_CATEGORY_TODOS, 'toggleDrawer', 'menu'); + }, + enabled: this.stores.user.isLoggedIn, + }, { + type: 'separator', + }); + + return menu; + } + + debugMenu() { const { intl } = window.franz; -- cgit v1.2.3-70-g09d2 From d047035e4797ebbe24698545da017bb16b7ba625 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 2 Aug 2019 11:42:27 +0200 Subject: Update en-US.json --- src/i18n/locales/en-US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/i18n/locales') diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 3cec9960e..cee42c350 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -336,4 +336,4 @@ "workspaceDrawer.workspaceFeatureInfo": "

Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

", "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", "workspaces.switchingIndicator.switchingTo": "Switching to" -} +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 76559f2895012803aed3256ce521b9cfff2f63b8 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Mon, 5 Aug 2019 13:24:35 +0200 Subject: WIP: add option to activate trial --- src/api/server/ServerApi.js | 2 - src/components/TrialActivationInfoBar.js | 94 +++++++ src/components/layout/AppLayout.js | 37 ++- src/components/services/content/Services.js | 61 ++--- .../settings/account/AccountDashboard.js | 134 ++++++---- .../settings/settings/EditSettingsForm.js | 2 - src/containers/layout/AppLayoutContainer.js | 2 + src/features/delayApp/Component.js | 43 +++- src/features/delayApp/index.js | 2 +- src/i18n/locales/defaultMessages.json | 284 ++++++++++++++++++--- src/i18n/locales/en-US.json | 29 ++- .../src/components/TrialActivationInfoBar.json | 15 ++ .../messages/src/components/layout/AppLayout.json | 12 +- .../messages/src/features/delayApp/Component.json | 40 ++- src/models/User.js | 14 +- src/stores/UserStore.js | 21 ++ src/styles/recipes.scss | 1 + 17 files changed, 630 insertions(+), 163 deletions(-) create mode 100644 src/components/TrialActivationInfoBar.js create mode 100644 src/i18n/messages/src/components/TrialActivationInfoBar.json (limited to 'src/i18n/locales') diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js index f2568d597..f56c7b6e4 100644 --- a/src/api/server/ServerApi.js +++ b/src/api/server/ServerApi.js @@ -87,8 +87,6 @@ export default class ServerApi { } const trial = await request.json(); - console.log(trial); - debug('ServerApi::signup resolves', trial); return true; } 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 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { defineMessages, intlShape } from 'react-intl'; +import ms from 'ms'; +import injectSheet from 'react-jss'; +import classnames from 'classnames'; + +import InfoBar from './ui/InfoBar'; + +const messages = defineMessages({ + message: { + id: 'infobar.trialActivated', + defaultMessage: '!!!Your trial was successfully activated. Happy messaging!', + }, +}); + +const styles = { + notification: { + height: 'auto', + position: 'absolute', + top: -50, + transition: 'top 0.3s', + zIndex: 300, + width: 'calc(100% - 300px)', + }, + show: { + top: 0, + }, +}; + +@injectSheet(styles) +class TrialActivationInfoBar extends Component { + static propTypes = { + // eslint-disable-next-line + classes: PropTypes.object.isRequired, + }; + + static contextTypes = { + intl: intlShape, + }; + + state = { + showing: false, + removed: false, + } + + componentDidMount() { + setTimeout(() => { + this.setState({ + showing: true, + }); + }, 0); + + setTimeout(() => { + this.setState({ + showing: false, + }); + }, ms('6s')); + + setTimeout(() => { + this.setState({ + removed: true, + }); + }, ms('7s')); + } + + render() { + const { classes } = this.props; + const { showing, removed } = this.state; + const { intl } = this.context; + + if (removed) return null; + + return ( +
+ + + {intl.formatMessage(messages.message)} + +
+ ); + } +} + +export default TrialActivationInfoBar; diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js index ebb9849ea..1976f5a50 100644 --- a/src/components/layout/AppLayout.js +++ b/src/components/layout/AppLayout.js @@ -17,6 +17,7 @@ import { isWindows } from '../../environment'; import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator'; import { workspaceStore } from '../../features/workspaces'; import AppUpdateInfoBar from '../AppUpdateInfoBar'; +import TrialActivationInfoBar from '../TrialActivationInfoBar'; function createMarkup(HTMLString) { return { __html: HTMLString }; @@ -57,7 +58,6 @@ class AppLayout extends Component { services: PropTypes.element.isRequired, children: PropTypes.element, news: MobxPropTypes.arrayOrObservableArray.isRequired, - // isOnline: PropTypes.bool.isRequired, showServicesUpdatedInfoBar: PropTypes.bool.isRequired, appUpdateIsDownloaded: PropTypes.bool.isRequired, nextAppReleaseVersion: PropTypes.string, @@ -69,6 +69,7 @@ class AppLayout extends Component { retryRequiredRequests: PropTypes.func.isRequired, areRequiredRequestsLoading: PropTypes.bool.isRequired, isDelayAppScreenVisible: PropTypes.bool.isRequired, + hasActivatedTrial: PropTypes.bool.isRequired, }; static defaultProps = { @@ -88,7 +89,6 @@ class AppLayout extends Component { sidebar, services, children, - // isOnline, news, showServicesUpdatedInfoBar, appUpdateIsDownloaded, @@ -101,6 +101,7 @@ class AppLayout extends Component { retryRequiredRequests, areRequiredRequestsLoading, isDelayAppScreenVisible, + hasActivatedTrial, } = this.props; const { intl } = this.context; @@ -125,26 +126,20 @@ class AppLayout extends Component { ))} - {/* {!isOnline && ( - - - {intl.formatMessage(globalMessages.notConnectedToTheInternet)} - - )} */} + {hasActivatedTrial && ( + + )} {!areRequiredRequestsSuccessful && showRequiredRequestsError && ( - - - {intl.formatMessage(messages.requiredRequestsFailed)} - + + + {intl.formatMessage(messages.requiredRequestsFailed)} + )} {showServicesUpdatedInfoBar && ( + {(userHasCompletedSignup || hasActivatedTrial) && ( +
+ +
+ )} {services.length === 0 && ( - <> - {userHasCompletedSignup && ( -
- -
- )} - -
- -

{intl.formatMessage(messages.welcome)}

- - - {intl.formatMessage(messages.getStarted)} - - -
-
- + +
+ +

{intl.formatMessage(messages.welcome)}

+ + + {intl.formatMessage(messages.getStarted)} + + +
+
)} {services.map(service => ( + <> {!isLoading && ( -
-
-
- -
-
-

- {`${user.firstname} ${user.lastname}`} - {user.isPremium && ( - <> - {' '} - - {intl.formatMessage(messages.accountTypePremium)} - - )} -

- {user.organization && `${user.organization}, `} - {user.email} - {user.isPremium && ( -
-
+ +

+ {user.organization && `${user.organization}, `} + {user.email} +

+ {user.isPremium && ( +
+
+ )} +
+ {!user.isPremium && ( +
- {!user.isPremium && ( -
-
+ {user.isSubscriptionOwner && ( +
+
+

+ Your license: {user.team.plan} +

+ {user.team.isTrial && ( + <> +

+ Trial ends in 14 days +

+ + )} + {user.isPremium && ( +
+
+ )} +
+
+ )} + )} {!user.isPremium && ( @@ -227,7 +261,7 @@ export default @observer class AccountDashboard extends Component { )}
- + )} diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index 6d0811b1b..3f9e0a6bc 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js @@ -143,8 +143,6 @@ export default @observer class EditSettingsForm extends Component { updateButtonLabelMessage = messages.buttonSearchForUpdate; } - console.log('isSpellcheckerIncludedInCurrentPlan', isSpellcheckerIncludedInCurrentPlan); - return (
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index b4e32cffa..a14a98554 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js @@ -128,6 +128,7 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e openSettings={openSettings} update={updateService} userHasCompletedSignup={user.hasCompletedSignup} + hasActivatedTrial={user.hasActivatedTrial} /> ); @@ -152,6 +153,7 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e retryRequiredRequests={retryRequiredRequests} areRequiredRequestsLoading={requests.areRequiredRequestsLoading} isDelayAppScreenVisible={delayAppState.isDelayAppScreenVisible} + hasActivatedTrial={user.hasActivatedTrial} > {React.Children.count(children) > 0 ? children : null} 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'; import { defineMessages, intlShape } from 'react-intl'; import injectSheet from 'react-jss'; +import { Button } from '@meetfranz/forms'; import { gaEvent } from '../../lib/analytics'; -import Button from '../../components/ui/Button'; +// import Button from '../../components/ui/Button'; import { config } from '.'; import styles from './styles'; +import UserStore from '../../stores/UserStore'; const messages = defineMessages({ headline: { id: 'feature.delayApp.headline', defaultMessage: '!!!Please purchase license to skip waiting', }, + headlineTrial: { + id: 'feature.delayApp.trial.headline', + defaultMessage: '!!!Get the free Franz Professional 14 day trial and skip the line', + }, action: { - id: 'feature.delayApp.action', + id: 'feature.delayApp.upgrade.action', defaultMessage: '!!!Get a Franz Supporter License', }, + actionTrial: { + id: 'feature.delayApp.trial.action', + defaultMessage: '!!!Yes, I want the free 14 day trial of Franz Professional', + }, text: { id: 'feature.delayApp.text', defaultMessage: '!!!Franz will continue in {seconds} seconds.', }, }); -export default @inject('actions') @injectSheet(styles) @observer class DelayApp extends Component { +export default @inject('stores', 'actions') @injectSheet(styles) @observer class DelayApp extends Component { static propTypes = { // eslint-disable-next-line classes: PropTypes.object.isRequired, @@ -62,25 +72,37 @@ export default @inject('actions') @injectSheet(styles) @observer class DelayApp } handleCTAClick() { - const { actions } = this.props; + const { actions, stores } = this.props; + const { hadSubscription } = stores.user.data; + const { defaultTrialPlan } = stores.features.features; + + if (!hadSubscription) { + console.log('directly activate trial'); + actions.user.activateTrial({ planId: defaultTrialPlan }); - actions.ui.openSettings({ path: 'user' }); + gaEvent('DelayApp', 'subscribe_click', 'Delay App Feature'); + } else { + actions.ui.openSettings({ path: 'user' }); - gaEvent('DelayApp', 'subscribe_click', 'Delay App Feature'); + gaEvent('DelayApp', 'subscribe_click', 'Delay App Feature'); + } } render() { - const { classes } = this.props; + const { classes, stores } = this.props; const { intl } = this.context; + const { hadSubscription } = stores.user.data; + return (
-

{intl.formatMessage(messages.headline)}

+

{intl.formatMessage(hadSubscription ? messages.headline : messages.headlineTrial)}

- )} +
+
)} - - )} - - {!user.isPremium && ( - isLoadingPlans ? ( - - ) : ( -
-
-

{intl.formatMessage(messages.headlineUpgrade)}

- + {!user.isPremium && ( +
+
+

{intl.formatMessage(messages.headlineUpgrade)}

+ +
-
- ) + )} + )}
-

{intl.formatMessage(messages.headlineDangerZone)}

+

{intl.formatMessage(messages.headlineDangerZone)}

{!isDeleteAccountSuccessful && (

{intl.formatMessage(messages.deleteInfo)}

diff --git a/src/components/subscription/SubscriptionForm.js b/src/components/subscription/SubscriptionForm.js index 50f1e0522..0c630f047 100644 --- a/src/components/subscription/SubscriptionForm.js +++ b/src/components/subscription/SubscriptionForm.js @@ -1,214 +1,94 @@ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; +import { observer } from 'mobx-react'; import { defineMessages, intlShape } from 'react-intl'; +import injectSheet from 'react-jss'; -import Form from '../../lib/Form'; -import Radio from '../ui/Radio'; -import Button from '../ui/Button'; -import Loader from '../ui/Loader'; +import { H3 } from '@meetfranz/ui'; -import { required } from '../../helpers/validation-helpers'; +import { Button } from '@meetfranz/forms'; +import { FeatureList } from '../ui/FeatureList'; +import { FeatureItem } from '../ui/FeatureItem'; const messages = defineMessages({ submitButtonLabel: { - id: 'subscription.submit.label', - defaultMessage: '!!!Support the development of Franz', - }, - paymentSessionError: { - id: 'subscription.paymentSessionError', - defaultMessage: '!!!Could not initialize payment form', - }, - typeFree: { - id: 'subscription.type.free', - defaultMessage: '!!!free', - }, - typeMonthly: { - id: 'subscription.type.month', - defaultMessage: '!!!month', - }, - typeYearly: { - id: 'subscription.type.year', - defaultMessage: '!!!year', + id: 'subscription.cta.activateTrial', + defaultMessage: '!!!Yes, upgrade my account to Franz Professional', }, includedFeatures: { - id: 'subscription.includedFeatures', - defaultMessage: '!!!The Franz Premium Supporter Account includes', - }, - onpremise: { - id: 'subscription.features.onpremise.mattermost', - defaultMessage: '!!!Add on-premise/hosted services like Mattermost', - }, - noInterruptions: { - id: 'subscription.features.noInterruptions', - defaultMessage: '!!!No app delays & nagging to upgrade license', + id: 'subscription.includedProFeatures', + defaultMessage: '!!!The Franz Professional Plan includes:', }, - proxy: { - id: 'subscription.features.proxy', - defaultMessage: '!!!Proxy support for services', + noStringsAttachedHeadline: { + id: 'pricing.trial.terms.headline', + defaultMessage: '!!!No strings attached', }, - spellchecker: { - id: 'subscription.features.spellchecker', - defaultMessage: '!!!Support for Spellchecker', + noCreditCard: { + id: 'pricing.trial.terms.noCreditCard', + defaultMessage: '!!!No credit card required', }, - workspaces: { - id: 'subscription.features.workspaces', - defaultMessage: '!!!Organize your services in workspaces', + automaticTrialEnd: { + id: 'pricing.trial.terms.automaticTrialEnd', + defaultMessage: '!!!Your free trial ends automatically after 14 days', }, - ads: { - id: 'subscription.features.ads', - defaultMessage: '!!!No ads, ever!', - }, - comingSoon: { - id: 'subscription.features.comingSoon', - defaultMessage: '!!!coming soon', +}); + +const styles = () => ({ + activateTrialButton: { + margin: [40, 0, 50], }, - euTaxInfo: { - id: 'subscription.euTaxInfo', - defaultMessage: '!!!EU residents: local sales tax may apply', + keyTerms: { + marginTop: 20, }, }); -export default @observer class SubscriptionForm extends Component { +export default @observer @injectSheet(styles) class SubscriptionForm extends Component { static propTypes = { - plan: MobxPropTypes.objectOrObservableObject.isRequired, - isLoading: PropTypes.bool.isRequired, - handlePayment: PropTypes.func.isRequired, - retryPlanRequest: PropTypes.func.isRequired, - isCreatingHostedPage: PropTypes.bool.isRequired, - error: PropTypes.bool.isRequired, - showSkipOption: PropTypes.bool, - skipAction: PropTypes.func, - skipButtonLabel: PropTypes.string, - hideInfo: PropTypes.bool.isRequired, - }; - - static defaultProps = { - showSkipOption: false, - skipAction: () => null, - skipButtonLabel: '', + activateTrial: PropTypes.func.isRequired, + isActivatingTrial: PropTypes.bool.isRequired, + classes: PropTypes.object.isRequired, }; static contextTypes = { intl: intlShape, }; - componentWillMount() { - this.form = this.prepareForm(); - } - - prepareForm() { - const { intl } = this.context; - - const form = { - fields: { - paymentTier: { - value: 'year', - validators: [required], - options: [{ - value: 'month', - label: `€ ${Object.hasOwnProperty.call(this.props.plan, 'month') - ? `${this.props.plan.month.price} / ${intl.formatMessage(messages.typeMonthly)}` - : 'monthly'}`, - }, { - value: 'year', - label: `€ ${Object.hasOwnProperty.call(this.props.plan, 'year') - ? `${this.props.plan.year.price} / ${intl.formatMessage(messages.typeYearly)}` - : 'yearly'}`, - }], - }, - }, - }; - - if (this.props.showSkipOption) { - form.fields.paymentTier.options.unshift({ - value: 'skip', - label: `€ 0 / ${intl.formatMessage(messages.typeFree)}`, - }); - } - - return new Form(form, this.context.intl); - } - render() { const { - isLoading, - isCreatingHostedPage, - handlePayment, - retryPlanRequest, - error, - showSkipOption, - skipAction, - skipButtonLabel, - hideInfo, + isActivatingTrial, + activateTrial, + classes, } = this.props; const { intl } = this.context; - if (error) { - return ( -
+ ); } } diff --git a/src/config.js b/src/config.js index 3c8b0f0d0..edcae9df1 100644 --- a/src/config.js +++ b/src/config.js @@ -84,3 +84,27 @@ export const ALLOWED_PROTOCOLS = [ 'http:', 'ftp:', ]; + +export const PLANS = { + PERSONAL_MONTHLY: 'PERSONAL_MONTHLY', + PERSONAL_YEARLY: 'PERSONAL_YEARLY', + PRO_MONTHLY: 'PRO_MONTHLY', + PRO_YEARLY: 'PRO_YEARLY', + LEGACY: 'LEGACY', + FREE: 'FREE', +}; + +export const PLANS_MAPPING = { + 'franz-personal-monthly': PLANS.PERSONAL_MONTHLY, + 'franz-personal-yearly': PLANS.PERSONAL_YEARLY, + 'franz-pro-monthly': PLANS.PRO_MONTHLY, + 'franz-pro-yearly': PLANS.PRO_YEARLY, + 'franz-supporter-license': PLANS.LEGACY, + 'franz-supporter-license-x1': PLANS.LEGACY, + 'franz-supporter-license-x2': PLANS.LEGACY, + 'franz-supporter-license-year': PLANS.LEGACY, + 'franz-supporter-license-year-x1': PLANS.LEGACY, + 'franz-supporter-license-year-x2': PLANS.LEGACY, + 'franz-supporter-license-year-2019': PLANS.LEGACY, + free: PLANS.FREE, +}; diff --git a/src/containers/subscription/SubscriptionFormScreen.js b/src/containers/subscription/SubscriptionFormScreen.js index aa1166f5e..7486cc498 100644 --- a/src/containers/subscription/SubscriptionFormScreen.js +++ b/src/containers/subscription/SubscriptionFormScreen.js @@ -74,28 +74,14 @@ export default @inject('stores', 'actions') @observer class SubscriptionFormScre render() { const { - content, actions, stores, - showSkipOption, - skipAction, - skipButtonLabel, - hideInfo, } = this.props; return ( stores.payment.plansRequest.reload()} - isCreatingHostedPage={stores.payment.createHostedPageRequest.isExecuting} - handlePayment={price => this.handlePayment(price)} - content={content} - error={stores.payment.plansRequest.isError} - showSkipOption={showSkipOption} - skipAction={skipAction} - skipButtonLabel={skipButtonLabel} - hideInfo={hideInfo} - openExternalUrl={actions.app.openExternalUrl} + activateTrial={() => actions.user.activateTrial({ planId: stores.features.features.defaultTrialPlan })} + isActivatingTrial={stores.user.activateTrialRequest.isExecuting || stores.user.getUserInfoRequest.isExecuting} /> ); } diff --git a/src/helpers/plan-helpers.js b/src/helpers/plan-helpers.js new file mode 100644 index 000000000..37a4457af --- /dev/null +++ b/src/helpers/plan-helpers.js @@ -0,0 +1,43 @@ +import { defineMessages } from 'react-intl'; +import { PLANS_MAPPING, PLANS } from '../config'; + +const messages = defineMessages({ + [PLANS.PRO_YEARLY]: { + id: 'pricing.plan.pro-yearly', + defaultMessage: '!!!Franz Professional Yearly', + }, + [PLANS.PRO_MONTHLY]: { + id: 'pricing.plan.pro-monthly', + defaultMessage: '!!!Franz Professional Monthly', + }, + [PLANS.PERSONAL_YEARLY]: { + id: 'pricing.plan.personal-yearly', + defaultMessage: '!!!Franz Personal Yearly', + }, + [PLANS.PERSONAL_MONTHLY]: { + id: 'pricing.plan.personal-monthly', + defaultMessage: '!!!Franz Personal Monthly', + }, + [PLANS.FREE]: { + id: 'pricing.plan.free', + defaultMessage: '!!!Franz Free', + }, + [PLANS.LEGACY]: { + id: 'pricing.plan.legacy', + defaultMessage: '!!!Franz Premium', + }, +}); + +export function i18nPlanName(planId, intl) { + if (!planId) { + throw new Error('planId is required'); + } + + if (!intl) { + throw new Error('intl context is required'); + } + + const plan = PLANS_MAPPING[planId]; + + return intl.formatMessage(messages[plan]); +} diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index 930f6752e..836fe3b24 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -734,39 +734,39 @@ "defaultMessage": "!!!Your services have been updated.", "end": { "column": 3, - "line": 29 + "line": 30 }, "file": "src/components/layout/AppLayout.js", "id": "infobar.servicesUpdated", "start": { "column": 19, - "line": 26 + "line": 27 } }, { "defaultMessage": "!!!Reload services", "end": { "column": 3, - "line": 33 + "line": 34 }, "file": "src/components/layout/AppLayout.js", "id": "infobar.buttonReloadServices", "start": { "column": 24, - "line": 30 + "line": 31 } }, { "defaultMessage": "!!!Could not load services and user information", "end": { "column": 3, - "line": 37 + "line": 38 }, "file": "src/components/layout/AppLayout.js", "id": "infobar.requiredRequestsFailed", "start": { "column": 26, - "line": 34 + "line": 35 } } ], @@ -1242,195 +1242,247 @@ "defaultMessage": "!!!Account", "end": { "column": 3, - "line": 17 + "line": 19 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.headline", "start": { "column": 12, - "line": 14 + "line": 16 } }, { "defaultMessage": "!!!Your Subscription", "end": { "column": 3, - "line": 21 + "line": 23 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.headlineSubscription", "start": { "column": 24, - "line": 18 + "line": 20 } }, { "defaultMessage": "!!!Upgrade your Account", "end": { "column": 3, - "line": 25 + "line": 27 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.headlineUpgrade", "start": { "column": 19, - "line": 22 + "line": 24 } }, { "defaultMessage": "!!Danger Zone", "end": { "column": 3, - "line": 29 + "line": 31 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.headlineDangerZone", "start": { "column": 22, - "line": 26 + "line": 28 } }, { "defaultMessage": "!!!Manage your subscription", "end": { "column": 3, - "line": 33 + "line": 35 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.manageSubscription.label", "start": { "column": 33, - "line": 30 + "line": 32 } }, { "defaultMessage": "!!!Basic Account", "end": { "column": 3, - "line": 37 + "line": 39 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.accountType.basic", "start": { "column": 20, - "line": 34 + "line": 36 } }, { "defaultMessage": "!!!Premium Supporter Account", "end": { "column": 3, - "line": 41 + "line": 43 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.accountType.premium", "start": { "column": 22, - "line": 38 + "line": 40 } }, { "defaultMessage": "!!!Edit Account", "end": { "column": 3, - "line": 45 + "line": 47 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.account.editButton", "start": { "column": 21, - "line": 42 + "line": 44 } }, { "defaultMessage": "!!Invoices", "end": { "column": 3, - "line": 49 + "line": 51 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.headlineInvoices", "start": { "column": 18, - "line": 46 + "line": 48 } }, { "defaultMessage": "!!!Download", "end": { "column": 3, - "line": 53 + "line": 55 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.invoiceDownload", "start": { "column": 19, - "line": 50 + "line": 52 } }, { "defaultMessage": "!!!Could not load user information", "end": { "column": 3, - "line": 57 + "line": 59 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.userInfoRequestFailed", "start": { "column": 25, - "line": 54 + "line": 56 } }, { "defaultMessage": "!!!Try again", "end": { "column": 3, - "line": 61 + "line": 63 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.tryReloadUserInfoRequest", "start": { "column": 28, - "line": 58 + "line": 60 } }, { "defaultMessage": "!!!Delete account", "end": { "column": 3, - "line": 65 + "line": 67 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.deleteAccount", "start": { "column": 17, - "line": 62 + "line": 64 } }, { "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", "end": { "column": 3, - "line": 69 + "line": 71 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.deleteInfo", "start": { "column": 14, - "line": 66 + "line": 68 } }, { "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", "end": { "column": 3, - "line": 73 + "line": 75 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.deleteEmailSent", "start": { "column": 19, - "line": 70 + "line": 72 + } + }, + { + "defaultMessage": "!!!Free Trial", + "end": { + "column": 3, + "line": 79 + }, + "file": "src/components/settings/account/AccountDashboard.js", + "id": "settings.account.trial", + "start": { + "column": 9, + "line": 76 + } + }, + { + "defaultMessage": "!!!Your license:", + "end": { + "column": 3, + "line": 83 + }, + "file": "src/components/settings/account/AccountDashboard.js", + "id": "settings.account.yourLicense", + "start": { + "column": 15, + "line": 80 + } + }, + { + "defaultMessage": "!!!Your free trial ends in {duration}.", + "end": { + "column": 3, + "line": 87 + }, + "file": "src/components/settings/account/AccountDashboard.js", + "id": "settings.account.trialEndsIn", + "start": { + "column": 15, + "line": 84 + } + }, + { + "defaultMessage": "!!!Please update your billing info to continue using {license} after your trial period.", + "end": { + "column": 3, + "line": 91 + }, + "file": "src/components/settings/account/AccountDashboard.js", + "id": "settings.account.trialUpdateBillingInfo", + "start": { + "column": 33, + "line": 88 } } ], @@ -2869,6 +2921,24 @@ ], "path": "src/components/subscription/SubscriptionPopup.json" }, + { + "descriptors": [ + { + "defaultMessage": "!!!Your trial was successfully activated. Happy messaging!", + "end": { + "column": 3, + "line": 14 + }, + "file": "src/components/TrialActivationInfoBar.js", + "id": "infobar.trialActivated", + "start": { + "column": 11, + "line": 11 + } + } + ], + "path": "src/components/TrialActivationInfoBar.json" + }, { "descriptors": [ { @@ -3578,65 +3648,65 @@ "defaultMessage": "!!!Please purchase license to skip waiting", "end": { "column": 3, - "line": 19 + "line": 20 }, "file": "src/features/delayApp/Component.js", "id": "feature.delayApp.headline", "start": { "column": 12, - "line": 16 + "line": 17 } }, { "defaultMessage": "!!!Get the free Franz Professional 14 day trial and skip the line", "end": { "column": 3, - "line": 23 + "line": 24 }, "file": "src/features/delayApp/Component.js", "id": "feature.delayApp.trial.headline", "start": { "column": 17, - "line": 20 + "line": 21 } }, { "defaultMessage": "!!!Get a Franz Supporter License", "end": { "column": 3, - "line": 27 + "line": 28 }, "file": "src/features/delayApp/Component.js", "id": "feature.delayApp.upgrade.action", "start": { "column": 10, - "line": 24 + "line": 25 } }, { "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", "end": { "column": 3, - "line": 31 + "line": 32 }, "file": "src/features/delayApp/Component.js", "id": "feature.delayApp.trial.action", "start": { "column": 15, - "line": 28 + "line": 29 } }, { "defaultMessage": "!!!Franz will continue in {seconds} seconds.", "end": { "column": 3, - "line": 35 + "line": 36 }, "file": "src/features/delayApp/Component.js", "id": "feature.delayApp.text", "start": { "column": 8, - "line": 32 + "line": 33 } } ], @@ -4181,6 +4251,172 @@ ], "path": "src/features/workspaces/components/WorkspaceSwitchingIndicator.json" }, + { + "descriptors": [ + { + "defaultMessage": "!!!Franz Professional Yearly", + "end": { + "column": 3, + "line": 8 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.pro-yearly", + "start": { + "column": 22, + "line": 5 + } + }, + { + "defaultMessage": "!!!Franz Professional Monthly", + "end": { + "column": 3, + "line": 12 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.pro-monthly", + "start": { + "column": 23, + "line": 9 + } + }, + { + "defaultMessage": "!!!Franz Personal Yearly", + "end": { + "column": 3, + "line": 16 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.personal-yearly", + "start": { + "column": 27, + "line": 13 + } + }, + { + "defaultMessage": "!!!Franz Personal Monthly", + "end": { + "column": 3, + "line": 20 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.personal-monthly", + "start": { + "column": 28, + "line": 17 + } + }, + { + "defaultMessage": "!!!Franz Free", + "end": { + "column": 3, + "line": 24 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.free", + "start": { + "column": 16, + "line": 21 + } + }, + { + "defaultMessage": "!!!Franz Premium", + "end": { + "column": 3, + "line": 28 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.legacy", + "start": { + "column": 18, + "line": 25 + } + } + ], + "path": "src/helpers/plan-helpers.json" + }, + { + "descriptors": [ + { + "defaultMessage": "!!!Franz Professional Yearly", + "end": { + "column": 3, + "line": 8 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.pro-yearly", + "start": { + "column": 22, + "line": 5 + } + }, + { + "defaultMessage": "!!!Franz Professional Monthly", + "end": { + "column": 3, + "line": 12 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.pro-monthly", + "start": { + "column": 23, + "line": 9 + } + }, + { + "defaultMessage": "!!!Franz Personal Yearly", + "end": { + "column": 3, + "line": 16 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.personal-yearly", + "start": { + "column": 27, + "line": 13 + } + }, + { + "defaultMessage": "!!!Franz Personal Monthly", + "end": { + "column": 3, + "line": 20 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.personal-monthly", + "start": { + "column": 28, + "line": 17 + } + }, + { + "defaultMessage": "!!!Franz Free", + "end": { + "column": 3, + "line": 24 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.free", + "start": { + "column": 16, + "line": 21 + } + }, + { + "defaultMessage": "!!!Franz Premium", + "end": { + "column": 3, + "line": 28 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.legacy", + "start": { + "column": 18, + "line": 25 + } + } + ], + "path": "src/helpers/pricing-helpers.json" + }, { "descriptors": [ { diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 4049e9400..eb0027424 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -4,9 +4,9 @@ "feature.announcements.changelog.headline": "Changes in Franz {version}", "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", "feature.delayApp.text": "Franz will continue in {seconds} seconds.", - "feature.delayApp.trial.action": "!!!Yes, I want the free 14 day trial of Franz Professional", - "feature.delayApp.trial.headline": "!!!Get the free Franz Professional 14 day trial and skip the line", - "feature.delayApp.upgrade.action": "!!!Get a Franz Supporter License", + "feature.delayApp.trial.action": "Yes, I want the free 14 day trial of Franz Professional", + "feature.delayApp.trial.headline": "Get the free Franz Professional 14 day trial and skip the line", + "feature.delayApp.upgrade.action": "Get a Franz Supporter License", "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.", "feature.shareFranz.action.email": "Send as email", "feature.shareFranz.action.facebook": "Share on Facebook", @@ -30,6 +30,7 @@ "infobar.buttonReloadServices": "Reload services", "infobar.requiredRequestsFailed": "Could not load services and user information", "infobar.servicesUpdated": "Your services have been updated.", + "infobar.trialActivated": "Your trial was successfully activated. Happy messaging!", "infobar.updateAvailable": "A new update for Franz is available.", "invite.email.label": "Email address", "invite.headline.friends": "Invite 3 of your friends or colleagues", @@ -106,25 +107,31 @@ "password.submit.label": "Submit", "password.successInfo": "Please check your email", "premiumFeature.button.upgradeAccount": "Upgrade account", - "pricing.features.adFree": "!!!Forever ad-free", - "pricing.features.appDelays": "!!!No Waiting Screens", - "pricing.features.customWebsites": "!!!Add Custom Websites", - "pricing.features.onPremise": "!!!On-premise & other Hosted Services", - "pricing.features.serviceProxies": "!!!Service Proxies", - "pricing.features.spellchecker": "!!!Spellchecker support", - "pricing.features.teamManagement": "!!!Team Management", - "pricing.features.thirdPartyServices": "!!!Install 3rd party services", - "pricing.features.unlimitedServices": "!!!Add unlimited services", - "pricing.features.workspaces": "!!!Workspaces", - "pricing.trial.cta.accept": "!!!Yes, upgrade my account to Franz Professional", - "pricing.trial.cta.skip": "!!!Continue to Franz", - "pricing.trial.error": "!!!Sorry, we could not activate your trial!", - "pricing.trial.features.headline": "!!!Franz Professional includes:", - "pricing.trial.headline": "!!!Franz Professional", - "pricing.trial.subheadline": "!!!Your personal welcome offer:", - "pricing.trial.terms.automaticTrialEnd": "!!!Your free trial ends automatically after 14 days", - "pricing.trial.terms.headline": "!!!No strings attached", - "pricing.trial.terms.noCreditCard": "!!!No credit card required", + "pricing.features.adFree": "Forever ad-free", + "pricing.features.appDelays": "No Waiting Screens", + "pricing.features.customWebsites": "Add Custom Websites", + "pricing.features.onPremise": "On-premise & other Hosted Services", + "pricing.features.serviceProxies": "Service Proxies", + "pricing.features.spellchecker": "Spellchecker support", + "pricing.features.teamManagement": "Team Management", + "pricing.features.thirdPartyServices": "Install 3rd party services", + "pricing.features.unlimitedServices": "Add unlimited services", + "pricing.features.workspaces": "Workspaces", + "pricing.plan.free": "Franz Free", + "pricing.plan.legacy": "Franz Premium", + "pricing.plan.personal-monthly": "Franz Personal Monthly", + "pricing.plan.personal-yearly": "Franz Personal Yearly", + "pricing.plan.pro-monthly": "Franz Professional Monthly", + "pricing.plan.pro-yearly": "Franz Professional Yearly", + "pricing.trial.cta.accept": "Yes, upgrade my account to Franz Professional", + "pricing.trial.cta.skip": "Continue to Franz", + "pricing.trial.error": "Sorry, we could not activate your trial!", + "pricing.trial.features.headline": "Franz Professional includes:", + "pricing.trial.headline": "Franz Professional", + "pricing.trial.subheadline": "Your personal welcome offer:", + "pricing.trial.terms.automaticTrialEnd": "Your free trial ends automatically after 14 days", + "pricing.trial.terms.headline": "No strings attached", + "pricing.trial.terms.noCreditCard": "No credit card required", "service.crashHandler.action": "Reload {name}", "service.crashHandler.autoReload": "Trying to automatically restore {name} in {seconds} seconds", "service.crashHandler.headline": "Oh no!", @@ -162,9 +169,13 @@ "settings.account.invoiceDownload": "Download", "settings.account.manageSubscription.label": "Manage your subscription", "settings.account.successInfo": "Your changes have been saved", + "settings.account.trial": "Free Trial", + "settings.account.trialEndsIn": "Your free trial ends in {duration}.", + "settings.account.trialUpdateBillingInfo": "Please update your billing info to continue using {license} after your trial period.", "settings.account.tryReloadServices": "Try again", "settings.account.tryReloadUserInfoRequest": "Try again", "settings.account.userInfoRequestFailed": "Could not load user information", + "settings.account.yourLicense": "Your license:", "settings.app.buttonClearAllCache": "Clear cache", "settings.app.buttonInstallUpdate": "Restart & install update", "settings.app.buttonSearchForUpdate": "Check for updates", @@ -358,4 +369,4 @@ "workspaceDrawer.workspaceFeatureInfo": "

Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

", "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", "workspaces.switchingIndicator.switchingTo": "Switching to" -} \ No newline at end of file +} diff --git a/src/i18n/messages/src/components/settings/account/AccountDashboard.json b/src/i18n/messages/src/components/settings/account/AccountDashboard.json index 4969db910..1e21bad69 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 @@ "defaultMessage": "!!!Account", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 14, + "line": 18, "column": 12 }, "end": { - "line": 17, + "line": 21, "column": 3 } }, @@ -17,24 +17,24 @@ "defaultMessage": "!!!Your Subscription", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 18, + "line": 22, "column": 24 }, "end": { - "line": 21, + "line": 25, "column": 3 } }, { - "id": "settings.account.headlineUpgrade", - "defaultMessage": "!!!Upgrade your Account", + "id": "settings.account.headlineTrialUpgrade", + "defaultMessage": "!!!Get the free 14 day Franz Professional Trial", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 22, + "line": 26, "column": 19 }, "end": { - "line": 25, + "line": 29, "column": 3 } }, @@ -43,11 +43,11 @@ "defaultMessage": "!!Danger Zone", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 26, + "line": 30, "column": 22 }, "end": { - "line": 29, + "line": 33, "column": 3 } }, @@ -56,11 +56,11 @@ "defaultMessage": "!!!Manage your subscription", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 30, + "line": 34, "column": 33 }, "end": { - "line": 33, + "line": 37, "column": 3 } }, @@ -69,11 +69,11 @@ "defaultMessage": "!!!Basic Account", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 34, + "line": 38, "column": 20 }, "end": { - "line": 37, + "line": 41, "column": 3 } }, @@ -82,11 +82,11 @@ "defaultMessage": "!!!Premium Supporter Account", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 38, + "line": 42, "column": 22 }, "end": { - "line": 41, + "line": 45, "column": 3 } }, @@ -95,11 +95,11 @@ "defaultMessage": "!!!Edit Account", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 42, + "line": 46, "column": 21 }, "end": { - "line": 45, + "line": 49, "column": 3 } }, @@ -108,11 +108,11 @@ "defaultMessage": "!!Invoices", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 46, + "line": 50, "column": 18 }, "end": { - "line": 49, + "line": 53, "column": 3 } }, @@ -121,11 +121,11 @@ "defaultMessage": "!!!Download", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 50, + "line": 54, "column": 19 }, "end": { - "line": 53, + "line": 57, "column": 3 } }, @@ -134,11 +134,11 @@ "defaultMessage": "!!!Could not load user information", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 54, + "line": 58, "column": 25 }, "end": { - "line": 57, + "line": 61, "column": 3 } }, @@ -147,11 +147,11 @@ "defaultMessage": "!!!Try again", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 58, + "line": 62, "column": 28 }, "end": { - "line": 61, + "line": 65, "column": 3 } }, @@ -160,11 +160,11 @@ "defaultMessage": "!!!Delete account", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 62, + "line": 66, "column": 17 }, "end": { - "line": 65, + "line": 69, "column": 3 } }, @@ -173,11 +173,11 @@ "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 66, + "line": 70, "column": 14 }, "end": { - "line": 69, + "line": 73, "column": 3 } }, @@ -186,11 +186,63 @@ "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 70, + "line": 74, "column": 19 }, "end": { - "line": 73, + "line": 77, + "column": 3 + } + }, + { + "id": "settings.account.trial", + "defaultMessage": "!!!Free Trial", + "file": "src/components/settings/account/AccountDashboard.js", + "start": { + "line": 78, + "column": 9 + }, + "end": { + "line": 81, + "column": 3 + } + }, + { + "id": "settings.account.yourLicense", + "defaultMessage": "!!!Your license:", + "file": "src/components/settings/account/AccountDashboard.js", + "start": { + "line": 82, + "column": 15 + }, + "end": { + "line": 85, + "column": 3 + } + }, + { + "id": "settings.account.trialEndsIn", + "defaultMessage": "!!!Your free trial ends in {duration}.", + "file": "src/components/settings/account/AccountDashboard.js", + "start": { + "line": 86, + "column": 15 + }, + "end": { + "line": 89, + "column": 3 + } + }, + { + "id": "settings.account.trialUpdateBillingInfo", + "defaultMessage": "!!!Please update your billing info to continue using {license} after your trial period.", + "file": "src/components/settings/account/AccountDashboard.js", + "start": { + "line": 90, + "column": 33 + }, + "end": { + "line": 93, "column": 3 } } diff --git a/src/i18n/messages/src/components/subscription/SubscriptionForm.json b/src/i18n/messages/src/components/subscription/SubscriptionForm.json index f98eb986f..224a78c4c 100644 --- a/src/i18n/messages/src/components/subscription/SubscriptionForm.json +++ b/src/i18n/messages/src/components/subscription/SubscriptionForm.json @@ -1,7 +1,7 @@ [ { - "id": "subscription.submit.label", - "defaultMessage": "!!!Support the development of Franz", + "id": "subscription.cta.activateTrial", + "defaultMessage": "!!!Yes, upgrade my account to Franz Professional", "file": "src/components/subscription/SubscriptionForm.js", "start": { "line": 14, @@ -13,12 +13,12 @@ } }, { - "id": "subscription.paymentSessionError", - "defaultMessage": "!!!Could not initialize payment form", + "id": "subscription.includedProFeatures", + "defaultMessage": "!!!The Franz Professional Plan includes:", "file": "src/components/subscription/SubscriptionForm.js", "start": { "line": 18, - "column": 23 + "column": 20 }, "end": { "line": 21, @@ -26,12 +26,12 @@ } }, { - "id": "subscription.type.free", - "defaultMessage": "!!!free", + "id": "pricing.trial.terms.headline", + "defaultMessage": "!!!No strings attached", "file": "src/components/subscription/SubscriptionForm.js", "start": { "line": 22, - "column": 12 + "column": 29 }, "end": { "line": 25, @@ -39,12 +39,12 @@ } }, { - "id": "subscription.type.month", - "defaultMessage": "!!!month", + "id": "pricing.trial.terms.noCreditCard", + "defaultMessage": "!!!No credit card required", "file": "src/components/subscription/SubscriptionForm.js", "start": { "line": 26, - "column": 15 + "column": 16 }, "end": { "line": 29, @@ -52,133 +52,16 @@ } }, { - "id": "subscription.type.year", - "defaultMessage": "!!!year", + "id": "pricing.trial.terms.automaticTrialEnd", + "defaultMessage": "!!!Your free trial ends automatically after 14 days", "file": "src/components/subscription/SubscriptionForm.js", "start": { "line": 30, - "column": 14 + "column": 21 }, "end": { "line": 33, "column": 3 } - }, - { - "id": "subscription.includedFeatures", - "defaultMessage": "!!!The Franz Premium Supporter Account includes", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 34, - "column": 20 - }, - "end": { - "line": 37, - "column": 3 - } - }, - { - "id": "subscription.features.onpremise.mattermost", - "defaultMessage": "!!!Add on-premise/hosted services like Mattermost", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 38, - "column": 13 - }, - "end": { - "line": 41, - "column": 3 - } - }, - { - "id": "subscription.features.noInterruptions", - "defaultMessage": "!!!No app delays & nagging to upgrade license", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 42, - "column": 19 - }, - "end": { - "line": 45, - "column": 3 - } - }, - { - "id": "subscription.features.proxy", - "defaultMessage": "!!!Proxy support for services", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 46, - "column": 9 - }, - "end": { - "line": 49, - "column": 3 - } - }, - { - "id": "subscription.features.spellchecker", - "defaultMessage": "!!!Support for Spellchecker", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 50, - "column": 16 - }, - "end": { - "line": 53, - "column": 3 - } - }, - { - "id": "subscription.features.workspaces", - "defaultMessage": "!!!Organize your services in workspaces", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 54, - "column": 14 - }, - "end": { - "line": 57, - "column": 3 - } - }, - { - "id": "subscription.features.ads", - "defaultMessage": "!!!No ads, ever!", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 58, - "column": 7 - }, - "end": { - "line": 61, - "column": 3 - } - }, - { - "id": "subscription.features.comingSoon", - "defaultMessage": "!!!coming soon", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 62, - "column": 14 - }, - "end": { - "line": 65, - "column": 3 - } - }, - { - "id": "subscription.euTaxInfo", - "defaultMessage": "!!!EU residents: local sales tax may apply", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 66, - "column": 13 - }, - "end": { - "line": 69, - "column": 3 - } } ] \ No newline at end of file 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..de27dfcfd --- /dev/null +++ b/src/i18n/messages/src/helpers/plan-helpers.json @@ -0,0 +1,80 @@ +[ + { + "id": "pricing.plan.pro-yearly", + "defaultMessage": "!!!Franz Professional Yearly", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 5, + "column": 22 + }, + "end": { + "line": 8, + "column": 3 + } + }, + { + "id": "pricing.plan.pro-monthly", + "defaultMessage": "!!!Franz Professional Monthly", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 9, + "column": 23 + }, + "end": { + "line": 12, + "column": 3 + } + }, + { + "id": "pricing.plan.personal-yearly", + "defaultMessage": "!!!Franz Personal Yearly", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 13, + "column": 27 + }, + "end": { + "line": 16, + "column": 3 + } + }, + { + "id": "pricing.plan.personal-monthly", + "defaultMessage": "!!!Franz Personal Monthly", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 20, + "column": 3 + } + }, + { + "id": "pricing.plan.free", + "defaultMessage": "!!!Franz Free", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 21, + "column": 16 + }, + "end": { + "line": 24, + "column": 3 + } + }, + { + "id": "pricing.plan.legacy", + "defaultMessage": "!!!Franz Premium", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 25, + "column": 18 + }, + "end": { + "line": 28, + "column": 3 + } + } +] \ 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 @@ +[ + { + "id": "pricing.plan.pro-yearly", + "defaultMessage": "!!!Franz Professional Yearly", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 5, + "column": 22 + }, + "end": { + "line": 8, + "column": 3 + } + }, + { + "id": "pricing.plan.pro-monthly", + "defaultMessage": "!!!Franz Professional Monthly", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 9, + "column": 23 + }, + "end": { + "line": 12, + "column": 3 + } + }, + { + "id": "pricing.plan.personal-yearly", + "defaultMessage": "!!!Franz Personal Yearly", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 13, + "column": 27 + }, + "end": { + "line": 16, + "column": 3 + } + }, + { + "id": "pricing.plan.personal-monthly", + "defaultMessage": "!!!Franz Personal Monthly", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 20, + "column": 3 + } + }, + { + "id": "pricing.plan.free", + "defaultMessage": "!!!Franz Free", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 21, + "column": 16 + }, + "end": { + "line": 24, + "column": 3 + } + }, + { + "id": "pricing.plan.legacy", + "defaultMessage": "!!!Franz Premium", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 25, + "column": 18 + }, + "end": { + "line": 28, + "column": 3 + } + } +] \ No newline at end of file diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js index 72c4b4d0b..55ee52b18 100644 --- a/src/stores/AppStore.js +++ b/src/stores/AppStore.js @@ -334,6 +334,8 @@ export default class AppStore extends Store { this.locale = this._getDefaultLocale(); } + moment.locale(this.locale); + debug(`Set locale to "${this.locale}"`); } 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 @@ .account__subscription-button { margin-left: auto; } .franz-form__button { white-space: nowrap; } div { height: auto; } + [data-type="franz-button"] div { height: 100% } .invoices { width: 100%; -- cgit v1.2.3-70-g09d2 From 56f4658b58c56dd1e5165be755e8144ba2fd4937 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Wed, 14 Aug 2019 08:04:02 +0200 Subject: remove monthly & yearly names --- src/config.js | 14 ++++---- src/helpers/plan-helpers.js | 20 ++++------- src/i18n/locales/en-US.json | 6 ++-- src/i18n/messages/src/helpers/plan-helpers.json | 46 ++++++------------------- 4 files changed, 24 insertions(+), 62 deletions(-) (limited to 'src/i18n/locales') diff --git a/src/config.js b/src/config.js index edcae9df1..66adedfc6 100644 --- a/src/config.js +++ b/src/config.js @@ -86,19 +86,17 @@ export const ALLOWED_PROTOCOLS = [ ]; export const PLANS = { - PERSONAL_MONTHLY: 'PERSONAL_MONTHLY', - PERSONAL_YEARLY: 'PERSONAL_YEARLY', - PRO_MONTHLY: 'PRO_MONTHLY', - PRO_YEARLY: 'PRO_YEARLY', + PERSONAL: 'PERSONAL_MONTHLY', + PRO: 'PRO_MONTHLY', LEGACY: 'LEGACY', FREE: 'FREE', }; export const PLANS_MAPPING = { - 'franz-personal-monthly': PLANS.PERSONAL_MONTHLY, - 'franz-personal-yearly': PLANS.PERSONAL_YEARLY, - 'franz-pro-monthly': PLANS.PRO_MONTHLY, - 'franz-pro-yearly': PLANS.PRO_YEARLY, + 'franz-personal-monthly': PLANS.PERSONAL, + 'franz-personal-yearly': PLANS.PERSONAL, + 'franz-pro-monthly': PLANS.PRO, + 'franz-pro-yearly': PLANS.PRO, 'franz-supporter-license': PLANS.LEGACY, 'franz-supporter-license-x1': PLANS.LEGACY, 'franz-supporter-license-x2': PLANS.LEGACY, diff --git a/src/helpers/plan-helpers.js b/src/helpers/plan-helpers.js index 37a4457af..19392585e 100644 --- a/src/helpers/plan-helpers.js +++ b/src/helpers/plan-helpers.js @@ -2,21 +2,13 @@ import { defineMessages } from 'react-intl'; import { PLANS_MAPPING, PLANS } from '../config'; const messages = defineMessages({ - [PLANS.PRO_YEARLY]: { - id: 'pricing.plan.pro-yearly', - defaultMessage: '!!!Franz Professional Yearly', + [PLANS.PRO]: { + id: 'pricing.plan.pro', + defaultMessage: '!!!Franz Professional', }, - [PLANS.PRO_MONTHLY]: { - id: 'pricing.plan.pro-monthly', - defaultMessage: '!!!Franz Professional Monthly', - }, - [PLANS.PERSONAL_YEARLY]: { - id: 'pricing.plan.personal-yearly', - defaultMessage: '!!!Franz Personal Yearly', - }, - [PLANS.PERSONAL_MONTHLY]: { - id: 'pricing.plan.personal-monthly', - defaultMessage: '!!!Franz Personal Monthly', + [PLANS.PERSONAL]: { + id: 'pricing.plan.personal', + defaultMessage: '!!!Franz Personal', }, [PLANS.FREE]: { id: 'pricing.plan.free', diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index cd1e39543..a4c828f92 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -122,10 +122,8 @@ "pricing.features.workspaces": "Workspaces", "pricing.plan.free": "Franz Free", "pricing.plan.legacy": "Franz Premium", - "pricing.plan.personal-monthly": "Franz Personal Monthly", - "pricing.plan.personal-yearly": "Franz Personal Yearly", - "pricing.plan.pro-monthly": "Franz Professional Monthly", - "pricing.plan.pro-yearly": "Franz Professional Yearly", + "pricing.plan.personal": "Franz Personal", + "pricing.plan.pro": "Franz Professional", "pricing.trial.cta.accept": "Yes, upgrade my account to Franz Professional", "pricing.trial.cta.skip": "Continue to Franz", "pricing.trial.error": "Sorry, we could not activate your trial!", diff --git a/src/i18n/messages/src/helpers/plan-helpers.json b/src/i18n/messages/src/helpers/plan-helpers.json index de27dfcfd..df8ee19e3 100644 --- a/src/i18n/messages/src/helpers/plan-helpers.json +++ b/src/i18n/messages/src/helpers/plan-helpers.json @@ -1,11 +1,11 @@ [ { - "id": "pricing.plan.pro-yearly", - "defaultMessage": "!!!Franz Professional Yearly", + "id": "pricing.plan.pro", + "defaultMessage": "!!!Franz Professional", "file": "src/helpers/plan-helpers.js", "start": { "line": 5, - "column": 22 + "column": 15 }, "end": { "line": 8, @@ -13,54 +13,28 @@ } }, { - "id": "pricing.plan.pro-monthly", - "defaultMessage": "!!!Franz Professional Monthly", + "id": "pricing.plan.personal", + "defaultMessage": "!!!Franz Personal", "file": "src/helpers/plan-helpers.js", "start": { "line": 9, - "column": 23 + "column": 20 }, "end": { "line": 12, "column": 3 } }, - { - "id": "pricing.plan.personal-yearly", - "defaultMessage": "!!!Franz Personal Yearly", - "file": "src/helpers/plan-helpers.js", - "start": { - "line": 13, - "column": 27 - }, - "end": { - "line": 16, - "column": 3 - } - }, - { - "id": "pricing.plan.personal-monthly", - "defaultMessage": "!!!Franz Personal Monthly", - "file": "src/helpers/plan-helpers.js", - "start": { - "line": 17, - "column": 28 - }, - "end": { - "line": 20, - "column": 3 - } - }, { "id": "pricing.plan.free", "defaultMessage": "!!!Franz Free", "file": "src/helpers/plan-helpers.js", "start": { - "line": 21, + "line": 13, "column": 16 }, "end": { - "line": 24, + "line": 16, "column": 3 } }, @@ -69,11 +43,11 @@ "defaultMessage": "!!!Franz Premium", "file": "src/helpers/plan-helpers.js", "start": { - "line": 25, + "line": 17, "column": 18 }, "end": { - "line": 28, + "line": 20, "column": 3 } } -- cgit v1.2.3-70-g09d2 From dd744e4d9339b56ea94598a9a5ec7eefb052bbdb Mon Sep 17 00:00:00 2001 From: FranzBot Date: Thu, 15 Aug 2019 09:36:04 +0000 Subject: Automatic i18n update (i18n.meetfranz.com) --- src/i18n/locales/cs.json | 2 +- src/i18n/locales/fr.json | 2 +- src/i18n/locales/nl.json | 114 +++++++++++++++++++++++------------------------ src/i18n/locales/sk.json | 58 ++++++++++++------------ 4 files changed, 88 insertions(+), 88 deletions(-) (limited to 'src/i18n/locales') diff --git a/src/i18n/locales/cs.json b/src/i18n/locales/cs.json index 809c5d5a8..36732b44d 100644 --- a/src/i18n/locales/cs.json +++ b/src/i18n/locales/cs.json @@ -8,7 +8,7 @@ "feature.shareFranz.action.email" : "Poslat jako e-mail", "feature.shareFranz.action.facebook" : "Sdílet na Facebooku", "feature.shareFranz.action.twitter" : "Sdílet na Twitteru", - "feature.shareFranz.headline" : "Franz is better together!", + "feature.shareFranz.headline" : "Společně je Franz ještě lepší!", "feature.shareFranz.shareText.email" : "Přidali jsme {count} služeb do Franze. Získejte zdarma aplikace pro WhatsApp, Messenger, SLack, Skype a další na www.meetfranz.com", "feature.shareFranz.shareText.twitter" : "I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com \/cc @FranzMessenger", "feature.shareFranz.text" : "Tell your friends and colleagues how awesome Franz is and help us to spread the word.", diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 9227ff28f..451247c8b 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -1,5 +1,5 @@ { - "app.errorHandler.action" : "Recharger", + "app.errorHandler.action" : "Rafraîchir", "app.errorHandler.headline" : "Une erreur s'est produite", "feature.announcements.changelog.headline" : "Changements dans Franz {version}", "feature.delayApp.action" : "Obtenez une licence de Supporter Franz", diff --git a/src/i18n/locales/nl.json b/src/i18n/locales/nl.json index a05297a64..fd80dbdb9 100644 --- a/src/i18n/locales/nl.json +++ b/src/i18n/locales/nl.json @@ -1,6 +1,6 @@ { "app.errorHandler.action" : "Herladen", - "app.errorHandler.headline" : "Er ging iets mis", + "app.errorHandler.headline" : "Er is iets mis gegaan", "feature.announcements.changelog.headline" : "Wijzigingen in Franz {version}", "feature.delayApp.action" : "Sponsor Franz", "feature.delayApp.headline" : "Sponsor Franz om wachten over te slaan", @@ -9,27 +9,27 @@ "feature.shareFranz.action.facebook" : "Deel op Facebook", "feature.shareFranz.action.twitter" : "Deel op Twitter", "feature.shareFranz.headline" : "Franz is leuker samen!", - "feature.shareFranz.shareText.email" : "Ik heb {count} diensten toegevoegd aan Franz! Download de gratis app voor Whatsapp, Messenger, Slack, Skype en co op www.meetfranz.com", - "feature.shareFranz.shareText.twitter" : "Ik heb {count} diensten toegevoegd aan Franz! Download de gratis app voor Whatsapp, Messenger, Slack, Skype en co op www.meetfranz.com \/cc @FranzMessenger", - "feature.shareFranz.text" : "Vertel je vrienden en collega's hoe geweldig Franz is en help ons om bekender te worden", - "global.api.unhealthy" : "Kan geen verbinding maken met de Franz-services", + "feature.shareFranz.shareText.email" : "Ik heb {count} services toegevoegd aan Franz! Download de gratis app voor Whatsapp, Messenger, Slack, Skype en co op www.meetfranz.com", + "feature.shareFranz.shareText.twitter" : "Ik heb {count} services toegevoegd aan Franz! Download de gratis app voor Whatsapp, Messenger, Slack, Skype en co op www.meetfranz.com \/cc @FranzMessenger", + "feature.shareFranz.text" : "Vertel je vrienden en collega's hoe geweldig Franz is en help ons om bekender te worden.", + "global.api.unhealthy" : "Kan geen verbinding maken met de Franz-services.", "global.notConnectedToTheInternet" : "U bent niet verbonden met het internet.", "global.spellchecker.useDefault" : "Gebruik systeemstandaard ({default})", "global.spellchecking.autodetect" : "Taal automatisch herkennen", "global.spellchecking.autodetect.short" : "Automatisch", - "global.spellchecking.language" : "Spelling checken", + "global.spellchecking.language" : "Taal voor spellingcontrole", "import.headline" : "Importeer uw Franz 4-services", - "import.notSupportedHeadline" : "Services die nog niet ondersteund worden in Franz 5", - "import.skip.label" : "Ik wil services handmatig toevoegen", + "import.notSupportedHeadline" : "Services die (nog) niet ondersteund worden in Franz 5", + "import.skip.label" : "Ik wil diensten handmatig toevoegen", "import.submit.label" : "Importeer services", "infobar.buttonChangelog" : "Wat is er nieuw?", "infobar.buttonInstallUpdate" : "Opnieuw opstarten & update installeren", "infobar.buttonReloadServices" : "Services opnieuw laden", "infobar.requiredRequestsFailed" : "Kan de services en gebruikersinformatie niet laden", "infobar.servicesUpdated" : "Je services zijn bijgewerkt.", - "infobar.updateAvailable" : "Er is een nieuwe update voor Franz beschikbaar.", + "infobar.updateAvailable" : "Een nieuwe update voor Franz is beschikbaar.", "invite.email.label" : "E-mailadres", - "invite.headline.friends" : "Nodig 3 van je vrienden of collega's uit", + "invite.headline.friends" : "Nodig 3 vrienden of collega's uit", "invite.name.label" : "Naam", "invite.skip.label" : "Ik wil dit later doen", "invite.submit.label" : "Uitnodigingen verzenden", @@ -62,20 +62,20 @@ "menu.edit.selectAll" : "Selecteer alles", "menu.edit.speech" : "Spraak", "menu.edit.startDictation" : "Beginnen met dicteren", - "menu.edit.startSpeaking" : "Beginnen met praten", - "menu.edit.stopSpeaking" : "Stoppen met spreken", + "menu.edit.startSpeaking" : "Begin met spreken", + "menu.edit.stopSpeaking" : "Stop met spreken", "menu.edit.undo" : "Ongedaan maken", "menu.file" : "Bestand", "menu.help" : "Hulp", "menu.help.changelog" : "Wijzigingenlogboek", "menu.help.learnMore" : "Meer informatie", - "menu.help.privacy" : "Privacy Voorwaarden", + "menu.help.privacy" : "Privacyvoorwaarden", "menu.help.support" : "Ondersteuning", "menu.help.tos" : "Servicevoorwaarden", - "menu.services" : "Diensten", - "menu.services.activatePreviousService" : "Activeer vorige dienst", - "menu.services.addNewService" : "Nieuwe dienst toevoegen", - "menu.services.setNextServiceActive" : "Activeer volgende dienst", + "menu.services" : "Services", + "menu.services.activatePreviousService" : "Activeer vorige service", + "menu.services.addNewService" : "Nieuwe service toevoegen...", + "menu.services.setNextServiceActive" : "Activeer volgende service", "menu.view" : "Weergave", "menu.view.enterFullScreen" : "Gebruik volledig scherm", "menu.view.exitFullScreen" : "Volledig scherm verlaten", @@ -101,14 +101,14 @@ "password.link.signup" : "Maak een gratis account", "password.noUser" : "Geen gebruiker bekend met dat e-mailadres", "password.submit.label" : "Verzenden", - "password.successInfo" : "Controleer alsjeblieft je e-mail", + "password.successInfo" : "Controleer je e-mail", "premiumFeature.button.upgradeAccount" : "Upgrade Account", "pricing.headline" : "Steun Franz", - "pricing.link.skipPayment" : "Ik wil de ontwikkeling van Franz niet ondersteunen.", + "pricing.link.skipPayment" : "Ik wil de ontwikkeling van Franz (nog) niet ondersteunen.", "pricing.submit.label" : "Ik wil de ontwikkeling van Franz steunen", "pricing.support.label" : "Selecteer je ondersteuningsplan", "service.crashHandler.action" : "Laad {name} opnieuw", - "service.crashHandler.autoReload" : "Ga proberen om {name} te herstellen over {seconds} seconden", + "service.crashHandler.autoReload" : "Bezig om {name} te herstellen over {seconds} seconden", "service.crashHandler.headline" : "Oh nee!", "service.crashHandler.text" : "{name} heeft een fout veroorzaakt.", "service.disabledHandler.action" : "Activeer {name}", @@ -126,8 +126,8 @@ "settings.account.accountType.premium" : "Premium Supporter Account", "settings.account.buttonSave" : "Update profiel", "settings.account.deleteAccount" : "Verwijder account", - "settings.account.deleteEmailSent" : "Je hebt een e-mail ontvangen met een link om de aanvraag tot verwijderen van het account te bevestigen. Je accountgegevens en -data kunnen niet worden teruggehaald!", - "settings.account.deleteInfo" : "Wanneer je je Franz-account niet langer wilt gebruiken, kan je je account en alle gerelateerde data hier verwijderen.", + "settings.account.deleteEmailSent" : "Je hebt een e-mail ontvangen met een link om het verwijderen van je account te bevestigen. Je accountgegevens en -data kunnen na verwijderen niet meer worden teruggehaald!", + "settings.account.deleteInfo" : "Wanneer je je Franz-account niet langer wilt gebruiken, kun je je account en alle gerelateerde data verwijderen.", "settings.account.headline" : "Account", "settings.account.headlineAccount" : "Accountinformatie", "settings.account.headlineDangerZone" : "Gevarenzone", @@ -143,20 +143,20 @@ "settings.account.tryReloadUserInfoRequest" : "Probeer opnieuw", "settings.account.userInfoRequestFailed" : "Kon gebruikersinformatie niet laden", "settings.app.buttonClearAllCache" : "Cache legen", - "settings.app.buttonInstallUpdate" : "Herstart & installeer update", + "settings.app.buttonInstallUpdate" : "Opnieuw opstarten en updates installeren", "settings.app.buttonSearchForUpdate" : "Controleer op updates", - "settings.app.cacheInfo" : "De Franz-cache gebruikt op dit moment {size} schijfruimte.", + "settings.app.cacheInfo" : "Franz gebruikt op dit moment {size} schijfruimte aan tijdelijke bestanden.", "settings.app.currentVersion" : "Huidige versie:", "settings.app.form.autoLaunchInBackground" : "Open op de achtergrond", "settings.app.form.autoLaunchOnStart" : "Open Franz bij opstarten", "settings.app.form.beta" : "Inclusief bètaversies", "settings.app.form.darkMode" : "Stap over naar de donkere kant", - "settings.app.form.enableGPUAcceleration" : "Schakel videokaart acceleratie in ", + "settings.app.form.enableGPUAcceleration" : "Schakel videokaart-acceleratie in ", "settings.app.form.enableSpellchecking" : "Zet spellingcontrole aan", - "settings.app.form.enableSystemTray" : "Toon Franz in de systeembalk", + "settings.app.form.enableSystemTray" : "Pictogram voor Franz in systeemvak tonen", "settings.app.form.language" : "Taal", - "settings.app.form.minimizeToSystemTray" : "Minimaliseer Franz naar de systeembalk", - "settings.app.form.runInBackground" : "Houd Franz op de achtergrond wanneer het venster gesloten wordt", + "settings.app.form.minimizeToSystemTray" : "Minimaliseer Franz naar systeemvak", + "settings.app.form.runInBackground" : "Houd Franz open op de achtergrond wanneer het venster gesloten wordt", "settings.app.form.showDisabledServices" : "Toon uitgeschakelde services", "settings.app.form.showMessagesBadgesWhenMuted" : "Toon badge met ongelezen berichten wanneer meldingen zijn uitgeschakeld", "settings.app.headline" : "Instellingen", @@ -165,10 +165,10 @@ "settings.app.headlineGeneral" : "Algemeen", "settings.app.headlineLanguage" : "Taal", "settings.app.headlineUpdates" : "Updates", - "settings.app.languageDisclaimer" : "Officiële vertalingen zijn in het Engels en Duits. Alle andere talen zijn beheerd door de community.", + "settings.app.languageDisclaimer" : "Franz spreekt officieel Engels en Duits. Alle andere talen worden beheerd door de community.", "settings.app.restartRequired" : "Deze wijziging heeft een herstart nodig", "settings.app.subheadlineCache" : "Cache", - "settings.app.translationHelp" : "Help ons om Franz te vertalen naar uw taal.", + "settings.app.translationHelp" : "Help ons om Franz uw taal te laten spreken.", "settings.app.updateStatusAvailable" : "Update beschikbaar, downloaden...", "settings.app.updateStatusSearching" : "Zoekt naar updates", "settings.app.updateStatusUpToDate" : "Je gebruikt de laatste versie van Franz", @@ -184,7 +184,7 @@ "settings.recipes.all" : "Alle services", "settings.recipes.dev" : "Ontwikkeling", "settings.recipes.headline" : "Beschikbare services", - "settings.recipes.missingService" : "Mist er een dienst?", + "settings.recipes.missingService" : "Mis je een service?", "settings.recipes.mostPopular" : "Meest populair", "settings.recipes.nothingFound" : "Sorry, geen service gevonden met deze zoekterm.", "settings.recipes.servicesSuccessfulAddedInfo" : "Service succesvol toegevoegd", @@ -213,7 +213,7 @@ "settings.service.form.iconUpload" : "Sleep en drop je afbeelding, of klik hier", "settings.service.form.indirectMessageInfo" : "Je ontvangt meldingen van alle nieuwe berichten in een kanaal, niet alleen @username, @channel, @here, ...", "settings.service.form.indirectMessages" : "Toon berichtenbadge voor alle nieuwe berichten", - "settings.service.form.isMutedInfo" : "Indien uitgeschakeld zullen alle meldinggeluiden en afgespeelde audio uitgeschakeld zijn", + "settings.service.form.isMutedInfo" : "Indien uitgeschakeld, worden meldingen en audio niet afgespeeld", "settings.service.form.name" : "Naam", "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy instellingen", "settings.service.form.proxy.host" : "Proxy Host\/IP", @@ -233,15 +233,15 @@ "settings.services.discoverServices" : "Ontdek services", "settings.services.headline" : "Jouw services", "settings.services.noServicesAdded" : "Je hebt nog geen services toegevoegd.", - "settings.services.servicesRequestFailed" : "Kan jouw diensten niet laden", + "settings.services.servicesRequestFailed" : "Kan jouw services niet laden", "settings.services.tooltip.isDisabled" : "Service is uitgeschakeld", - "settings.services.tooltip.isMuted" : "Alle geluiden zijn uitgeschakeld", + "settings.services.tooltip.isMuted" : "Geluid is uitgeschakeld", "settings.services.tooltip.notificationsDisabled" : "Meldingen zijn uitgeschakeld", "settings.services.updatedInfo" : "Je wijzigingen zijn opgeslagen", - "settings.team.contentHeadline" : "Franz voor groepen", - "settings.team.copy" : "Franz voor Teams geeft je de mogelijkheid om collega's uit te nodigen voor je team door hen een e-mail te sturen en hun inschrijvingen te beheren in je accountvoorkeuren. Verspil geen tijd met het instellen van inschrijvingen voor elk teamlid apart, vergeet meerdere facturen en verschillende afrekeningsperiodes - één team regeert alles!", + "settings.team.contentHeadline" : "Franz voor Teams", + "settings.team.copy" : "Franz voor Teams geeft je de mogelijkheid om collega's uit te nodigen voor je team door hen een e-mail te sturen en hun inschrijvingen te beheren in je accountvoorkeuren. Verspil geen tijd met het instellen van inschrijvingen voor elk individueel teamlid, vergeet meerdere facturen en verschillende afrekeningsperiodes - één team om alles te regelen!", "settings.team.headline" : "Team", - "settings.team.intro" : "Gebruiken jij en je team Franz? Je kunt nu Premium inschrijvingen beheren voor zoveel collega's, vrienden, of familieleden als je wilt, allemaal vanaf één account.", + "settings.team.intro" : "Gebruiken jij en je team Franz? Je kunt nu Premium inschrijvingen beheren voor zoveel collega's, vrienden, of familieleden als je wilt. En dat alles vanuit één account.", "settings.team.manageAction" : "Beheer je Team op meetfranz.com", "settings.team.upgradeAction" : "Jouw Account opwaarderen", "settings.user.form.accountType.company" : "Bedrijf", @@ -258,7 +258,7 @@ "settings.workspace.form.buttonDelete" : "Verwijder werkruimte", "settings.workspace.form.buttonSave" : "Sla werkruimte op", "settings.workspace.form.name" : "Naam", - "settings.workspace.form.servicesInWorkspaceHeadline" : "Diensten in deze werkruimte", + "settings.workspace.form.servicesInWorkspaceHeadline" : "Services in deze werkruimte", "settings.workspace.form.yourWorkspaces" : "Jouw werkruimtes", "settings.workspaces.deletedInfo" : "Werkruimte is verwijderd", "settings.workspaces.headline" : "Jouw werkplaatsen", @@ -266,11 +266,11 @@ "settings.workspaces.tryReloadWorkspaces" : "Probeer opnieuw", "settings.workspaces.updatedInfo" : "Je wijzigingen zijn opgeslagen", "settings.workspaces.workspaceFeatureHeadline" : "Less is More: Zie hier Franz Werkruimtes", - "settings.workspaces.workspaceFeatureInfo" : "Franz werkruimtes laat je aandacht geven aan wat nu belangrijk is. Maak verschillende sets van diensten aan en schakel gelijk wanneer tussen de verschillende sets.Jij beslist welke diensten je wanneer en waar nodig hebt, enkel zo kunnen wij jou helpen je focus te behouden. Of net makkelijk de switch te maken van werk naar ontspanning.", + "settings.workspaces.workspaceFeatureInfo" : "Franz werkruimtes laat je aandacht geven aan wat nu belangrijk is. Maak verschillende sets van services aan en schakel wanneer je wilt tussen de verschillende sets. Jij beslist welke services je wanneer en waar nodig hebt. Zo helpen wij jou je focus te behouden - of net zo gemakkelijk te switchen van werk naar ontspanning.", "settings.workspaces.workspacesRequestFailed" : "Kan jouw werkruimtes niet laden", "sidebar.addNewService" : "Voeg service toe", "sidebar.closeWorkspaceDrawer" : "Werkruimte pagina sluiten", - "sidebar.muteApp" : "Schakel berichten & geluid uit", + "sidebar.muteApp" : "Berichten & geluid uitschakelen", "sidebar.openWorkspaceDrawer" : "Werkruimte pagina openen", "sidebar.settings" : "Instellingen", "sidebar.unmuteApp" : "Berichten & geluid inschakelen", @@ -281,18 +281,18 @@ "signup.headline" : "Aanmelden", "signup.lastname.label" : "Achternaam", "signup.legal.info" : "Door een Franz-account aan te maken ga je akkoord met de", - "signup.legal.privacy" : "Privacy Voorwaarden", + "signup.legal.privacy" : "Privacyvoorwaarden", "signup.legal.terms" : "Gebruiksvoorwaarden", - "signup.link.login" : "Al een account? Log in!", + "signup.link.login" : "Heb je al een account? Log in!", "signup.password.label" : "Wachtwoord", "signup.submit.label" : "Account aanmaken", - "subscription.euTaxInfo" : "Bewoners binnen EU: lokale belasting kan van toepassing zijn", + "subscription.euTaxInfo" : "EU-bewoners: lokale belastingen kunnen van toepassing zijn", "subscription.features.ads" : "Geen advertenties, nooit!", - "subscription.features.comingSoon" : "komt binnenkort", + "subscription.features.comingSoon" : "Binnenkort", "subscription.features.noInterruptions" : "Geen haperingen & pop ups over upgrades", "subscription.features.onpremise.mattermost" : "Voeg op-locatie\/gehoste diensten zoals Mattermost toe", - "subscription.features.proxy" : "Proxy understeuning voor diensten", - "subscription.features.spellchecker" : "Ondersteuning voor spellingscheck", + "subscription.features.proxy" : "Proxy understeuning voor services", + "subscription.features.spellchecker" : "Ondersteuning voor spellingcontrole", "subscription.features.workspaces" : "Beheer je diensten in de werkruimtes", "subscription.includedFeatures" : "Betaald Franz Premium Supporter Account bevat", "subscription.paymentSessionError" : "Kan betaalformulier niet initialiseren", @@ -303,30 +303,30 @@ "subscriptionPopup.buttonCancel" : "Annuleer", "subscriptionPopup.buttonDone" : "Klaar", "tabs.item.deleteService" : "Verwijder service", - "tabs.item.disableAudio" : "Schakel audio uit", - "tabs.item.disableNotifications" : "Schakel meldingen uit", - "tabs.item.disableService" : "Schakel service uit", + "tabs.item.disableAudio" : "Audio uitschakelen", + "tabs.item.disableNotifications" : "Meldingen uitschakelen", + "tabs.item.disableService" : "Service uitschakelen", "tabs.item.edit" : "Bewerken", "tabs.item.enableAudio" : "Audio inschakelen", "tabs.item.enableNotification" : "Meldingen inschakelen", "tabs.item.enableService" : "Service inschakelen", "tabs.item.reload" : "Herladen", "validation.email" : "{field} is niet geldig", - "validation.minLength" : "{field} moet minimaal {length} karakters lang zijn", - "validation.oneRequired" : "Er is op zijn minst één vereist", + "validation.minLength" : "{field} dient minimaal {length} karakters lang te zijn", + "validation.oneRequired" : "Minstens één vereist", "validation.required" : "{field} is vereist", - "validation.url" : "{field} is niet een geldige URL", + "validation.url" : "{field} is geen geldige URL", "welcome.loginButton" : "Log in op je account", "welcome.signupButton" : "Maak een gratis account", "workspaceDrawer.addNewWorkspaceLabel" : "Voeg een nieuwe werkruimte toe", - "workspaceDrawer.allServices" : "Alle diensten", + "workspaceDrawer.allServices" : "Alle services", "workspaceDrawer.headline" : "Werkruimtes", "workspaceDrawer.item.contextMenuEdit" : "bewerken", - "workspaceDrawer.item.noServicesAddedYet" : "Nog geen diensten toegevoegd", + "workspaceDrawer.item.noServicesAddedYet" : "Nog geen services toegevoegd", "workspaceDrawer.premiumCtaButtonLabel" : "Maak je eerste werkruimte", "workspaceDrawer.proFeatureBadge" : "Premium feature", - "workspaceDrawer.reactivatePremiumAccountLabel" : "Heractiveer premium account", - "workspaceDrawer.workspaceFeatureInfo" : "

Franz werkruimtes laat je aandacht geven aan wat nu belangrijk is. Maak verschillende sets van diensten aan en schakel gelijk wanneer tussen de verschillende sets.<\/p>

Jij beslist welke diensten je wanneer en waar nodig hebt, enkel zo kunnen wij jou helpen je focus te behouden. Of net makkelijk de switch te maken van werk naar ontspanning.<\/p>", - "workspaceDrawer.workspacesSettingsTooltip" : "Pas werkruimte instellingen aan", + "workspaceDrawer.reactivatePremiumAccountLabel" : "Premium account heractiveren", + "workspaceDrawer.workspaceFeatureInfo" : "Franz werkruimtes laat je aandacht geven aan wat nu belangrijk is. Maak verschillende sets van services aan en schakel wanneer je wilt tussen de verschillende sets. Jij beslist welke services je wanneer en waar nodig hebt. Zo helpen wij jou je focus te behouden - of net zo gemakkelijk te switchen van werk naar ontspanning.", + "workspaceDrawer.workspacesSettingsTooltip" : "Werkruimte instellingen aanpassen", "workspaces.switchingIndicator.switchingTo" : "Overschakelen naar" } diff --git a/src/i18n/locales/sk.json b/src/i18n/locales/sk.json index 3b051e975..bd08d5e4d 100644 --- a/src/i18n/locales/sk.json +++ b/src/i18n/locales/sk.json @@ -3,15 +3,15 @@ "app.errorHandler.headline" : "Niečo sa pokazilo", "feature.announcements.changelog.headline" : "Zmeny vo Franz {version}", "feature.delayApp.action" : "Získajte licenciu pre Franz podporu", - "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", - "feature.delayApp.text" : "Franz bude pokračovať v {seconds} seundách.", + "feature.delayApp.headline" : "Prosím, kúp si licenciu Franz Supporter a nebudeš musieť čakať", + "feature.delayApp.text" : "Franz bude pokračovať v {seconds} sekundách.", "feature.shareFranz.action.email" : "Odoslať ako e-mail", "feature.shareFranz.action.facebook" : "Zdielať na Facebook-u", "feature.shareFranz.action.twitter" : "Zdieľať na Twitter-i", - "feature.shareFranz.headline" : "Franz is better together!", - "feature.shareFranz.shareText.email" : "I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", - "feature.shareFranz.shareText.twitter" : "I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com \/cc @FranzMessenger", - "feature.shareFranz.text" : "Tell your friends and colleagues how awesome Franz is and help us to spread the word.", + "feature.shareFranz.headline" : "Franz je lepší spolu!", + "feature.shareFranz.shareText.email" : "Pridali sme {count} služieb do Franz! Získajte zadarmo aplikáciu pre WhatsApp, Messenger, Slack, Skype a iné na www.meetfranz.com", + "feature.shareFranz.shareText.twitter" : "Pridal som {count} služieb do Franz! Získajte zadarmo aplikáciu pre WhatsApp, Messenger, Slack, Skype a iné na www.meetfranz.com \/cc @FranzMessenger", + "feature.shareFranz.text" : "Povedzte vašim priateľom a známym aký je Franz skvelý a pomôžte nám rozšíriť sa do sveta.", "global.api.unhealthy" : "Nedá sa pripojiť k online službám Franz", "global.notConnectedToTheInternet" : "Nie ste pripojení k internetu.", "global.spellchecker.useDefault" : "Použiť predvolené nastavenie systému ({default})", @@ -92,9 +92,9 @@ "menu.window.minimize" : "Minimalizovať", "menu.workspaces" : "Pracovný priestor", "menu.workspaces.addNewWorkspace" : "Pridať nový pracovný priestor ...", - "menu.workspaces.closeWorkspaceDrawer" : "Close workspace drawer", + "menu.workspaces.closeWorkspaceDrawer" : "Zavrieť workspace záložku", "menu.workspaces.defaultWorkspace" : "Všetky služby", - "menu.workspaces.openWorkspaceDrawer" : "Open workspace drawer", + "menu.workspaces.openWorkspaceDrawer" : "Otvoriť workspace záložku", "password.email.label" : "E-mailová adresa", "password.headline" : "Obnoviť heslo", "password.link.login" : "Prihlásiť sa do vášho účtu", @@ -117,7 +117,7 @@ "service.errorHandler.editAction" : "Upraviť {name}", "service.errorHandler.headline" : "Ale nie!", "service.errorHandler.message" : "Chyba", - "service.errorHandler.text" : "{name} has failed to load.", + "service.errorHandler.text" : "{name} sa nepodarilo načítať.", "service.webviewLoader.loading" : "Načítava", "services.getStarted" : "Začíname", "services.welcome" : "Vítajte v aplikácii Franz", @@ -266,12 +266,12 @@ "settings.workspaces.tryReloadWorkspaces" : "Skúsiť znova", "settings.workspaces.updatedInfo" : "Vaše zmeny boli uložené", "settings.workspaces.workspaceFeatureHeadline" : "Menej je viac: Predstavenie Franz Pracovné priestory", - "settings.workspaces.workspaceFeatureInfo" : "Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time. You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.", - "settings.workspaces.workspacesRequestFailed" : "Could not load your workspaces", + "settings.workspaces.workspaceFeatureInfo" : "Franz Workspace vám umožňujú sústrediť sa na to, čo je práve dôležité. Nastavte si rozličné skupiny služieb a jednoducho medzi nimi kedykoľvek prepínajte. Vy rozhodujete ktoré služby, kedy a kde potrebujete, a my vám potom vieme pomôcť sústrediť sa na prácu - alebo jednoducho prepnúť z práce na čokoľvek iné.", + "settings.workspaces.workspacesRequestFailed" : "Nebolo možné načítať vaše workspace", "sidebar.addNewService" : "Pridať novú službu", - "sidebar.closeWorkspaceDrawer" : "Close workspace drawer", + "sidebar.closeWorkspaceDrawer" : "Zavrieť workspace záložku", "sidebar.muteApp" : "Vypnúť upozornenia a zvuky", - "sidebar.openWorkspaceDrawer" : "Open workspace drawer", + "sidebar.openWorkspaceDrawer" : "Otvoriť workspace záložku", "sidebar.settings" : "Nastavenia", "sidebar.unmuteApp" : "Povoliť oznámenia a zvuky", "signup.company.label" : "Spoločnosť", @@ -289,11 +289,11 @@ "subscription.euTaxInfo" : "Pre obyvateľov EÚ: môže byť aplikovaná miestna daň", "subscription.features.ads" : "Žiadne reklamy, nikdy!", "subscription.features.comingSoon" : "už čoskoro", - "subscription.features.noInterruptions" : "No app delays & nagging to upgrade license", - "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost", - "subscription.features.proxy" : "Proxy support for services", - "subscription.features.spellchecker" : "Support for spellchecker", - "subscription.features.workspaces" : "Organize your services in workspaces", + "subscription.features.noInterruptions" : "Žiadne oneskorenia a obťažovania po aktivovaní licencie", + "subscription.features.onpremise.mattermost" : "Pridať on-premise\/hostovanú službu ako Mattermost", + "subscription.features.proxy" : "Podpora proxy pre služby", + "subscription.features.spellchecker" : "Podpora pre kontrolovanie pravopisných chýb", + "subscription.features.workspaces" : "Organizujte vaše služby vo workspace", "subscription.includedFeatures" : "Platený účet Premium Supporter Franz zahŕňa", "subscription.paymentSessionError" : "Nepodarilo sa inicializovať platbu od", "subscription.submit.label" : "Chcem podporiť vývoj aplikácie Franz", @@ -313,20 +313,20 @@ "tabs.item.reload" : "Obnoviť", "validation.email" : "{field} je neplatný", "validation.minLength" : "{field} by malo byť dlhé aspoň {length} znakov", - "validation.oneRequired" : "At least one is required", + "validation.oneRequired" : "Je nutné zadať aspoň jeden", "validation.required" : "{field} je povinné", "validation.url" : "{field} nie je platné URL", "welcome.loginButton" : "Prihlásiť sa do vášho účtu", "welcome.signupButton" : "Vytvoriť účet zdarma", - "workspaceDrawer.addNewWorkspaceLabel" : "Add new workspace", + "workspaceDrawer.addNewWorkspaceLabel" : "Pridať nový workspace", "workspaceDrawer.allServices" : "Všetky služby", - "workspaceDrawer.headline" : "Pracovný priestor", - "workspaceDrawer.item.contextMenuEdit" : "edit", - "workspaceDrawer.item.noServicesAddedYet" : "No services added yet", - "workspaceDrawer.premiumCtaButtonLabel" : "Create your first workspace", - "workspaceDrawer.proFeatureBadge" : "Premium feature", - "workspaceDrawer.reactivatePremiumAccountLabel" : "Reactivate premium account", - "workspaceDrawer.workspaceFeatureInfo" : "

Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.<\/p>

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.<\/p>", - "workspaceDrawer.workspacesSettingsTooltip" : "Edit workspaces settings", - "workspaces.switchingIndicator.switchingTo" : "Switching to" + "workspaceDrawer.headline" : "Pracovné plochy", + "workspaceDrawer.item.contextMenuEdit" : "Upraviť", + "workspaceDrawer.item.noServicesAddedYet" : "Zatiaľ žiadne služby", + "workspaceDrawer.premiumCtaButtonLabel" : "Vytvorte váš prvý workspace", + "workspaceDrawer.proFeatureBadge" : "Prémiová funkcia", + "workspaceDrawer.reactivatePremiumAccountLabel" : "Obnovte svoj prémiový účet", + "workspaceDrawer.workspaceFeatureInfo" : "

Franz Workspace vám umožňujú sústrediť sa na to, čo je práve dôležité. Nastavte si rozličné skupiny služieb a jednoducho medzi nimi kedykoľvek prepínajte.<\/p>

Vy rozhodujete ktoré služby, kedy a kde potrebujete, a my vám potom vieme pomôcť sústrediť sa na prácu - alebo jednoducho prepnúť z práce na čokoľvek iné. <\/p>", + "workspaceDrawer.workspacesSettingsTooltip" : "Upraviť nastavenia workspace", + "workspaces.switchingIndicator.switchingTo" : "Prepínanie na" } -- cgit v1.2.3-70-g09d2 From 478b5fc6574765072eafd4fa074ae832e67627bf Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Mon, 19 Aug 2019 12:11:38 +0200 Subject: Add trial / subscription handling --- .../settings/account/AccountDashboard.js | 12 +- src/components/settings/team/TeamDashboard.js | 10 +- src/components/subscription/SubscriptionForm.js | 52 ++-- src/components/subscription/SubscriptionPopup.js | 6 +- src/components/subscription/TrialForm.js | 99 ++++++ .../subscription/SubscriptionFormScreen.js | 83 ++---- .../subscription/SubscriptionPopupScreen.js | 3 +- src/features/workspaces/store.js | 4 +- src/i18n/locales/defaultMessages.json | 332 ++++++++------------- src/i18n/locales/en-US.json | 26 +- .../settings/account/AccountDashboard.json | 77 ++--- .../components/subscription/SubscriptionForm.json | 51 ++-- .../src/components/subscription/TrialForm.json | 80 +++++ src/stores/UserStore.js | 2 - 14 files changed, 423 insertions(+), 414 deletions(-) create mode 100644 src/components/subscription/TrialForm.js create mode 100644 src/i18n/messages/src/components/subscription/TrialForm.json (limited to 'src/i18n/locales') diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js index 079d50380..6d10487e8 100644 --- a/src/components/settings/account/AccountDashboard.js +++ b/src/components/settings/account/AccountDashboard.js @@ -23,10 +23,6 @@ const messages = defineMessages({ id: 'settings.account.headlineSubscription', defaultMessage: '!!!Your Subscription', }, - headlineUpgrade: { - id: 'settings.account.headlineTrialUpgrade', - defaultMessage: '!!!Get the free 14 day Franz Professional Trial', - }, headlineDangerZone: { id: 'settings.account.headlineDangerZone', defaultMessage: '!!Danger Zone', @@ -97,10 +93,8 @@ export default @observer class AccountDashboard extends Component { static propTypes = { user: MobxPropTypes.observableObject.isRequired, isLoading: PropTypes.bool.isRequired, - isLoadingPlans: PropTypes.bool.isRequired, userInfoRequestFailed: PropTypes.bool.isRequired, retryUserInfoRequest: PropTypes.func.isRequired, - onCloseSubscriptionWindow: PropTypes.func.isRequired, deleteAccount: PropTypes.func.isRequired, isLoadingDeleteAccount: PropTypes.bool.isRequired, isDeleteAccountSuccessful: PropTypes.bool.isRequired, @@ -117,10 +111,8 @@ export default @observer class AccountDashboard extends Component { const { user, isLoading, - isLoadingPlans, userInfoRequestFailed, retryUserInfoRequest, - onCloseSubscriptionWindow, deleteAccount, isLoadingDeleteAccount, isDeleteAccountSuccessful, @@ -134,7 +126,6 @@ export default @observer class AccountDashboard extends Component { if (user.team && user.team.plan) { planName = i18nPlanName(user.team.plan, intl); - console.log(planName); } return ( @@ -221,7 +212,7 @@ export default @observer class AccountDashboard extends Component { )}

- {user.isSubscriptionOwner && ( + {user.isPremium && user.isSubscriptionOwner && (

@@ -268,7 +259,6 @@ export default @observer class AccountDashboard extends Component { {!user.isPremium && (
-

{intl.formatMessage(messages.headlineUpgrade)}

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

Franz for Teams
-
)} @@ -218,7 +203,7 @@ export default @observer class AccountDashboard extends Component {

{intl.formatMessage(messages.yourLicense)}

-

+

{planName} {user.team.isTrial && ( <> @@ -226,9 +211,10 @@ export default @observer class AccountDashboard extends Component { {intl.formatMessage(messages.trial)} )} -

+

{user.team.isTrial && ( <> +

{intl.formatMessage(messages.trialEndsIn, { duration: moment.duration(moment().diff(user.team.trialEnd)).humanize(), diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 57785b74a..0270bb857 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -181,7 +181,7 @@ "settings.account.tryReloadServices": "Try again", "settings.account.tryReloadUserInfoRequest": "Try again", "settings.account.userInfoRequestFailed": "Could not load user information", - "settings.account.yourLicense": "Your license:", + "settings.account.yourLicense": "Your Franz License", "settings.app.buttonClearAllCache": "Clear cache", "settings.app.buttonInstallUpdate": "Restart & install update", "settings.app.buttonSearchForUpdate": "Check for updates", diff --git a/src/i18n/messages/src/components/settings/account/AccountDashboard.json b/src/i18n/messages/src/components/settings/account/AccountDashboard.json index 68d3e6dd1..72cf7e0f3 100644 --- a/src/i18n/messages/src/components/settings/account/AccountDashboard.json +++ b/src/i18n/messages/src/components/settings/account/AccountDashboard.json @@ -196,7 +196,7 @@ }, { "id": "settings.account.yourLicense", - "defaultMessage": "!!!Your license:", + "defaultMessage": "!!!Your Franz License:", "file": "src/components/settings/account/AccountDashboard.js", "start": { "line": 78, -- cgit v1.2.3-70-g09d2 From 9226d71efb4b8d545c7a0abd2ba6bffdd57336c9 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Wed, 28 Aug 2019 10:11:14 +0200 Subject: Update i18n files --- src/i18n/locales/defaultMessages.json | 2 +- src/i18n/locales/en-US.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/i18n/locales') diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index e3c50f259..742fc94cf 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -1434,7 +1434,7 @@ } }, { - "defaultMessage": "!!!Your license:", + "defaultMessage": "!!!Your Franz License:", "end": { "column": 3, "line": 81 diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 0270bb857..22f8f2595 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -366,4 +366,4 @@ "workspaceDrawer.workspaceFeatureInfo": "

Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

", "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", "workspaces.switchingIndicator.switchingTo": "Switching to" -} +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 88a89ea3eb88f76ff9a2b9b856db855a7e15a46c Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Mon, 2 Sep 2019 11:28:39 +0200 Subject: Remove user type from signup --- src/components/auth/Signup.js | 30 +++-------------------- src/components/subscription/TrialForm.js | 19 +++++++++++++- src/i18n/locales/en-US.json | 3 +-- src/i18n/messages/src/components/auth/Signup.json | 13 ---------- 4 files changed, 23 insertions(+), 42 deletions(-) (limited to 'src/i18n/locales') diff --git a/src/components/auth/Signup.js b/src/components/auth/Signup.js index d9b83eeb8..7724bb908 100644 --- a/src/components/auth/Signup.js +++ b/src/components/auth/Signup.js @@ -31,10 +31,10 @@ const messages = defineMessages({ id: 'signup.email.label', defaultMessage: '!!!Email address', }, - companyLabel: { - id: 'signup.company.label', - defaultMessage: '!!!Company', - }, + // companyLabel: { + // id: 'signup.company.label', + // defaultMessage: '!!!Company', + // }, passwordLabel: { id: 'signup.password.label', defaultMessage: '!!!Password', @@ -79,20 +79,6 @@ export default @observer class Signup extends Component { form = new Form({ fields: { - accountType: { - value: 'individual', - validators: [required], - options: [{ - value: 'individual', - label: 'Individual', - }, { - value: 'non-profit', - label: 'Non-Profit', - }, { - value: 'company', - label: 'Company', - }], - }, firstname: { label: this.context.intl.formatMessage(messages.firstnameLabel), value: '', @@ -108,10 +94,6 @@ export default @observer class Signup extends Component { value: '', validators: [required, email], }, - organization: { - label: this.context.intl.formatMessage(messages.companyLabel), - value: '', // TODO: make required when accountType: company - }, password: { label: this.context.intl.formatMessage(messages.passwordLabel), value: '', @@ -151,7 +133,6 @@ export default @observer class Signup extends Component { In Dev Mode your data is not persistent. Please use the live app for accesing the production API. )} -
@@ -162,9 +143,6 @@ export default @observer class Signup extends Component { showPasswordToggle scorePassword /> - {form.$('accountType').value === 'company' && ( - - )} {error.code === 'email-duplicate' && (

{intl.formatMessage(messages.emailDuplicate)}

)} diff --git a/src/components/subscription/TrialForm.js b/src/components/subscription/TrialForm.js index 81b1c713c..9fe1c93b7 100644 --- a/src/components/subscription/TrialForm.js +++ b/src/components/subscription/TrialForm.js @@ -15,6 +15,10 @@ const messages = defineMessages({ id: 'subscription.cta.activateTrial', defaultMessage: '!!!Yes, start the free Franz Professional trial', }, + allOptionsButton: { + id: 'subscription.cta.allOptions', + defaultMessage: '!!!See all options', + }, teaserHeadline: { id: 'settings.account.headlineTrialUpgrade', defaultMessage: '!!!Get the free 14 day Franz Professional Trial', @@ -39,7 +43,12 @@ const messages = defineMessages({ const styles = () => ({ activateTrialButton: { - margin: [40, 0, 50], + margin: [40, 0, 10], + }, + allOptionsButton: { + margin: [0, 0, 40], + background: 'none', + border: 'none', }, keyTerms: { marginTop: 20, @@ -50,6 +59,7 @@ export default @observer @injectSheet(styles) class TrialForm extends Component static propTypes = { activateTrial: PropTypes.func.isRequired, isActivatingTrial: PropTypes.bool.isRequired, + showAllOptions: PropTypes.func.isRequired, classes: PropTypes.object.isRequired, }; @@ -61,6 +71,7 @@ export default @observer @injectSheet(styles) class TrialForm extends Component const { isActivatingTrial, activateTrial, + showAllOptions, classes, } = this.props; const { intl } = this.context; @@ -83,6 +94,12 @@ export default @observer @injectSheet(styles) class TrialForm extends Component onClick={activateTrial} stretch /> +
)} - { - const { setTodosWebview } = this.props; - setTodosWebview(this.webview); - this.startListeningToIpcMessages(); - }} - partition="persist:todos" - preload="./features/todos/preload.js" - ref={(webview) => { this.webview = webview ? webview.view : null; }} - src={environment.TODOS_FRONTEND} - /> + {isTodosIncludedInCurrentPlan ? ( + { + const { setTodosWebview } = this.props; + setTodosWebview(this.webview); + this.startListeningToIpcMessages(); + }} + partition="persist:todos" + preload="./features/todos/preload.js" + ref={(webview) => { this.webview = webview ? webview.view : null; }} + src={environment.TODOS_FRONTEND} + /> + ) : ( + +
+ +

{intl.formatMessage(messages.premiumInfo)}

+

{intl.formatMessage(messages.rolloutInfo)}

+
+
+ )}
); diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js index d071d0677..7f3688828 100644 --- a/src/features/todos/containers/TodosScreen.js +++ b/src/features/todos/containers/TodosScreen.js @@ -1,12 +1,14 @@ import React, { Component } from 'react'; -import { observer } from 'mobx-react'; +import { observer, inject } from 'mobx-react'; +import PropTypes from 'prop-types'; +import FeaturesStore from '../../../stores/FeaturesStore'; import TodosWebview from '../components/TodosWebview'; import ErrorBoundary from '../../../components/util/ErrorBoundary'; import { TODOS_MIN_WIDTH, todosStore } from '..'; import { todoActions } from '../actions'; -@observer +@inject('stores', 'actions') @observer class TodosScreen extends Component { render() { if (!todosStore || !todosStore.isFeatureActive) { @@ -23,6 +25,8 @@ class TodosScreen extends Component { width={todosStore.width} minWidth={TODOS_MIN_WIDTH} resize={width => todoActions.resize({ width })} + isTodosIncludedInCurrentPlan={this.props.stores.features.features.isTodosIncludedInCurrentPlan || false} + upgradeAccount={() => this.props.actions.ui.openSettings({ path: 'user' })} /> ); @@ -30,3 +34,14 @@ class TodosScreen extends Component { } export default TodosScreen; + +TodosScreen.wrappedComponent.propTypes = { + stores: PropTypes.shape({ + features: PropTypes.instanceOf(FeaturesStore).isRequired, + }).isRequired, + actions: PropTypes.shape({ + ui: PropTypes.shape({ + openSettings: PropTypes.func.isRequired, + }).isRequired, + }).isRequired, +}; diff --git a/src/features/todos/store.js b/src/features/todos/store.js index acf95df0d..7da3b7f49 100644 --- a/src/features/todos/store.js +++ b/src/features/todos/store.js @@ -29,6 +29,7 @@ export default class TodoStore extends FeatureStore { } @computed get isTodosPanelVisible() { + if (this.stores.services.all.length === 0) return false; if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; return this.settings.isTodosPanelVisible; diff --git a/src/features/workspaces/components/WorkspaceDrawer.js b/src/features/workspaces/components/WorkspaceDrawer.js index 684e50dd0..e7bc0b157 100644 --- a/src/features/workspaces/components/WorkspaceDrawer.js +++ b/src/features/workspaces/components/WorkspaceDrawer.js @@ -7,6 +7,7 @@ import { H1, Icon, ProBadge } from '@meetfranz/ui'; import { Button } from '@meetfranz/forms/lib'; import ReactTooltip from 'react-tooltip'; +import { mdiPlusBox, mdiSettings } from '@mdi/js'; import WorkspaceDrawerItem from './WorkspaceDrawerItem'; import { workspaceActions } from '../actions'; import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../index'; @@ -159,7 +160,7 @@ class WorkspaceDrawer extends Component { data-tip={`${intl.formatMessage(messages.workspacesSettingsTooltip)}`} > @@ -184,7 +185,7 @@ class WorkspaceDrawer extends Component { className={classes.premiumCtaButton} buttonType="primary" label={intl.formatMessage(messages.premiumCtaButtonLabel)} - icon="mdiPlusBox" + icon={mdiPlusBox} onClick={() => { workspaceActions.openWorkspaceSettings(); gaEvent(GA_CATEGORY_WORKSPACES, 'add', 'drawerPremiumCta'); @@ -227,7 +228,7 @@ class WorkspaceDrawer extends Component { }} > diff --git a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js index c4a800a7b..a70d1d66f 100644 --- a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js +++ b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js @@ -21,11 +21,8 @@ const styles = theme => ({ alignItems: 'flex-start', position: 'absolute', transition: 'width 0.5s ease', - width: '100%', - marginTop: '20px', - }, - wrapperWhenDrawerIsOpen: { width: `calc(100% - ${theme.workspaces.drawer.width}px)`, + marginTop: '20px', }, component: { background: 'rgba(20, 20, 20, 0.4)', @@ -64,14 +61,13 @@ class WorkspaceSwitchingIndicator extends Component { render() { const { classes, theme } = this.props; const { intl } = this.context; - const { isSwitchingWorkspace, isWorkspaceDrawerOpen, nextWorkspace } = workspaceStore; + const { isSwitchingWorkspace, nextWorkspace } = workspaceStore; if (!isSwitchingWorkspace) return null; const nextWorkspaceName = nextWorkspace ? nextWorkspace.name : 'All services'; return (
diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index 62d56ad1f..dabe2f11f 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -3810,6 +3810,50 @@ ], "path": "src/features/shareFranz/Component.json" }, + { + "descriptors": [ + { + "defaultMessage": "!!!The Franz Todos Preview is currently only available for Franz Premium accounts.", + "end": { + "column": 3, + "line": 21 + }, + "file": "src/features/todos/components/TodosWebview.js", + "id": "feature.todos.premium.info", + "start": { + "column": 15, + "line": 18 + } + }, + { + "defaultMessage": "!!!Upgrade Account", + "end": { + "column": 3, + "line": 25 + }, + "file": "src/features/todos/components/TodosWebview.js", + "id": "feature.todos.premium.upgrade", + "start": { + "column": 14, + "line": 22 + } + }, + { + "defaultMessage": "!!!Franz Todos will be available to everyone soon.", + "end": { + "column": 3, + "line": 29 + }, + "file": "src/features/todos/components/TodosWebview.js", + "id": "feature.todos.premium.rollout", + "start": { + "column": 15, + "line": 26 + } + } + ], + "path": "src/features/todos/components/TodosWebview.json" + }, { "descriptors": [ { @@ -3943,104 +3987,104 @@ "defaultMessage": "!!!Workspaces", "end": { "column": 3, - "line": 19 + "line": 20 }, "file": "src/features/workspaces/components/WorkspaceDrawer.js", "id": "workspaceDrawer.headline", "start": { "column": 12, - "line": 16 + "line": 17 } }, { "defaultMessage": "!!!All services", "end": { "column": 3, - "line": 23 + "line": 24 }, "file": "src/features/workspaces/components/WorkspaceDrawer.js", "id": "workspaceDrawer.allServices", "start": { "column": 15, - "line": 20 + "line": 21 } }, { "defaultMessage": "!!!Workspaces settings", "end": { "column": 3, - "line": 27 + "line": 28 }, "file": "src/features/workspaces/components/WorkspaceDrawer.js", "id": "workspaceDrawer.workspacesSettingsTooltip", "start": { "column": 29, - "line": 24 + "line": 25 } }, { "defaultMessage": "!!!Info about workspace feature", "end": { "column": 3, - "line": 31 + "line": 32 }, "file": "src/features/workspaces/components/WorkspaceDrawer.js", "id": "workspaceDrawer.workspaceFeatureInfo", "start": { "column": 24, - "line": 28 + "line": 29 } }, { "defaultMessage": "!!!Create your first workspace", "end": { "column": 3, - "line": 35 + "line": 36 }, "file": "src/features/workspaces/components/WorkspaceDrawer.js", "id": "workspaceDrawer.premiumCtaButtonLabel", "start": { "column": 25, - "line": 32 + "line": 33 } }, { "defaultMessage": "!!!Reactivate premium account", "end": { "column": 3, - "line": 39 + "line": 40 }, "file": "src/features/workspaces/components/WorkspaceDrawer.js", "id": "workspaceDrawer.reactivatePremiumAccountLabel", "start": { "column": 28, - "line": 36 + "line": 37 } }, { "defaultMessage": "!!!add new workspace", "end": { "column": 3, - "line": 43 + "line": 44 }, "file": "src/features/workspaces/components/WorkspaceDrawer.js", "id": "workspaceDrawer.addNewWorkspaceLabel", "start": { "column": 24, - "line": 40 + "line": 41 } }, { "defaultMessage": "!!!Premium feature", "end": { "column": 3, - "line": 47 + "line": 48 }, "file": "src/features/workspaces/components/WorkspaceDrawer.js", "id": "workspaceDrawer.proFeatureBadge", "start": { "column": 23, - "line": 44 + "line": 45 } } ], diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 727eb2884..2bfe5a670 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -15,6 +15,9 @@ "feature.shareFranz.shareText.email": "I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", "feature.shareFranz.shareText.twitter": "I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", "feature.shareFranz.text": "Tell your friends and colleagues how awesome Franz is and help us to spread the word.", + "feature.todos.premium.info": "The Franz Todos Preview is currently only available for Franz Premium accounts.", + "feature.todos.premium.rollout": "Franz Todos will be available to everyone soon.", + "feature.todos.premium.upgrade": "Upgrade Account", "global.api.unhealthy": "Can't connect to Franz online services", "global.notConnectedToTheInternet": "You are not connected to the internet.", "global.spellchecker.useDefault": "Use System Default ({default})", @@ -371,4 +374,4 @@ "workspaceDrawer.workspaceFeatureInfo": "

Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

", "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", "workspaces.switchingIndicator.switchingTo": "Switching to" -} \ No newline at end of file +} diff --git a/src/i18n/messages/src/features/todos/components/TodosWebview.json b/src/i18n/messages/src/features/todos/components/TodosWebview.json new file mode 100644 index 000000000..2387112b4 --- /dev/null +++ b/src/i18n/messages/src/features/todos/components/TodosWebview.json @@ -0,0 +1,41 @@ +[ + { + "id": "feature.todos.premium.info", + "defaultMessage": "!!!The Franz Todos Preview is currently only available for Franz Premium accounts.", + "file": "src/features/todos/components/TodosWebview.js", + "start": { + "line": 18, + "column": 15 + }, + "end": { + "line": 21, + "column": 3 + } + }, + { + "id": "feature.todos.premium.upgrade", + "defaultMessage": "!!!Upgrade Account", + "file": "src/features/todos/components/TodosWebview.js", + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 25, + "column": 3 + } + }, + { + "id": "feature.todos.premium.rollout", + "defaultMessage": "!!!Franz Todos will be available to everyone soon.", + "file": "src/features/todos/components/TodosWebview.js", + "start": { + "line": 26, + "column": 15 + }, + "end": { + "line": 29, + "column": 3 + } + } +] \ No newline at end of file diff --git a/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json b/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json index 9f0935620..2f340f1e9 100644 --- a/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json +++ b/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Workspaces", "file": "src/features/workspaces/components/WorkspaceDrawer.js", "start": { - "line": 16, + "line": 17, "column": 12 }, "end": { - "line": 19, + "line": 20, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!All services", "file": "src/features/workspaces/components/WorkspaceDrawer.js", "start": { - "line": 20, + "line": 21, "column": 15 }, "end": { - "line": 23, + "line": 24, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Workspaces settings", "file": "src/features/workspaces/components/WorkspaceDrawer.js", "start": { - "line": 24, + "line": 25, "column": 29 }, "end": { - "line": 27, + "line": 28, "column": 3 } }, @@ -43,11 +43,11 @@ "defaultMessage": "!!!Info about workspace feature", "file": "src/features/workspaces/components/WorkspaceDrawer.js", "start": { - "line": 28, + "line": 29, "column": 24 }, "end": { - "line": 31, + "line": 32, "column": 3 } }, @@ -56,11 +56,11 @@ "defaultMessage": "!!!Create your first workspace", "file": "src/features/workspaces/components/WorkspaceDrawer.js", "start": { - "line": 32, + "line": 33, "column": 25 }, "end": { - "line": 35, + "line": 36, "column": 3 } }, @@ -69,11 +69,11 @@ "defaultMessage": "!!!Reactivate premium account", "file": "src/features/workspaces/components/WorkspaceDrawer.js", "start": { - "line": 36, + "line": 37, "column": 28 }, "end": { - "line": 39, + "line": 40, "column": 3 } }, @@ -82,11 +82,11 @@ "defaultMessage": "!!!add new workspace", "file": "src/features/workspaces/components/WorkspaceDrawer.js", "start": { - "line": 40, + "line": 41, "column": 24 }, "end": { - "line": 43, + "line": 44, "column": 3 } }, @@ -95,11 +95,11 @@ "defaultMessage": "!!!Premium feature", "file": "src/features/workspaces/components/WorkspaceDrawer.js", "start": { - "line": 44, + "line": 45, "column": 23 }, "end": { - "line": 47, + "line": 48, "column": 3 } } diff --git a/src/stores/UIStore.js b/src/stores/UIStore.js index 9680c5bcc..2c785111f 100644 --- a/src/stores/UIStore.js +++ b/src/stores/UIStore.js @@ -46,6 +46,7 @@ export default class UIStore extends Store { // Actions @action _openSettings({ path = '/settings' }) { const settingsPath = path !== '/settings' ? `/settings/${path}` : path; + console.log(settingsPath); this.stores.router.push(settingsPath); } -- cgit v1.2.3-70-g09d2 From 4a621330dde699c11b46ed2f09e90e75acacaa1a Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Wed, 4 Sep 2019 11:51:58 +0200 Subject: Update en-US.json --- src/i18n/locales/en-US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/i18n/locales') diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 2bfe5a670..32e9c743a 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -374,4 +374,4 @@ "workspaceDrawer.workspaceFeatureInfo": "

Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

", "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", "workspaces.switchingIndicator.switchingTo": "Switching to" -} +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From c6dda35baf7eb9a7d89bf224c38973a1b6171c14 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Wed, 4 Sep 2019 15:37:56 +0200 Subject: bugfixing & polishing --- packages/theme/src/themes/dark/index.ts | 2 + packages/theme/src/themes/default/index.ts | 2 + src/assets/images/workspaces/teaser_dark.png | Bin 0 -> 179047 bytes src/assets/images/workspaces/teaser_light.png | Bin 0 -> 182321 bytes .../settings/account/AccountDashboard.js | 19 ++- .../settings/recipes/RecipesDashboard.js | 4 +- src/components/subscription/TrialForm.js | 3 +- src/components/ui/ActivateTrialButton/index.js | 115 ++++++++++++++++++ src/components/ui/FeatureItem.js | 2 +- src/components/ui/PremiumFeatureContainer/index.js | 22 +++- src/config.js | 4 +- src/containers/settings/AccountScreen.js | 1 + src/features/todos/components/TodosWebview.js | 14 +-- src/features/todos/containers/TodosScreen.js | 6 - src/features/todos/store.js | 3 +- .../workspaces/components/WorkspacesDashboard.js | 50 ++++++-- src/features/workspaces/store.js | 5 +- src/helpers/plan-helpers.js | 10 ++ src/i18n/locales/defaultMessages.json | 133 +++++++++++++++------ src/i18n/locales/en-US.json | 2 + .../components/ui/ActivateTrialButton/index.json | 54 +++++++++ .../ui/PremiumFeatureContainer/index.json | 4 +- .../features/todos/components/TodosWebview.json | 12 +- .../workspaces/components/WorkspacesDashboard.json | 32 ++--- src/stores/UserStore.js | 22 ++++ 25 files changed, 415 insertions(+), 106 deletions(-) create mode 100644 src/assets/images/workspaces/teaser_dark.png create mode 100644 src/assets/images/workspaces/teaser_light.png create mode 100644 src/components/ui/ActivateTrialButton/index.js create mode 100644 src/i18n/messages/src/components/ui/ActivateTrialButton/index.json (limited to 'src/i18n/locales') diff --git a/packages/theme/src/themes/dark/index.ts b/packages/theme/src/themes/dark/index.ts index 93c18efde..e94f54c55 100644 --- a/packages/theme/src/themes/dark/index.ts +++ b/packages/theme/src/themes/dark/index.ts @@ -11,6 +11,8 @@ export const colorBackgroundSubscriptionContainer = legacyStyles.themeBrandInfo; export const colorHeadline = legacyStyles.darkThemeTextColor; export const colorText = legacyStyles.darkThemeTextColor; +export const defaultContentBorder = legacyStyles.themeGrayDark; + // Loader export const colorFullscreenLoaderSpinner = '#FFF'; export const colorWebviewLoaderBackground = color(legacyStyles.darkThemeGrayDarkest).alpha(0.5).rgb().string(); diff --git a/packages/theme/src/themes/default/index.ts b/packages/theme/src/themes/default/index.ts index 7edf8331f..4e042afce 100644 --- a/packages/theme/src/themes/default/index.ts +++ b/packages/theme/src/themes/default/index.ts @@ -28,6 +28,8 @@ export const colorHeadline = legacyStyles.themeGrayDark; export const colorText = legacyStyles.themeTextColor; +export const defaultContentBorder = color(legacyStyles.themeGrayLighter).darken(0.1).rgb().string(); + // Subscription Container Component export const colorSubscriptionContainerBackground = 'none'; export const colorSubscriptionContainerBorder = `1px solid ${brandPrimary}`; diff --git a/src/assets/images/workspaces/teaser_dark.png b/src/assets/images/workspaces/teaser_dark.png new file mode 100644 index 000000000..5b6d7334b Binary files /dev/null and b/src/assets/images/workspaces/teaser_dark.png differ diff --git a/src/assets/images/workspaces/teaser_light.png b/src/assets/images/workspaces/teaser_light.png new file mode 100644 index 000000000..635af43fa Binary files /dev/null and b/src/assets/images/workspaces/teaser_light.png differ diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js index 900a83a78..4fd1e8163 100644 --- a/src/components/settings/account/AccountDashboard.js +++ b/src/components/settings/account/AccountDashboard.js @@ -93,9 +93,11 @@ const messages = defineMessages({ }, }); -export default @observer class AccountDashboard extends Component { +@observer +class AccountDashboard extends Component { static propTypes = { user: MobxPropTypes.observableObject.isRequired, + isProUser: PropTypes.bool.isRequired, isLoading: PropTypes.bool.isRequired, userInfoRequestFailed: PropTypes.bool.isRequired, retryUserInfoRequest: PropTypes.func.isRequired, @@ -115,6 +117,7 @@ export default @observer class AccountDashboard extends Component { render() { const { user, + isProUser, isLoading, userInfoRequestFailed, retryUserInfoRequest, @@ -234,11 +237,13 @@ export default @observer class AccountDashboard extends Component { )}
-
diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js index 7f3688828..65afc985b 100644 --- a/src/features/todos/containers/TodosScreen.js +++ b/src/features/todos/containers/TodosScreen.js @@ -26,7 +26,6 @@ class TodosScreen extends Component { minWidth={TODOS_MIN_WIDTH} resize={width => todoActions.resize({ width })} isTodosIncludedInCurrentPlan={this.props.stores.features.features.isTodosIncludedInCurrentPlan || false} - upgradeAccount={() => this.props.actions.ui.openSettings({ path: 'user' })} /> ); @@ -39,9 +38,4 @@ TodosScreen.wrappedComponent.propTypes = { stores: PropTypes.shape({ features: PropTypes.instanceOf(FeaturesStore).isRequired, }).isRequired, - actions: PropTypes.shape({ - ui: PropTypes.shape({ - openSettings: PropTypes.func.isRequired, - }).isRequired, - }).isRequired, }; diff --git a/src/features/todos/store.js b/src/features/todos/store.js index 7da3b7f49..56e117c6c 100644 --- a/src/features/todos/store.js +++ b/src/features/todos/store.js @@ -12,6 +12,7 @@ import { createReactions } from '../../stores/lib/Reaction'; import { createActionBindings } from '../utils/ActionBinding'; import { DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH, DEFAULT_TODOS_VISIBLE } from '.'; import { IPC } from './constants'; +import { state as delayAppState } from '../delayApp'; const debug = require('debug')('Franz:feature:todos:store'); @@ -29,7 +30,7 @@ export default class TodoStore extends FeatureStore { } @computed get isTodosPanelVisible() { - if (this.stores.services.all.length === 0) return false; + if (this.stores.services.all.length === 0 || delayAppState.isDelayAppScreenVisible) return false; if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; return this.settings.isTodosPanelVisible; diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js index 09c98ab8c..9e06a78e3 100644 --- a/src/features/workspaces/components/WorkspacesDashboard.js +++ b/src/features/workspaces/components/WorkspacesDashboard.js @@ -1,6 +1,6 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; -import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; +import { observer, PropTypes as MobxPropTypes, inject } from 'mobx-react'; import { defineMessages, intlShape } from 'react-intl'; import injectSheet from 'react-jss'; import { Infobox } from '@meetfranz/ui'; @@ -12,6 +12,8 @@ import Request from '../../../stores/lib/Request'; import Appear from '../../../components/ui/effects/Appear'; import { workspaceStore } from '../index'; import PremiumFeatureContainer from '../../../components/ui/PremiumFeatureContainer'; +import UIStore from '../../../stores/UIStore'; +import ActivateTrialButton from '../../../components/ui/activateTrialButton'; const messages = defineMessages({ headline: { @@ -62,17 +64,27 @@ const styles = theme => ({ height: 'auto', }, premiumAnnouncement: { - padding: '20px', - backgroundColor: '#3498db', - marginLeft: '-20px', - marginBottom: '20px', + padding: 20, + // backgroundColor: '#3498db', + marginLeft: -20, + marginBottom: 40, + paddingBottom: 40, height: 'auto', - color: 'white', - borderRadius: theme.borderRadius, + display: 'flex', + borderBottom: [1, 'solid', theme.inputBackground], + }, + teaserImage: { + width: 200, + height: '100%', + float: 'left', + margin: [-8, 0, 0, -20], + }, + upgradeCTA: { + marginTop: 20, }, }); -@injectSheet(styles) @observer +@inject('stores') @injectSheet(styles) @observer class WorkspacesDashboard extends Component { static propTypes = { classes: PropTypes.object.isRequired, @@ -100,7 +112,9 @@ class WorkspacesDashboard extends Component { onWorkspaceClick, workspaces, } = this.props; + const { intl } = this.context; + return (
@@ -138,13 +152,21 @@ class WorkspacesDashboard extends Component { {workspaceStore.isPremiumUpgradeRequired && (
-

{intl.formatMessage(messages.workspaceFeatureHeadline)}

-

{intl.formatMessage(messages.workspaceFeatureInfo)}

+ +
+

{intl.formatMessage(messages.workspaceFeatureHeadline)}

+

{intl.formatMessage(messages.workspaceFeatureInfo)}

+ +
)} workspaceStore.isPremiumUpgradeRequired} gaEventInfo={{ category: 'User', event: 'upgrade', label: 'workspaces' }} > {/* ===== Create workspace form ===== */} @@ -207,3 +229,9 @@ class WorkspacesDashboard extends Component { } export default WorkspacesDashboard; + +WorkspacesDashboard.wrappedComponent.propTypes = { + stores: PropTypes.shape({ + ui: PropTypes.instanceOf(UIStore).isRequired, + }).isRequired, +}; diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js index e44569be9..4a1f80b4e 100644 --- a/src/features/workspaces/store.js +++ b/src/features/workspaces/store.js @@ -253,11 +253,10 @@ export default class WorkspacesStore extends FeatureStore { }; _setIsPremiumFeatureReaction = () => { - const { features, user } = this.stores; - const { isPremium } = user.data; + const { features } = this.stores; const { isWorkspaceIncludedInCurrentPlan } = features.features; this.isPremiumFeature = !isWorkspaceIncludedInCurrentPlan; - this.isPremiumUpgradeRequired = !isWorkspaceIncludedInCurrentPlan && !isPremium; + this.isPremiumUpgradeRequired = !isWorkspaceIncludedInCurrentPlan; }; _setWorkspaceBeingEditedReaction = () => { diff --git a/src/helpers/plan-helpers.js b/src/helpers/plan-helpers.js index 19392585e..e0f1fd89a 100644 --- a/src/helpers/plan-helpers.js +++ b/src/helpers/plan-helpers.js @@ -33,3 +33,13 @@ export function i18nPlanName(planId, intl) { return intl.formatMessage(messages[plan]); } + +export function getPlan(planId) { + if (!planId) { + throw new Error('planId is required'); + } + + const plan = PLANS_MAPPING[planId]; + + return plan; +} diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index dabe2f11f..367184c01 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -2892,6 +2892,63 @@ ], "path": "src/components/TrialActivationInfoBar.json" }, + { + "descriptors": [ + { + "defaultMessage": "!!!Get a Franz Supporter License", + "end": { + "column": 3, + "line": 16 + }, + "file": "src/components/ui/ActivateTrialButton/index.js", + "id": "feature.delayApp.upgrade.action", + "start": { + "column": 10, + "line": 13 + } + }, + { + "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", + "end": { + "column": 3, + "line": 20 + }, + "file": "src/components/ui/ActivateTrialButton/index.js", + "id": "feature.delayApp.trial.action", + "start": { + "column": 15, + "line": 17 + } + }, + { + "defaultMessage": "!!!Upgrade account", + "end": { + "column": 3, + "line": 24 + }, + "file": "src/components/ui/ActivateTrialButton/index.js", + "id": "feature.delayApp.upgrade.actionShort", + "start": { + "column": 15, + "line": 21 + } + }, + { + "defaultMessage": "!!!Activate the free Franz Professional trial", + "end": { + "column": 3, + "line": 28 + }, + "file": "src/components/ui/ActivateTrialButton/index.js", + "id": "feature.delayApp.trial.actionShort", + "start": { + "column": 20, + "line": 25 + } + } + ], + "path": "src/components/ui/ActivateTrialButton/index.json" + }, { "descriptors": [ { @@ -3033,13 +3090,13 @@ "defaultMessage": "!!!Upgrade account", "end": { "column": 3, - "line": 18 + "line": 19 }, "file": "src/components/ui/PremiumFeatureContainer/index.js", "id": "premiumFeature.button.upgradeAccount", "start": { "column": 10, - "line": 15 + "line": 16 } } ], @@ -3720,91 +3777,91 @@ "defaultMessage": "!!!Franz is better together!", "end": { "column": 3, - "line": 19 + "line": 21 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.headline", "start": { "column": 12, - "line": 16 + "line": 18 } }, { "defaultMessage": "!!!Tell your friends and colleagues how awesome Franz is and help us to spread the word.", "end": { "column": 3, - "line": 23 + "line": 25 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.text", "start": { "column": 8, - "line": 20 + "line": 22 } }, { "defaultMessage": "!!!Share as email", "end": { "column": 3, - "line": 27 + "line": 29 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.action.email", "start": { "column": 16, - "line": 24 + "line": 26 } }, { "defaultMessage": "!!!Share on Facebook", "end": { "column": 3, - "line": 31 + "line": 33 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.action.facebook", "start": { "column": 19, - "line": 28 + "line": 30 } }, { "defaultMessage": "!!!Share on Twitter", "end": { "column": 3, - "line": 35 + "line": 37 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.action.twitter", "start": { "column": 18, - "line": 32 + "line": 34 } }, { "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", "end": { "column": 3, - "line": 39 + "line": 41 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.shareText.email", "start": { "column": 18, - "line": 36 + "line": 38 } }, { "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", "end": { "column": 3, - "line": 43 + "line": 45 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.shareText.twitter", "start": { "column": 20, - "line": 40 + "line": 42 } } ], @@ -3816,39 +3873,39 @@ "defaultMessage": "!!!The Franz Todos Preview is currently only available for Franz Premium accounts.", "end": { "column": 3, - "line": 21 + "line": 22 }, "file": "src/features/todos/components/TodosWebview.js", "id": "feature.todos.premium.info", "start": { "column": 15, - "line": 18 + "line": 19 } }, { "defaultMessage": "!!!Upgrade Account", "end": { "column": 3, - "line": 25 + "line": 26 }, "file": "src/features/todos/components/TodosWebview.js", "id": "feature.todos.premium.upgrade", "start": { "column": 14, - "line": 22 + "line": 23 } }, { "defaultMessage": "!!!Franz Todos will be available to everyone soon.", "end": { "column": 3, - "line": 29 + "line": 30 }, "file": "src/features/todos/components/TodosWebview.js", "id": "feature.todos.premium.rollout", "start": { "column": 15, - "line": 26 + "line": 27 } } ], @@ -4127,104 +4184,104 @@ "defaultMessage": "!!!Your workspaces", "end": { "column": 3, - "line": 20 + "line": 22 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.headline", "start": { "column": 12, - "line": 17 + "line": 19 } }, { "defaultMessage": "!!!You haven't added any workspaces yet.", "end": { "column": 3, - "line": 24 + "line": 26 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.noWorkspacesAdded", "start": { "column": 19, - "line": 21 + "line": 23 } }, { "defaultMessage": "!!!Could not load your workspaces", "end": { "column": 3, - "line": 28 + "line": 30 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.workspacesRequestFailed", "start": { "column": 27, - "line": 25 + "line": 27 } }, { "defaultMessage": "!!!Try again", "end": { "column": 3, - "line": 32 + "line": 34 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.tryReloadWorkspaces", "start": { "column": 23, - "line": 29 + "line": 31 } }, { "defaultMessage": "!!!Your changes have been saved", "end": { "column": 3, - "line": 36 + "line": 38 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.updatedInfo", "start": { "column": 15, - "line": 33 + "line": 35 } }, { "defaultMessage": "!!!Workspace has been deleted", "end": { "column": 3, - "line": 40 + "line": 42 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.deletedInfo", "start": { "column": 15, - "line": 37 + "line": 39 } }, { "defaultMessage": "!!!Info about workspace feature", "end": { "column": 3, - "line": 44 + "line": 46 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.workspaceFeatureInfo", "start": { "column": 24, - "line": 41 + "line": 43 } }, { "defaultMessage": "!!!Less is More: Introducing Franz Workspaces", "end": { "column": 3, - "line": 48 + "line": 50 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.workspaceFeatureHeadline", "start": { "column": 28, - "line": 45 + "line": 47 } } ], diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 32e9c743a..f11d5ca91 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -5,8 +5,10 @@ "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", "feature.delayApp.text": "Franz will continue in {seconds} seconds.", "feature.delayApp.trial.action": "Yes, I want the free 14 day trial of Franz Professional", + "feature.delayApp.trial.actionShort": "Activate the free Franz Professional trial", "feature.delayApp.trial.headline": "Get the free Franz Professional 14 day trial and skip the line", "feature.delayApp.upgrade.action": "Get a Franz Supporter License", + "feature.delayApp.upgrade.actionShort": "Upgrade account", "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.", "feature.shareFranz.action.email": "Send as email", "feature.shareFranz.action.facebook": "Share on Facebook", diff --git a/src/i18n/messages/src/components/ui/ActivateTrialButton/index.json b/src/i18n/messages/src/components/ui/ActivateTrialButton/index.json new file mode 100644 index 000000000..08c1a9293 --- /dev/null +++ b/src/i18n/messages/src/components/ui/ActivateTrialButton/index.json @@ -0,0 +1,54 @@ +[ + { + "id": "feature.delayApp.upgrade.action", + "defaultMessage": "!!!Get a Franz Supporter License", + "file": "src/components/ui/ActivateTrialButton/index.js", + "start": { + "line": 13, + "column": 10 + }, + "end": { + "line": 16, + "column": 3 + } + }, + { + "id": "feature.delayApp.trial.action", + "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", + "file": "src/components/ui/ActivateTrialButton/index.js", + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 20, + "column": 3 + } + }, + { + "id": "feature.delayApp.upgrade.actionShort", + "defaultMessage": "!!!Upgrade account", + "file": "src/components/ui/ActivateTrialButton/index.js", + "start": { + "line": 21, + "column": 15 + }, + "end": { + "line": 24, + "column": 3 + } + }, + { + "id": "feature.delayApp.trial.actionShort", + "defaultMessage": "!!!Activate the free Franz Professional trial", + "file": "src/components/ui/ActivateTrialButton/index.js", + "start": { + "line": 25, + "column": 20 + }, + "end": { + "line": 28, + "column": 3 + } + } +] \ No newline at end of file diff --git a/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json b/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json index 320d3ca3e..0cde4cee5 100644 --- a/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json +++ b/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Upgrade account", "file": "src/components/ui/PremiumFeatureContainer/index.js", "start": { - "line": 15, + "line": 16, "column": 10 }, "end": { - "line": 18, + "line": 19, "column": 3 } } diff --git a/src/i18n/messages/src/features/todos/components/TodosWebview.json b/src/i18n/messages/src/features/todos/components/TodosWebview.json index 2387112b4..7d26342b7 100644 --- a/src/i18n/messages/src/features/todos/components/TodosWebview.json +++ b/src/i18n/messages/src/features/todos/components/TodosWebview.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!The Franz Todos Preview is currently only available for Franz Premium accounts.", "file": "src/features/todos/components/TodosWebview.js", "start": { - "line": 18, + "line": 19, "column": 15 }, "end": { - "line": 21, + "line": 22, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!Upgrade Account", "file": "src/features/todos/components/TodosWebview.js", "start": { - "line": 22, + "line": 23, "column": 14 }, "end": { - "line": 25, + "line": 26, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Franz Todos will be available to everyone soon.", "file": "src/features/todos/components/TodosWebview.js", "start": { - "line": 26, + "line": 27, "column": 15 }, "end": { - "line": 29, + "line": 30, "column": 3 } } diff --git a/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json b/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json index ef8f1bebc..7eb4fab50 100644 --- a/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json +++ b/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Your workspaces", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 17, + "line": 19, "column": 12 }, "end": { - "line": 20, + "line": 22, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!You haven't added any workspaces yet.", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 21, + "line": 23, "column": 19 }, "end": { - "line": 24, + "line": 26, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Could not load your workspaces", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 25, + "line": 27, "column": 27 }, "end": { - "line": 28, + "line": 30, "column": 3 } }, @@ -43,11 +43,11 @@ "defaultMessage": "!!!Try again", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 29, + "line": 31, "column": 23 }, "end": { - "line": 32, + "line": 34, "column": 3 } }, @@ -56,11 +56,11 @@ "defaultMessage": "!!!Your changes have been saved", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 33, + "line": 35, "column": 15 }, "end": { - "line": 36, + "line": 38, "column": 3 } }, @@ -69,11 +69,11 @@ "defaultMessage": "!!!Workspace has been deleted", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 37, + "line": 39, "column": 15 }, "end": { - "line": 40, + "line": 42, "column": 3 } }, @@ -82,11 +82,11 @@ "defaultMessage": "!!!Info about workspace feature", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 41, + "line": 43, "column": 24 }, "end": { - "line": 44, + "line": 46, "column": 3 } }, @@ -95,11 +95,11 @@ "defaultMessage": "!!!Less is More: Introducing Franz Workspaces", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 45, + "line": 47, "column": 28 }, "end": { - "line": 48, + "line": 50, "column": 3 } } diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js index f3dfbdbf0..7ac7d2375 100644 --- a/src/stores/UserStore.js +++ b/src/stores/UserStore.js @@ -10,6 +10,8 @@ import Request from './lib/Request'; import CachedRequest from './lib/CachedRequest'; import { gaEvent } from '../lib/analytics'; import { sleep } from '../helpers/async-helpers'; +import { getPlan } from '../helpers/plan-helpers'; +import { PLANS } from '../config'; const debug = require('debug')('Franz:UserStore'); @@ -150,10 +152,30 @@ export default class UserStore extends Store { return this.getUserInfoRequest.execute().result || {}; } + @computed get team() { + return this.data.team || null; + } + @computed get isPremium() { return !!this.data.isPremium; } + @computed get isPersonal() { + if (!this.team.plan) return false; + const plan = getPlan(this.team.plan); + + return plan === PLANS.PERSONAL; + } + + @computed get isPro() { + if (!this.team.plan && this.isPremium) return true; + + if (!this.team.plan) return false; + const plan = getPlan(this.team.plan); + + return plan === PLANS.PRO; + } + @computed get legacyServices() { return this.getLegacyServicesRequest.execute() || {}; } -- cgit v1.2.3-70-g09d2 From 24d0223fee38c36ec19d9c662579dba7d787f8b4 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Thu, 5 Sep 2019 09:49:25 +0200 Subject: polishing --- src/assets/images/workspaces/teaser_dark.png | Bin 179047 -> 0 bytes src/assets/images/workspaces/teaser_light.png | Bin 182321 -> 0 bytes src/components/settings/team/TeamDashboard.js | 62 ++++++-- src/components/ui/UpgradeButton/index.js | 90 +++++++++++ src/config.js | 2 +- src/containers/settings/TeamScreen.js | 1 + .../subscription/SubscriptionFormScreen.js | 2 +- src/environment.js | 6 +- src/features/todos/components/TodosWebview.js | 8 +- src/features/todos/store.js | 18 ++- .../workspaces/components/WorkspacesDashboard.js | 167 +++++++++++---------- .../workspaces/containers/WorkspacesScreen.js | 13 +- src/i18n/globalMessages.js | 4 + src/i18n/locales/defaultMessages.json | 67 ++++++--- src/i18n/locales/en-US.json | 4 +- .../components/settings/team/TeamDashboard.json | 24 +-- .../src/components/ui/UpgradeButton/index.json | 15 ++ src/i18n/messages/src/i18n/globalMessages.json | 13 ++ src/stores/UIStore.js | 1 - src/stores/UserStore.js | 4 +- 20 files changed, 360 insertions(+), 141 deletions(-) delete mode 100644 src/assets/images/workspaces/teaser_dark.png delete mode 100644 src/assets/images/workspaces/teaser_light.png create mode 100644 src/components/ui/UpgradeButton/index.js create mode 100644 src/i18n/messages/src/components/ui/UpgradeButton/index.json (limited to 'src/i18n/locales') diff --git a/src/assets/images/workspaces/teaser_dark.png b/src/assets/images/workspaces/teaser_dark.png deleted file mode 100644 index 5b6d7334b..000000000 Binary files a/src/assets/images/workspaces/teaser_dark.png and /dev/null differ diff --git a/src/assets/images/workspaces/teaser_light.png b/src/assets/images/workspaces/teaser_light.png deleted file mode 100644 index 635af43fa..000000000 Binary files a/src/assets/images/workspaces/teaser_light.png and /dev/null differ diff --git a/src/components/settings/team/TeamDashboard.js b/src/components/settings/team/TeamDashboard.js index 990ee52e7..51a3f375d 100644 --- a/src/components/settings/team/TeamDashboard.js +++ b/src/components/settings/team/TeamDashboard.js @@ -5,10 +5,14 @@ import { defineMessages, intlShape } from 'react-intl'; import ReactTooltip from 'react-tooltip'; import injectSheet from 'react-jss'; +import { Badge } from '@meetfranz/ui'; import Loader from '../../ui/Loader'; import Button from '../../ui/Button'; import Infobox from '../../ui/Infobox'; import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; +import globalMessages from '../../../i18n/globalMessages'; +import ActivateTrialButton from '../../ui/ActivateTrialButton'; +import UpgradeButton from '../../ui/UpgradeButton'; const messages = defineMessages({ headline: { @@ -40,6 +44,7 @@ const messages = defineMessages({ const styles = { cta: { margin: [40, 'auto'], + height: 'auto', }, container: { display: 'flex', @@ -69,6 +74,17 @@ const styles = { order: 1, }, }, + headline: { + marginBottom: 0, + }, + proRequired: { + margin: [10, 0, 40], + height: 'auto', + }, + buttonContainer: { + display: 'flex', + height: 'auto', + }, }; @@ -79,6 +95,7 @@ export default @injectSheet(styles) @observer class TeamDashboard extends Compon retryUserInfoRequest: PropTypes.func.isRequired, openTeamManagement: PropTypes.func.isRequired, classes: PropTypes.object.isRequired, + isProUser: PropTypes.bool.isRequired, }; static contextTypes = { @@ -91,6 +108,7 @@ export default @injectSheet(styles) @observer class TeamDashboard extends Compon userInfoRequestFailed, retryUserInfoRequest, openTeamManagement, + isProUser, classes, } = this.props; const { intl } = this.context; @@ -123,23 +141,35 @@ export default @injectSheet(styles) @observer class TeamDashboard extends Compon <> {!isLoading && ( <> - - <> -

{intl.formatMessage(messages.contentHeadline)}

-
-
-

{intl.formatMessage(messages.intro)}

-

{intl.formatMessage(messages.copy)}

-
- Franz for Teams + <> +

{intl.formatMessage(messages.contentHeadline)}

+ {!isProUser && ( + {intl.formatMessage(globalMessages.proRequired)} + )} +
+
+

{intl.formatMessage(messages.intro)}

+

{intl.formatMessage(messages.copy)}

- - -
+
+ {!isProUser ? ( + + ) : ( +
+ )} diff --git a/src/components/ui/UpgradeButton/index.js b/src/components/ui/UpgradeButton/index.js new file mode 100644 index 000000000..4aa494e38 --- /dev/null +++ b/src/components/ui/UpgradeButton/index.js @@ -0,0 +1,90 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { inject, observer } from 'mobx-react'; +import { defineMessages, intlShape } from 'react-intl'; +import classnames from 'classnames'; + +import { Button } from '@meetfranz/forms'; +import { gaEvent } from '../../../lib/analytics'; + +import UserStore from '../../../stores/UserStore'; +import ActivateTrialButton from '../ActivateTrialButton'; + +const messages = defineMessages({ + upgradeToPro: { + id: 'global.upgradeButton.upgradeToPro', + defaultMessage: '!!!Upgrade to Franz Professional', + }, +}); + +@inject('stores', 'actions') @observer +class UpgradeButton extends Component { + static propTypes = { + // eslint-disable-next-line + classes: PropTypes.object.isRequired, + className: PropTypes.string, + gaEventInfo: PropTypes.shape({ + category: PropTypes.string.isRequired, + event: PropTypes.string.isRequired, + label: PropTypes.string, + }), + requiresPro: PropTypes.bool, + }; + + static defaultProps = { + className: '', + gaEventInfo: null, + requiresPro: false, + } + + static contextTypes = { + intl: intlShape, + }; + + handleCTAClick() { + const { actions, gaEventInfo } = this.props; + + actions.ui.openSettings({ path: 'user' }); + if (gaEventInfo) { + const { category, event } = gaEventInfo; + gaEvent(category, event, 'Upgrade Account'); + } + } + + render() { + const { stores, requiresPro } = this.props; + const { intl } = this.context; + + const { isPremium, isPersonal } = stores.user; + + if (isPremium && isPersonal && requiresPro) { + return ( +