aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores
diff options
context:
space:
mode:
Diffstat (limited to 'src/stores')
-rw-r--r--src/stores/FeaturesStore.js18
-rw-r--r--src/stores/PaymentStore.js68
-rw-r--r--src/stores/ServicesStore.js34
-rw-r--r--src/stores/UserStore.js65
-rw-r--r--src/stores/index.js6
5 files changed, 1 insertions, 190 deletions
diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js
index 2fee9bdda..ac623c258 100644
--- a/src/stores/FeaturesStore.js
+++ b/src/stores/FeaturesStore.js
@@ -1,15 +1,12 @@
1import { 1import {
2 computed, 2 computed,
3 observable, 3 observable,
4 reaction,
5 runInAction, 4 runInAction,
6} from 'mobx'; 5} from 'mobx';
7 6
8import Store from './lib/Store'; 7import Store from './lib/Store';
9import CachedRequest from './lib/CachedRequest'; 8import CachedRequest from './lib/CachedRequest';
10 9
11import delayApp from '../features/delayApp';
12import spellchecker from '../features/spellchecker';
13import serviceProxy from '../features/serviceProxy'; 10import serviceProxy from '../features/serviceProxy';
14import basicAuth from '../features/basicAuth'; 11import basicAuth from '../features/basicAuth';
15import workspaces from '../features/workspaces'; 12import workspaces from '../features/workspaces';
@@ -19,12 +16,9 @@ import publishDebugInfo from '../features/publishDebugInfo';
19import shareFranz from '../features/shareFranz'; 16import shareFranz from '../features/shareFranz';
20import announcements from '../features/announcements'; 17import announcements from '../features/announcements';
21import settingsWS from '../features/settingsWS'; 18import settingsWS from '../features/settingsWS';
22import serviceLimit from '../features/serviceLimit';
23import communityRecipes from '../features/communityRecipes'; 19import communityRecipes from '../features/communityRecipes';
24import todos from '../features/todos'; 20import todos from '../features/todos';
25import appearance from '../features/appearance'; 21import appearance from '../features/appearance';
26import planSelection from '../features/planSelection';
27import trialStatusBar from '../features/trialStatusBar';
28 22
29import { DEFAULT_FEATURES_CONFIG } from '../config'; 23import { DEFAULT_FEATURES_CONFIG } from '../config';
30 24
@@ -43,13 +37,6 @@ export default class FeaturesStore extends Store {
43 37
44 await this.featuresRequest._promise; 38 await this.featuresRequest._promise;
45 setTimeout(this._setupFeatures.bind(this), 1); 39 setTimeout(this._setupFeatures.bind(this), 1);
46
47 // single key reaction
48 reaction(() => this.stores.user.data.isPremium, () => {
49 if (this.stores.user.isLoggedIn) {
50 this.featuresRequest.invalidate({ immediately: true });
51 }
52 });
53 } 40 }
54 41
55 @computed get anonymousFeatures() { 42 @computed get anonymousFeatures() {
@@ -80,8 +67,6 @@ export default class FeaturesStore extends Store {
80 } 67 }
81 68
82 _setupFeatures() { 69 _setupFeatures() {
83 delayApp(this.stores, this.actions);
84 spellchecker(this.stores, this.actions);
85 serviceProxy(this.stores, this.actions); 70 serviceProxy(this.stores, this.actions);
86 basicAuth(this.stores, this.actions); 71 basicAuth(this.stores, this.actions);
87 workspaces(this.stores, this.actions); 72 workspaces(this.stores, this.actions);
@@ -91,11 +76,8 @@ export default class FeaturesStore extends Store {
91 shareFranz(this.stores, this.actions); 76 shareFranz(this.stores, this.actions);
92 announcements(this.stores, this.actions); 77 announcements(this.stores, this.actions);
93 settingsWS(this.stores, this.actions); 78 settingsWS(this.stores, this.actions);
94 serviceLimit(this.stores, this.actions);
95 communityRecipes(this.stores, this.actions); 79 communityRecipes(this.stores, this.actions);
96 todos(this.stores, this.actions); 80 todos(this.stores, this.actions);
97 appearance(this.stores, this.actions); 81 appearance(this.stores, this.actions);
98 planSelection(this.stores, this.actions);
99 trialStatusBar(this.stores, this.actions);
100 } 82 }
101} 83}
diff --git a/src/stores/PaymentStore.js b/src/stores/PaymentStore.js
deleted file mode 100644
index 05bb5b3d0..000000000
--- a/src/stores/PaymentStore.js
+++ /dev/null
@@ -1,68 +0,0 @@
1import { action, observable, computed } from 'mobx';
2import { BrowserWindow, getCurrentWindow } from '@electron/remote';
3
4import Store from './lib/Store';
5import CachedRequest from './lib/CachedRequest';
6import Request from './lib/Request';
7
8export default class PaymentStore extends Store {
9 @observable plansRequest = new CachedRequest(this.api.payment, 'plans');
10
11 @observable createHostedPageRequest = new Request(this.api.payment, 'getHostedPage');
12
13 constructor(...args) {
14 super(...args);
15
16 this.actions.payment.createHostedPage.listen(this._createHostedPage.bind(this));
17 this.actions.payment.upgradeAccount.listen(this._upgradeAccount.bind(this));
18 }
19
20 @computed get plan() {
21 if (this.plansRequest.isError) {
22 return {};
23 }
24 return this.plansRequest.execute().result || {};
25 }
26
27 @action _createHostedPage({ planId }) {
28 const request = this.createHostedPageRequest.execute(planId);
29
30 return request;
31 }
32
33 @action _upgradeAccount({ planId, onCloseWindow = () => null }) {
34 let hostedPageURL = this.stores.features.features.subscribeURL;
35
36 const parsedUrl = new URL(hostedPageURL);
37 const params = new URLSearchParams(parsedUrl.search.slice(1));
38
39 params.set('plan', planId);
40
41 hostedPageURL = this.stores.user.getAuthURL(`${parsedUrl.origin}${parsedUrl.pathname}?${params.toString()}`);
42
43 const win = new BrowserWindow({
44 parent: getCurrentWindow(),
45 modal: true,
46 title: '🔒 Upgrade Your Franz Account',
47 width: 800,
48 height: window.innerHeight - 100,
49 maxWidth: 800,
50 minWidth: 600,
51 autoHideMenuBar: true,
52 webPreferences: {
53 nodeIntegration: true,
54 webviewTag: true,
55 enableRemoteModule: true,
56 contextIsolation: false,
57 },
58 });
59 win.loadURL(`file://${__dirname}/../index.html#/payment/${encodeURIComponent(hostedPageURL)}`);
60
61 win.on('closed', () => {
62 this.stores.user.getUserInfoRequest.invalidate({ immediately: true });
63 this.stores.features.featuresRequest.invalidate({ immediately: true });
64
65 onCloseWindow();
66 });
67 }
68}
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 9b69cb7c6..9521f8493 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -18,8 +18,6 @@ import { matchRoute } from '../helpers/routing-helpers';
18import { isInTimeframe } from '../helpers/schedule-helpers'; 18import { isInTimeframe } from '../helpers/schedule-helpers';
19import { getRecipeDirectory, getDevRecipeDirectory } from '../helpers/recipe-helpers'; 19import { getRecipeDirectory, getDevRecipeDirectory } from '../helpers/recipe-helpers';
20import { workspaceStore } from '../features/workspaces'; 20import { workspaceStore } from '../features/workspaces';
21import { serviceLimitStore } from '../features/serviceLimit';
22import { RESTRICTION_TYPES } from '../models/Service';
23import { KEEP_WS_LOADED_USID } from '../config'; 21import { KEEP_WS_LOADED_USID } from '../config';
24import { SPELLCHECKER_LOCALES } from '../i18n/languages'; 22import { SPELLCHECKER_LOCALES } from '../i18n/languages';
25 23
@@ -94,7 +92,6 @@ export default class ServicesStore extends Store {
94 this._saveActiveService.bind(this), 92 this._saveActiveService.bind(this),
95 this._logoutReaction.bind(this), 93 this._logoutReaction.bind(this),
96 this._handleMuteSettings.bind(this), 94 this._handleMuteSettings.bind(this),
97 this._restrictServiceAccess.bind(this),
98 this._checkForActiveService.bind(this), 95 this._checkForActiveService.bind(this),
99 ]); 96 ]);
100 97
@@ -297,8 +294,6 @@ export default class ServicesStore extends Store {
297 async _createService({ 294 async _createService({
298 recipeId, serviceData, redirect = true, skipCleanup = false, 295 recipeId, serviceData, redirect = true, skipCleanup = false,
299 }) { 296 }) {
300 if (serviceLimitStore.userHasReachedServiceLimit) return;
301
302 if (!this.stores.recipes.isInstalled(recipeId)) { 297 if (!this.stores.recipes.isInstalled(recipeId)) {
303 debug(`Recipe "${recipeId}" is not installed, installing recipe`); 298 debug(`Recipe "${recipeId}" is not installed, installing recipe`);
304 await this.stores.recipes._install({ recipeId }); 299 await this.stores.recipes._install({ recipeId });
@@ -961,35 +956,6 @@ export default class ServicesStore extends Store {
961 return serviceData; 956 return serviceData;
962 } 957 }
963 958
964 _restrictServiceAccess() {
965 const { features } = this.stores.features;
966 const { userHasReachedServiceLimit, serviceLimit } = this.stores.serviceLimit;
967
968 this.all.map((service, index) => {
969 if (userHasReachedServiceLimit) {
970 service.isServiceAccessRestricted = index >= serviceLimit;
971
972 if (service.isServiceAccessRestricted) {
973 service.restrictionType = RESTRICTION_TYPES.SERVICE_LIMIT;
974
975 debug('Restricting access to server due to service limit');
976 }
977 }
978
979 if (service.isUsingCustomUrl) {
980 service.isServiceAccessRestricted = !features.isCustomUrlIncludedInCurrentPlan;
981
982 if (service.isServiceAccessRestricted) {
983 service.restrictionType = RESTRICTION_TYPES.CUSTOM_URL;
984
985 debug('Restricting access to server due to custom url');
986 }
987 }
988
989 return service;
990 });
991 }
992
993 _checkForActiveService() { 959 _checkForActiveService() {
994 if (!this.stores.router.location || this.stores.router.location.pathname.includes('auth/signup')) { 960 if (!this.stores.router.location || this.stores.router.location.pathname.includes('auth/signup')) {
995 return; 961 return;
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js
index 7947e5a27..8a525c2ef 100644
--- a/src/stores/UserStore.js
+++ b/src/stores/UserStore.js
@@ -2,16 +2,13 @@ import { observable, computed, action } from 'mobx';
2import moment from 'moment'; 2import moment from 'moment';
3import jwt from 'jsonwebtoken'; 3import jwt from 'jsonwebtoken';
4import localStorage from 'mobx-localstorage'; 4import localStorage from 'mobx-localstorage';
5import ms from 'ms';
6import { session } from '@electron/remote'; 5import { session } from '@electron/remote';
7 6
8import { isDevMode } from '../environment'; 7import { isDevMode } from '../environment';
9import Store from './lib/Store'; 8import Store from './lib/Store';
10import Request from './lib/Request'; 9import Request from './lib/Request';
11import CachedRequest from './lib/CachedRequest'; 10import CachedRequest from './lib/CachedRequest';
12import { sleep } from '../helpers/async-helpers'; 11import { TODOS_PARTITION_ID } from '../config';
13import { getPlan } from '../helpers/plan-helpers';
14import { PLANS, TODOS_PARTITION_ID } from '../config';
15 12
16const debug = require('debug')('Ferdi:UserStore'); 13const debug = require('debug')('Ferdi:UserStore');
17 14
@@ -27,8 +24,6 @@ export default class UserStore extends Store {
27 24
28 SIGNUP_ROUTE = `${this.BASE_ROUTE}/signup`; 25 SIGNUP_ROUTE = `${this.BASE_ROUTE}/signup`;
29 26
30 PRICING_ROUTE = `${this.BASE_ROUTE}/signup/pricing`;
31
32 SETUP_ROUTE = `${this.BASE_ROUTE}/signup/setup`; 27 SETUP_ROUTE = `${this.BASE_ROUTE}/signup/setup`;
33 28
34 IMPORT_ROUTE = `${this.BASE_ROUTE}/signup/import`; 29 IMPORT_ROUTE = `${this.BASE_ROUTE}/signup/import`;
@@ -45,8 +40,6 @@ export default class UserStore extends Store {
45 40
46 @observable passwordRequest = new Request(this.api.user, 'password'); 41 @observable passwordRequest = new Request(this.api.user, 'password');
47 42
48 @observable activateTrialRequest = new Request(this.api.user, 'activateTrial');
49
50 @observable inviteRequest = new Request(this.api.user, 'invite'); 43 @observable inviteRequest = new Request(this.api.user, 'invite');
51 44
52 @observable getUserInfoRequest = new CachedRequest(this.api.user, 'getInfo'); 45 @observable getUserInfoRequest = new CachedRequest(this.api.user, 'getInfo');
@@ -71,8 +64,6 @@ export default class UserStore extends Store {
71 64
72 @observable hasCompletedSignup = false; 65 @observable hasCompletedSignup = false;
73 66
74 @observable hasActivatedTrial = false;
75
76 @observable userData = {}; 67 @observable userData = {};
77 68
78 @observable actionStatus = []; 69 @observable actionStatus = [];
@@ -93,7 +84,6 @@ export default class UserStore extends Store {
93 this.actions.user.retrievePassword.listen(this._retrievePassword.bind(this)); 84 this.actions.user.retrievePassword.listen(this._retrievePassword.bind(this));
94 this.actions.user.logout.listen(this._logout.bind(this)); 85 this.actions.user.logout.listen(this._logout.bind(this));
95 this.actions.user.signup.listen(this._signup.bind(this)); 86 this.actions.user.signup.listen(this._signup.bind(this));
96 this.actions.user.activateTrial.listen(this._activateTrial.bind(this));
97 this.actions.user.invite.listen(this._invite.bind(this)); 87 this.actions.user.invite.listen(this._invite.bind(this));
98 this.actions.user.update.listen(this._update.bind(this)); 88 this.actions.user.update.listen(this._update.bind(this));
99 this.actions.user.resetStatus.listen(this._resetStatus.bind(this)); 89 this.actions.user.resetStatus.listen(this._resetStatus.bind(this));
@@ -104,7 +94,6 @@ export default class UserStore extends Store {
104 this.registerReactions([ 94 this.registerReactions([
105 this._requireAuthenticatedUser.bind(this), 95 this._requireAuthenticatedUser.bind(this),
106 this._getUserData.bind(this), 96 this._getUserData.bind(this),
107 this._resetTrialActivationState.bind(this),
108 ]); 97 ]);
109 } 98 }
110 99
@@ -126,10 +115,6 @@ export default class UserStore extends Store {
126 return this.SIGNUP_ROUTE; 115 return this.SIGNUP_ROUTE;
127 } 116 }
128 117
129 get pricingRoute() {
130 return this.PRICING_ROUTE;
131 }
132
133 get setupRoute() { 118 get setupRoute() {
134 return this.SETUP_ROUTE; 119 return this.SETUP_ROUTE;
135 } 120 }
@@ -172,31 +157,6 @@ export default class UserStore extends Store {
172 return this.data.team || null; 157 return this.data.team || null;
173 } 158 }
174 159
175 @computed get isPremium() {
176 return true;
177 }
178
179 @computed get isPremiumOverride() {
180 return ((!this.team || !this.team.plan) && this.isPremium) || (this.team && this.team.state === 'expired' && this.isPremium);
181 }
182
183 @computed get isPersonal() {
184 if (!this.team || !this.team.plan) return false;
185 const plan = getPlan(this.team.plan);
186
187 return plan === PLANS.PERSONAL;
188 }
189
190 @computed get isPro() {
191 return true;
192 // if (this.isPremiumOverride) return true;
193
194 // if (!this.team || (!this.team.plan || this.team.state === 'expired')) return false;
195 // const plan = getPlan(this.team.plan);
196
197 // return plan === PLANS.PRO || plan === PLANS.LEGACY;
198 }
199
200 @computed get legacyServices() { 160 @computed get legacyServices() {
201 return this.getLegacyServicesRequest.execute() || {}; 161 return this.getLegacyServicesRequest.execute() || {};
202 } 162 }
@@ -244,21 +204,6 @@ export default class UserStore extends Store {
244 this.actionStatus = request.result.status || []; 204 this.actionStatus = request.result.status || [];
245 } 205 }
246 206
247 @action async _activateTrial({ planId }) {
248 debug('activate trial', planId);
249
250 this.activateTrialRequest.execute({
251 plan: planId,
252 });
253
254 await this.activateTrialRequest._promise;
255
256 this.hasActivatedTrial = true;
257
258 this.stores.features.featuresRequest.invalidate({ immediately: true });
259 this.stores.user.getUserInfoRequest.invalidate({ immediately: true });
260 }
261
262 @action async _invite({ invites }) { 207 @action async _invite({ invites }) {
263 const data = invites.filter(invite => invite.email !== ''); 208 const data = invites.filter(invite => invite.email !== '');
264 209
@@ -386,14 +331,6 @@ export default class UserStore extends Store {
386 } 331 }
387 } 332 }
388 333
389 async _resetTrialActivationState() {
390 if (this.hasActivatedTrial) {
391 await sleep(ms('12s'));
392
393 this.hasActivatedTrial = false;
394 }
395 }
396
397 // Helpers 334 // Helpers
398 _parseToken(authToken) { 335 _parseToken(authToken) {
399 try { 336 try {
diff --git a/src/stores/index.js b/src/stores/index.js
index 4eeef7982..b6e481e8a 100644
--- a/src/stores/index.js
+++ b/src/stores/index.js
@@ -6,16 +6,13 @@ import ServicesStore from './ServicesStore';
6import RecipesStore from './RecipesStore'; 6import RecipesStore from './RecipesStore';
7import RecipePreviewsStore from './RecipePreviewsStore'; 7import RecipePreviewsStore from './RecipePreviewsStore';
8import UIStore from './UIStore'; 8import UIStore from './UIStore';
9import PaymentStore from './PaymentStore';
10import NewsStore from './NewsStore'; 9import NewsStore from './NewsStore';
11import RequestStore from './RequestStore'; 10import RequestStore from './RequestStore';
12import GlobalErrorStore from './GlobalErrorStore'; 11import GlobalErrorStore from './GlobalErrorStore';
13import { workspaceStore } from '../features/workspaces'; 12import { workspaceStore } from '../features/workspaces';
14import { announcementsStore } from '../features/announcements'; 13import { announcementsStore } from '../features/announcements';
15import { serviceLimitStore } from '../features/serviceLimit';
16import { communityRecipesStore } from '../features/communityRecipes'; 14import { communityRecipesStore } from '../features/communityRecipes';
17import { todosStore } from '../features/todos'; 15import { todosStore } from '../features/todos';
18import { planSelectionStore } from '../features/planSelection';
19 16
20export default (api, actions, router) => { 17export default (api, actions, router) => {
21 const stores = {}; 18 const stores = {};
@@ -29,16 +26,13 @@ export default (api, actions, router) => {
29 recipes: new RecipesStore(stores, api, actions), 26 recipes: new RecipesStore(stores, api, actions),
30 recipePreviews: new RecipePreviewsStore(stores, api, actions), 27 recipePreviews: new RecipePreviewsStore(stores, api, actions),
31 ui: new UIStore(stores, api, actions), 28 ui: new UIStore(stores, api, actions),
32 payment: new PaymentStore(stores, api, actions),
33 news: new NewsStore(stores, api, actions), 29 news: new NewsStore(stores, api, actions),
34 requests: new RequestStore(stores, api, actions), 30 requests: new RequestStore(stores, api, actions),
35 globalError: new GlobalErrorStore(stores, api, actions), 31 globalError: new GlobalErrorStore(stores, api, actions),
36 workspaces: workspaceStore, 32 workspaces: workspaceStore,
37 announcements: announcementsStore, 33 announcements: announcementsStore,
38 serviceLimit: serviceLimitStore,
39 communityRecipes: communityRecipesStore, 34 communityRecipes: communityRecipesStore,
40 todos: todosStore, 35 todos: todosStore,
41 planSelection: planSelectionStore,
42 }); 36 });
43 // Initialize all stores 37 // Initialize all stores
44 Object.keys(stores).forEach((name) => { 38 Object.keys(stores).forEach((name) => {