From ad17ec5ccad3ceffd383f228d4529438b5a3b9a6 Mon Sep 17 00:00:00 2001
From: niu tech
Date: Fri, 12 Nov 2021 23:52:58 +0100
Subject: Adjust number of columns for Split Mode (#2208)
Co-authored-by: Vijay A
---
src/stores/ServicesStore.js | 7 +++++++
1 file changed, 7 insertions(+)
(limited to 'src/stores/ServicesStore.js')
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 926ee36f0..a34390d88 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -170,6 +170,13 @@ export default class ServicesStore extends Store {
},
);
+ reaction(
+ () => this.stores.settings.app.splitColumns,
+ () => {
+ this._shareSettingsWithServiceProcess();
+ },
+ );
+
reaction(
() => this.stores.settings.app.searchEngine,
() => {
--
cgit v1.2.3-70-g09d2
From 8e076d4763831059573abc6fa98bd67fe3b3f3dc Mon Sep 17 00:00:00 2001
From: Adrian Klaeger
Date: Sun, 14 Nov 2021 04:01:37 +0100
Subject: Fix service activation and hibernation timeout (#2224)
Fixes issue #2051
---
src/stores/ServicesStore.js | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
(limited to 'src/stores/ServicesStore.js')
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index a34390d88..16deb91c5 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -587,7 +587,10 @@ export default class ServicesStore extends Store {
const service = this.one(serviceId);
for (const s of this.all) {
- s.isActive = false;
+ if (s.isActive) {
+ s.lastUsed = Date.now();
+ s.isActive = false;
+ }
}
service.isActive = true;
this._awake({ serviceId: service.id });
@@ -624,12 +627,7 @@ export default class ServicesStore extends Store {
this.allDisplayed.length,
);
- for (const s of this.all) {
- s.isActive = false;
- }
- this.allDisplayed[nextIndex].isActive = true;
-
- this._focusActiveService();
+ this._setActive({ serviceId: this.allDisplayed[nextIndex].id });
}
@action _setActivePrev() {
@@ -639,12 +637,7 @@ export default class ServicesStore extends Store {
this.allDisplayed.length,
);
- for (const s of this.all) {
- s.isActive = false;
- }
- this.allDisplayed[prevIndex].isActive = true;
-
- this._focusActiveService();
+ this._setActive({ serviceId: this.allDisplayed[prevIndex].id });
}
@action _setUnreadMessageCount({ serviceId, count }) {
--
cgit v1.2.3-70-g09d2
From b37a6b07b39c8c7827052dc6fb97f490f1e0f514 Mon Sep 17 00:00:00 2001
From: Markus Hatvan
Date: Thu, 18 Nov 2021 17:37:45 +0100
Subject: chore: convert various files to TS (#2246)
* convert various files to TS
* removed outdated docs/example-feature folder
* turn off unicorn/no-empty-file
* update eslint config
---
.eslintrc.js | 6 +
docs/example-feature/actions.js | 10 -
docs/example-feature/api.js | 5 -
docs/example-feature/state.js | 14 -
docs/example-feature/store.js | 36 --
src/I18n.js | 42 --
src/I18n.tsx | 42 ++
src/api/server/ServerApi.js | 610 ---------------------
src/api/server/ServerApi.ts | 616 ++++++++++++++++++++++
src/api/utils/auth.ts | 2 +-
src/components/services/content/ServiceWebview.js | 12 +-
src/components/ui/Tabs/TabItem.tsx | 4 +-
src/features/communityRecipes/store.ts | 2 +-
src/features/publishDebugInfo/index.js | 19 -
src/features/publishDebugInfo/index.ts | 19 +
src/i18n/translations.ts | 24 +-
src/internal-server/database/factory.js | 1 -
src/routes.js | 98 ----
src/routes.tsx | 97 ++++
src/stores/AppStore.js | 4 +-
src/stores/ServicesStore.js | 56 +-
src/webview/lib/RecipeWebview.js | 166 ------
src/webview/lib/RecipeWebview.ts | 177 +++++++
src/webview/lib/Userscript.js | 138 -----
src/webview/lib/Userscript.ts | 107 ++++
25 files changed, 1118 insertions(+), 1189 deletions(-)
delete mode 100644 docs/example-feature/actions.js
delete mode 100644 docs/example-feature/api.js
delete mode 100644 docs/example-feature/state.js
delete mode 100644 docs/example-feature/store.js
delete mode 100644 src/I18n.js
create mode 100644 src/I18n.tsx
delete mode 100644 src/api/server/ServerApi.js
create mode 100644 src/api/server/ServerApi.ts
delete mode 100644 src/features/publishDebugInfo/index.js
create mode 100644 src/features/publishDebugInfo/index.ts
delete mode 100644 src/routes.js
create mode 100644 src/routes.tsx
delete mode 100644 src/webview/lib/RecipeWebview.js
create mode 100644 src/webview/lib/RecipeWebview.ts
delete mode 100644 src/webview/lib/Userscript.js
create mode 100644 src/webview/lib/Userscript.ts
(limited to 'src/stores/ServicesStore.js')
diff --git a/.eslintrc.js b/.eslintrc.js
index b18927381..f7ca7b620 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -83,6 +83,7 @@ module.exports = {
'react/state-in-constructor': 0,
'react/static-property-placement': 0,
'react/function-component-definition': 0,
+ 'react/jsx-no-useless-fragment': 0,
// eslint-plugin-jsx-a11y
'jsx-a11y/click-events-have-key-events': 1,
'jsx-a11y/mouse-events-have-key-events': 1,
@@ -116,6 +117,8 @@ module.exports = {
},
],
'unicorn/consistent-destructuring': 0,
+ // INFO: Turned off due to src/internal-server/database/factory.js
+ 'unicorn/no-empty-file': 0,
// eslint-plugin-prettier
'prettier/prettier': 1,
},
@@ -167,6 +170,7 @@ module.exports = {
'react/state-in-constructor': 1,
'react/sort-comp': 0,
'react/function-component-definition': 0,
+ 'react/jsx-no-useless-fragment': 0,
// eslint-plugin-jsx-a11y
'jsx-a11y/click-events-have-key-events': 1,
'jsx-a11y/no-static-element-interactions': 1,
@@ -189,6 +193,8 @@ module.exports = {
},
],
'unicorn/consistent-destructuring': 0,
+ // INFO: Turned off due to src/internal-server/database/factory.js
+ 'unicorn/no-empty-file': 0,
// eslint-plugin-prettier
'prettier/prettier': 1,
},
diff --git a/docs/example-feature/actions.js b/docs/example-feature/actions.js
deleted file mode 100644
index c4d49b708..000000000
--- a/docs/example-feature/actions.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import PropTypes from 'prop-types';
-import { createActionsFromDefinitions } from '../../src/actions/lib/actions';
-
-export const exampleFeatureActions = createActionsFromDefinitions({
- greet: {
- name: PropTypes.string.isRequired,
- },
-}, PropTypes.checkPropTypes);
-
-export default exampleFeatureActions;
diff --git a/docs/example-feature/api.js b/docs/example-feature/api.js
deleted file mode 100644
index d9c769c91..000000000
--- a/docs/example-feature/api.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default {
- async getName() {
- return Promise.resolve('Ferdi');
- },
-};
diff --git a/docs/example-feature/state.js b/docs/example-feature/state.js
deleted file mode 100644
index 676717da7..000000000
--- a/docs/example-feature/state.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import { observable } from 'mobx';
-
-const defaultState = {
- name: null,
- isFeatureActive: false,
-};
-
-export const exampleFeatureState = observable(defaultState);
-
-export function resetState() {
- Object.assign(exampleFeatureState, defaultState);
-}
-
-export default exampleFeatureState;
diff --git a/docs/example-feature/store.js b/docs/example-feature/store.js
deleted file mode 100644
index 9fc86de36..000000000
--- a/docs/example-feature/store.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import { action, observable, reaction } from 'mobx';
-import Store from '../../src/stores/lib/Store';
-import Request from '../../src/stores/lib/Request';
-
-const debug = require('debug')('Ferdi:feature:EXAMPLE_FEATURE:store');
-
-export class ExampleFeatureStore extends Store {
- @observable getNameRequest = new Request(this.api, 'getName');
-
- constructor(stores, api, actions, state) {
- super(stores, api, actions);
- this.state = state;
- }
-
- setup() {
- debug('fetching name from api');
- this.getNameRequest.execute();
-
- // Update the name on the state when the request resolved
- reaction(
- () => (
- this.getNameRequest.result
- ),
- (name) => {
- this._setName(name);
- },
- );
- }
-
- @action _setName = (name) => {
- debug('setting name', name);
- this.state.name = name;
- };
-}
-
-export default ExampleFeatureStore;
diff --git a/src/I18n.js b/src/I18n.js
deleted file mode 100644
index b10c5a94b..000000000
--- a/src/I18n.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import { Component } from 'react';
-import PropTypes from 'prop-types';
-import { inject, observer } from 'mobx-react';
-import { IntlProvider } from 'react-intl';
-
-import { oneOrManyChildElements } from './prop-types';
-import translations from './i18n/translations';
-import UserStore from './stores/UserStore';
-import AppStore from './stores/AppStore';
-
-@inject('stores')
-@observer
-class I18N extends Component {
- componentDidUpdate() {
- window['ferdi'].menu.rebuild();
- }
-
- render() {
- const { stores, children } = this.props;
- const { locale } = stores.app;
- return (
- {
- window['ferdi'].intl = intlProvider ? intlProvider.state.intl : null;
- }}
- >
- {children}
-
- );
- }
-}
-
-I18N.wrappedComponent.propTypes = {
- stores: PropTypes.shape({
- app: PropTypes.instanceOf(AppStore).isRequired,
- user: PropTypes.instanceOf(UserStore).isRequired,
- }).isRequired,
- children: oneOrManyChildElements.isRequired,
-};
-
-export default I18N;
diff --git a/src/I18n.tsx b/src/I18n.tsx
new file mode 100644
index 000000000..39b5273c1
--- /dev/null
+++ b/src/I18n.tsx
@@ -0,0 +1,42 @@
+import { Component, ReactNode } from 'react';
+import { inject, observer } from 'mobx-react';
+import { IntlProvider } from 'react-intl';
+
+import { generatedTranslations } from './i18n/translations';
+import UserStore from './stores/UserStore';
+import AppStore from './stores/AppStore';
+
+const translations = generatedTranslations();
+
+type Props = {
+ stores: {
+ app: typeof AppStore;
+ user: typeof UserStore;
+ };
+ children: ReactNode;
+};
+
+@inject('stores')
+@observer
+class I18N extends Component {
+ componentDidUpdate() {
+ window['ferdi'].menu.rebuild();
+ }
+
+ render() {
+ const { stores, children } = this.props;
+ const { locale } = stores.app;
+ return (
+ {
+ window['ferdi'].intl = intlProvider ? intlProvider.state.intl : null;
+ }}
+ >
+ {children}
+
+ );
+ }
+}
+
+export default I18N;
diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js
deleted file mode 100644
index bcc72ffdc..000000000
--- a/src/api/server/ServerApi.js
+++ /dev/null
@@ -1,610 +0,0 @@
-/* eslint-disable import/no-import-module-exports */
-/* eslint-disable global-require */
-import { join } from 'path';
-import tar from 'tar';
-import {
- readdirSync,
- statSync,
- writeFileSync,
- copySync,
- ensureDirSync,
- pathExistsSync,
- readJsonSync,
- removeSync,
-} from 'fs-extra';
-import fetch from 'electron-fetch';
-
-import ServiceModel from '../../models/Service';
-import RecipePreviewModel from '../../models/RecipePreview';
-import RecipeModel from '../../models/Recipe';
-import UserModel from '../../models/User';
-
-import { sleep } from '../../helpers/async-helpers';
-
-import { SERVER_NOT_LOADED } from '../../config';
-import { userDataRecipesPath, userDataPath } from '../../environment-remote';
-import { asarRecipesPath } from '../../helpers/asar-helpers';
-import apiBase from '../apiBase';
-import { prepareAuthRequest, sendAuthRequest } from '../utils/auth';
-
-import {
- getRecipeDirectory,
- getDevRecipeDirectory,
- loadRecipeConfig,
-} from '../../helpers/recipe-helpers';
-
-import { removeServicePartitionDirectory } from '../../helpers/service-helpers';
-
-const debug = require('debug')('Ferdi:ServerApi');
-
-module.paths.unshift(getDevRecipeDirectory(), getRecipeDirectory());
-
-export default class ServerApi {
- recipePreviews = [];
-
- recipes = [];
-
- // User
- async login(email, passwordHash) {
- const request = await sendAuthRequest(
- `${apiBase()}/auth/login`,
- {
- method: 'POST',
- headers: {
- Authorization: `Basic ${window.btoa(`${email}:${passwordHash}`)}`,
- },
- },
- false,
- );
- if (!request.ok) {
- throw request;
- }
- const u = await request.json();
-
- debug('ServerApi::login resolves', u);
- return u.token;
- }
-
- async signup(data) {
- const request = await sendAuthRequest(
- `${apiBase()}/auth/signup`,
- {
- method: 'POST',
- body: JSON.stringify(data),
- },
- false,
- );
- if (!request.ok) {
- throw request;
- }
- const u = await request.json();
-
- debug('ServerApi::signup resolves', u);
- return u.token;
- }
-
- async inviteUser(data) {
- const request = await sendAuthRequest(`${apiBase()}/invite`, {
- method: 'POST',
- body: JSON.stringify(data),
- });
- if (!request.ok) {
- throw request;
- }
-
- debug('ServerApi::inviteUser');
- return true;
- }
-
- async retrievePassword(email) {
- const request = await sendAuthRequest(
- `${apiBase()}/auth/password`,
- {
- method: 'POST',
- body: JSON.stringify({
- email,
- }),
- },
- false,
- );
- if (!request.ok) {
- throw request;
- }
- const r = await request.json();
-
- debug('ServerApi::retrievePassword');
- return r;
- }
-
- async userInfo() {
- if (apiBase() === SERVER_NOT_LOADED) {
- throw new Error('Server not loaded');
- }
-
- const request = await sendAuthRequest(`${apiBase()}/me`);
- if (!request.ok) {
- throw request;
- }
- const data = await request.json();
-
- const user = new UserModel(data);
- debug('ServerApi::userInfo resolves', user);
-
- return user;
- }
-
- async updateUserInfo(data) {
- const request = await sendAuthRequest(`${apiBase()}/me`, {
- method: 'PUT',
- body: JSON.stringify(data),
- });
- if (!request.ok) {
- throw request;
- }
- const updatedData = await request.json();
-
- const user = Object.assign(updatedData, {
- data: new UserModel(updatedData.data),
- });
- debug('ServerApi::updateUserInfo resolves', user);
- return user;
- }
-
- async deleteAccount() {
- const request = await sendAuthRequest(`${apiBase()}/me`, {
- method: 'DELETE',
- });
- if (!request.ok) {
- throw request;
- }
- const data = await request.json();
-
- debug('ServerApi::deleteAccount resolves', data);
- return data;
- }
-
- // Services
- async getServices() {
- if (apiBase() === SERVER_NOT_LOADED) {
- throw new Error('Server not loaded');
- }
-
- const request = await sendAuthRequest(`${apiBase()}/me/services`);
- if (!request.ok) {
- throw request;
- }
- const data = await request.json();
-
- const services = await this._mapServiceModels(data);
- const filteredServices = services.filter(service => !!service);
- debug('ServerApi::getServices resolves', filteredServices);
- return filteredServices;
- }
-
- async createService(recipeId, data) {
- const request = await sendAuthRequest(`${apiBase()}/service`, {
- method: 'POST',
- body: JSON.stringify({ recipeId, ...data }),
- });
- if (!request.ok) {
- throw request;
- }
- const serviceData = await request.json();
-
- if (data.iconFile) {
- const iconData = await this.uploadServiceIcon(
- serviceData.data.id,
- data.iconFile,
- );
-
- serviceData.data = iconData;
- }
-
- const service = Object.assign(serviceData, {
- data: await this._prepareServiceModel(serviceData.data),
- });
-
- debug('ServerApi::createService resolves', service);
- return service;
- }
-
- async updateService(serviceId, rawData) {
- const data = rawData;
-
- if (data.iconFile) {
- await this.uploadServiceIcon(serviceId, data.iconFile);
- }
-
- const request = await sendAuthRequest(`${apiBase()}/service/${serviceId}`, {
- method: 'PUT',
- body: JSON.stringify(data),
- });
-
- if (!request.ok) {
- throw request;
- }
-
- const serviceData = await request.json();
-
- const service = Object.assign(serviceData, {
- data: await this._prepareServiceModel(serviceData.data),
- });
-
- debug('ServerApi::updateService resolves', service);
- return service;
- }
-
- async uploadServiceIcon(serviceId, icon) {
- const formData = new FormData();
- formData.append('icon', icon);
-
- const requestData = prepareAuthRequest({
- method: 'PUT',
- body: formData,
- });
-
- delete requestData.headers['Content-Type'];
-
- const request = await window.fetch(
- `${apiBase()}/service/${serviceId}`,
- requestData,
- );
-
- if (!request.ok) {
- throw request;
- }
-
- const serviceData = await request.json();
-
- return serviceData.data;
- }
-
- async reorderService(data) {
- const request = await sendAuthRequest(`${apiBase()}/service/reorder`, {
- method: 'PUT',
- body: JSON.stringify(data),
- });
- if (!request.ok) {
- throw request;
- }
- const serviceData = await request.json();
- debug('ServerApi::reorderService resolves', serviceData);
- return serviceData;
- }
-
- async deleteService(id) {
- const request = await sendAuthRequest(`${apiBase()}/service/${id}`, {
- method: 'DELETE',
- });
- if (!request.ok) {
- throw request;
- }
- const data = await request.json();
-
- removeServicePartitionDirectory(id, true);
-
- debug('ServerApi::deleteService resolves', data);
- return data;
- }
-
- // Features
- async getDefaultFeatures() {
- const request = await sendAuthRequest(`${apiBase()}/features/default`);
- if (!request.ok) {
- throw request;
- }
- const data = await request.json();
-
- const features = data;
- debug('ServerApi::getDefaultFeatures resolves', features);
- return features;
- }
-
- async getFeatures() {
- if (apiBase() === SERVER_NOT_LOADED) {
- throw new Error('Server not loaded');
- }
-
- const request = await sendAuthRequest(`${apiBase()}/features`);
- if (!request.ok) {
- throw request;
- }
- const data = await request.json();
-
- const features = data;
- debug('ServerApi::getFeatures resolves', features);
- return features;
- }
-
- // Recipes
- async getInstalledRecipes() {
- const recipesDirectory = getRecipeDirectory();
- const paths = readdirSync(recipesDirectory).filter(
- file =>
- statSync(join(recipesDirectory, file)).isDirectory() &&
- file !== 'temp' &&
- file !== 'dev',
- );
-
- this.recipes = paths
- .map(id => {
- // eslint-disable-next-line import/no-dynamic-require
- const Recipe = require(id)(RecipeModel);
- return new Recipe(loadRecipeConfig(id));
- })
- .filter(recipe => recipe.id);
-
- // eslint-disable-next-line unicorn/prefer-spread
- this.recipes = this.recipes.concat(this._getDevRecipes());
-
- debug('StubServerApi::getInstalledRecipes resolves', this.recipes);
- return this.recipes;
- }
-
- async getRecipeUpdates(recipeVersions) {
- const request = await sendAuthRequest(`${apiBase()}/recipes/update`, {
- method: 'POST',
- body: JSON.stringify(recipeVersions),
- });
- if (!request.ok) {
- throw request;
- }
- const recipes = await request.json();
- debug('ServerApi::getRecipeUpdates resolves', recipes);
- return recipes;
- }
-
- // Recipes Previews
- async getRecipePreviews() {
- const request = await sendAuthRequest(`${apiBase()}/recipes`);
- if (!request.ok) throw request;
- const data = await request.json();
- const recipePreviews = this._mapRecipePreviewModel(data);
- debug('ServerApi::getRecipes resolves', recipePreviews);
- return recipePreviews;
- }
-
- async getFeaturedRecipePreviews() {
- // TODO: If we are hitting the internal-server, we need to return an empty list, else we can hit the remote server and get the data
- const request = await sendAuthRequest(`${apiBase()}/recipes/popular`);
- if (!request.ok) throw request;
-
- const data = await request.json();
- const recipePreviews = this._mapRecipePreviewModel(data);
- debug('ServerApi::getFeaturedRecipes resolves', recipePreviews);
- return recipePreviews;
- }
-
- async searchRecipePreviews(needle) {
- const url = `${apiBase()}/recipes/search?needle=${needle}`;
- const request = await sendAuthRequest(url);
- if (!request.ok) throw request;
-
- const data = await request.json();
- const recipePreviews = this._mapRecipePreviewModel(data);
- debug('ServerApi::searchRecipePreviews resolves', recipePreviews);
- return recipePreviews;
- }
-
- async getRecipePackage(recipeId) {
- try {
- const recipesDirectory = userDataRecipesPath();
- const recipeTempDirectory = join(recipesDirectory, 'temp', recipeId);
- const tempArchivePath = join(recipeTempDirectory, 'recipe.tar.gz');
-
- const internalRecipeFile = asarRecipesPath(`${recipeId}.tar.gz`);
-
- ensureDirSync(recipeTempDirectory);
-
- let archivePath;
-
- if (pathExistsSync(internalRecipeFile)) {
- debug('[ServerApi::getRecipePackage] Using internal recipe file');
- archivePath = internalRecipeFile;
- } else {
- debug('[ServerApi::getRecipePackage] Downloading recipe from server');
- archivePath = tempArchivePath;
-
- const packageUrl = `${apiBase()}/recipes/download/${recipeId}`;
-
- const res = await fetch(packageUrl);
- debug('Recipe downloaded', recipeId);
- const buffer = await res.buffer();
- writeFileSync(archivePath, buffer);
- }
- debug(archivePath);
-
- await sleep(10);
-
- await tar.x({
- file: archivePath,
- cwd: recipeTempDirectory,
- preservePaths: true,
- unlink: true,
- preserveOwner: false,
- onwarn: x => debug('warn', recipeId, x),
- });
-
- await sleep(10);
-
- const { id } = readJsonSync(join(recipeTempDirectory, 'package.json'));
- const recipeDirectory = join(recipesDirectory, id);
- copySync(recipeTempDirectory, recipeDirectory);
- removeSync(recipeTempDirectory);
- removeSync(join(recipesDirectory, recipeId, 'recipe.tar.gz'));
-
- return id;
- } catch (error) {
- console.error(error);
-
- return false;
- }
- }
-
- // Health Check
- async healthCheck() {
- if (apiBase() === SERVER_NOT_LOADED) {
- throw new Error('Server not loaded');
- }
-
- const request = await sendAuthRequest(
- `${apiBase(false)}/health`,
- {
- method: 'GET',
- },
- false,
- );
- if (!request.ok) {
- throw request;
- }
- debug('ServerApi::healthCheck resolves');
- }
-
- async getLegacyServices() {
- const file = userDataPath('settings', 'services.json');
-
- try {
- const config = readJsonSync(file);
-
- if (Object.prototype.hasOwnProperty.call(config, 'services')) {
- const services = await Promise.all(
- config.services.map(async s => {
- const service = s;
- const request = await sendAuthRequest(
- `${apiBase()}/recipes/${s.service}`,
- );
-
- if (request.status === 200) {
- const data = await request.json();
- service.recipe = new RecipePreviewModel(data);
- }
-
- return service;
- }),
- );
-
- debug('ServerApi::getLegacyServices resolves', services);
- return services;
- }
- } catch {
- console.error('ServerApi::getLegacyServices no config found');
- }
-
- return [];
- }
-
- // Helper
- async _mapServiceModels(services) {
- const recipes = services.map(s => s.recipeId);
- await this._bulkRecipeCheck(recipes);
- /* eslint-disable no-return-await */
- return Promise.all(
- services.map(async service => await this._prepareServiceModel(service)),
- );
- /* eslint-enable no-return-await */
- }
-
- async _prepareServiceModel(service) {
- let recipe;
- try {
- recipe = this.recipes.find(r => r.id === service.recipeId);
-
- if (!recipe) {
- console.warn(`Recipe ${service.recipeId} not loaded`);
- return null;
- }
-
- return new ServiceModel(service, recipe);
- } catch (error) {
- debug(error);
- return null;
- }
- }
-
- async _bulkRecipeCheck(unfilteredRecipes) {
- // Filter recipe duplicates as we don't need to download 3 Slack recipes
- const recipes = unfilteredRecipes.filter(
- (elem, pos, arr) => arr.indexOf(elem) === pos,
- );
-
- return Promise.all(
- recipes.map(async recipeId => {
- let recipe = this.recipes.find(r => r.id === recipeId);
-
- if (!recipe) {
- console.warn(
- `Recipe '${recipeId}' not installed, trying to fetch from server`,
- );
-
- await this.getRecipePackage(recipeId);
-
- debug('Rerun ServerAPI::getInstalledRecipes');
- await this.getInstalledRecipes();
-
- recipe = this.recipes.find(r => r.id === recipeId);
-
- if (!recipe) {
- console.warn(`Could not load recipe ${recipeId}`);
- return null;
- }
- }
-
- return recipe;
- }),
- ).catch(error => console.error("Can't load recipe", error));
- }
-
- _mapRecipePreviewModel(recipes) {
- return recipes
- .map(recipe => {
- try {
- return new RecipePreviewModel(recipe);
- } catch (error) {
- console.error(error);
- return null;
- }
- })
- .filter(recipe => recipe !== null);
- }
-
- _getDevRecipes() {
- const recipesDirectory = getDevRecipeDirectory();
- try {
- const paths = readdirSync(recipesDirectory).filter(
- file =>
- statSync(join(recipesDirectory, file)).isDirectory() &&
- file !== 'temp',
- );
-
- const recipes = paths
- .map(id => {
- let Recipe;
- try {
- // eslint-disable-next-line import/no-dynamic-require
- Recipe = require(id)(RecipeModel);
- return new Recipe(loadRecipeConfig(id));
- } catch (error) {
- console.error(error);
- }
-
- return false;
- })
- .filter(recipe => recipe.id)
- .map(data => {
- const recipe = data;
-
- recipe.icons = {
- svg: `${recipe.path}/icon.svg`,
- };
- recipe.local = true;
-
- return data;
- });
-
- return recipes;
- } catch {
- debug('Could not load dev recipes');
- return false;
- }
- }
-}
diff --git a/src/api/server/ServerApi.ts b/src/api/server/ServerApi.ts
new file mode 100644
index 000000000..2fd1a8d0d
--- /dev/null
+++ b/src/api/server/ServerApi.ts
@@ -0,0 +1,616 @@
+/* eslint-disable import/no-import-module-exports */
+/* eslint-disable global-require */
+import { join } from 'path';
+import tar from 'tar';
+import {
+ readdirSync,
+ statSync,
+ writeFileSync,
+ copySync,
+ ensureDirSync,
+ pathExistsSync,
+ readJsonSync,
+ removeSync,
+ PathOrFileDescriptor,
+} from 'fs-extra';
+import fetch from 'electron-fetch';
+
+import ServiceModel from '../../models/Service';
+import RecipePreviewModel from '../../models/RecipePreview';
+import RecipeModel from '../../models/Recipe';
+import UserModel from '../../models/User';
+
+import { sleep } from '../../helpers/async-helpers';
+
+import { SERVER_NOT_LOADED } from '../../config';
+import { userDataRecipesPath, userDataPath } from '../../environment-remote';
+import { asarRecipesPath } from '../../helpers/asar-helpers';
+import apiBase from '../apiBase';
+import { prepareAuthRequest, sendAuthRequest } from '../utils/auth';
+
+import {
+ getRecipeDirectory,
+ getDevRecipeDirectory,
+ loadRecipeConfig,
+} from '../../helpers/recipe-helpers';
+
+import { removeServicePartitionDirectory } from '../../helpers/service-helpers';
+
+const debug = require('debug')('Ferdi:ServerApi');
+
+module.paths.unshift(getDevRecipeDirectory(), getRecipeDirectory());
+
+export default class ServerApi {
+ recipePreviews: any[] = [];
+
+ recipes: any[] = [];
+
+ // User
+ async login(email: string, passwordHash: string) {
+ const request = await sendAuthRequest(
+ `${apiBase()}/auth/login`,
+ {
+ method: 'POST',
+ headers: {
+ Authorization: `Basic ${window.btoa(`${email}:${passwordHash}`)}`,
+ },
+ },
+ false,
+ );
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const u = await request.json();
+
+ debug('ServerApi::login resolves', u);
+ return u.token;
+ }
+
+ async signup(data: any) {
+ const request = await sendAuthRequest(
+ `${apiBase()}/auth/signup`,
+ {
+ method: 'POST',
+ body: JSON.stringify(data),
+ },
+ false,
+ );
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const u = await request.json();
+
+ debug('ServerApi::signup resolves', u);
+ return u.token;
+ }
+
+ async inviteUser(data: any) {
+ const request = await sendAuthRequest(`${apiBase()}/invite`, {
+ method: 'POST',
+ body: JSON.stringify(data),
+ });
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+
+ debug('ServerApi::inviteUser');
+ return true;
+ }
+
+ async retrievePassword(email: string) {
+ const request = await sendAuthRequest(
+ `${apiBase()}/auth/password`,
+ {
+ method: 'POST',
+ body: JSON.stringify({
+ email,
+ }),
+ },
+ false,
+ );
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const r = await request.json();
+
+ debug('ServerApi::retrievePassword');
+ return r;
+ }
+
+ async userInfo() {
+ if (apiBase() === SERVER_NOT_LOADED) {
+ throw new Error('Server not loaded');
+ }
+
+ const request = await sendAuthRequest(`${apiBase()}/me`);
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const data = await request.json();
+
+ const user = new UserModel(data);
+ debug('ServerApi::userInfo resolves', user);
+
+ return user;
+ }
+
+ async updateUserInfo(data: any) {
+ const request = await sendAuthRequest(`${apiBase()}/me`, {
+ method: 'PUT',
+ body: JSON.stringify(data),
+ });
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const updatedData = await request.json();
+
+ const user = Object.assign(updatedData, {
+ data: new UserModel(updatedData.data),
+ });
+ debug('ServerApi::updateUserInfo resolves', user);
+ return user;
+ }
+
+ async deleteAccount() {
+ const request = await sendAuthRequest(`${apiBase()}/me`, {
+ method: 'DELETE',
+ });
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const data = await request.json();
+
+ debug('ServerApi::deleteAccount resolves', data);
+ return data;
+ }
+
+ // Services
+ async getServices() {
+ if (apiBase() === SERVER_NOT_LOADED) {
+ throw new Error('Server not loaded');
+ }
+
+ const request = await sendAuthRequest(`${apiBase()}/me/services`);
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const data = await request.json();
+
+ const services = await this._mapServiceModels(data);
+ const filteredServices = services.filter(service => !!service);
+ debug('ServerApi::getServices resolves', filteredServices);
+ return filteredServices;
+ }
+
+ async createService(recipeId: string, data: { iconFile: any }) {
+ const request = await sendAuthRequest(`${apiBase()}/service`, {
+ method: 'POST',
+ body: JSON.stringify({ recipeId, ...data }),
+ });
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const serviceData = await request.json();
+
+ if (data.iconFile) {
+ const iconData = await this.uploadServiceIcon(
+ serviceData.data.id,
+ data.iconFile,
+ );
+
+ serviceData.data = iconData;
+ }
+
+ const service = Object.assign(serviceData, {
+ data: await this._prepareServiceModel(serviceData.data),
+ });
+
+ debug('ServerApi::createService resolves', service);
+ return service;
+ }
+
+ async updateService(serviceId: string, rawData: any) {
+ const data = rawData;
+
+ if (data.iconFile) {
+ await this.uploadServiceIcon(serviceId, data.iconFile);
+ }
+
+ const request = await sendAuthRequest(`${apiBase()}/service/${serviceId}`, {
+ method: 'PUT',
+ body: JSON.stringify(data),
+ });
+
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+
+ const serviceData = await request.json();
+
+ const service = Object.assign(serviceData, {
+ data: await this._prepareServiceModel(serviceData.data),
+ });
+
+ debug('ServerApi::updateService resolves', service);
+ return service;
+ }
+
+ async uploadServiceIcon(serviceId: string, icon: string | Blob) {
+ const formData = new FormData();
+ formData.append('icon', icon);
+
+ const requestData = prepareAuthRequest({
+ method: 'PUT',
+ // @ts-expect-error Argument of type '{ method: string; body: FormData; }' is not assignable to parameter of type '{ method: string; }'.
+ body: formData,
+ });
+
+ delete requestData.headers['Content-Type'];
+
+ const request = await window.fetch(
+ `${apiBase()}/service/${serviceId}`,
+ // @ts-expect-error Argument of type '{ method: string; } & { mode: string; headers: any; }' is not assignable to parameter of type 'RequestInit | undefined'.
+ requestData,
+ );
+
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+
+ const serviceData = await request.json();
+
+ return serviceData.data;
+ }
+
+ async reorderService(data: any) {
+ const request = await sendAuthRequest(`${apiBase()}/service/reorder`, {
+ method: 'PUT',
+ body: JSON.stringify(data),
+ });
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const serviceData = await request.json();
+ debug('ServerApi::reorderService resolves', serviceData);
+ return serviceData;
+ }
+
+ async deleteService(id: string) {
+ const request = await sendAuthRequest(`${apiBase()}/service/${id}`, {
+ method: 'DELETE',
+ });
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const data = await request.json();
+
+ removeServicePartitionDirectory(id, true);
+
+ debug('ServerApi::deleteService resolves', data);
+ return data;
+ }
+
+ // Features
+ async getDefaultFeatures() {
+ const request = await sendAuthRequest(`${apiBase()}/features/default`);
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const data = await request.json();
+
+ const features = data;
+ debug('ServerApi::getDefaultFeatures resolves', features);
+ return features;
+ }
+
+ async getFeatures() {
+ if (apiBase() === SERVER_NOT_LOADED) {
+ throw new Error('Server not loaded');
+ }
+
+ const request = await sendAuthRequest(`${apiBase()}/features`);
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const data = await request.json();
+
+ const features = data;
+ debug('ServerApi::getFeatures resolves', features);
+ return features;
+ }
+
+ // Recipes
+ async getInstalledRecipes() {
+ const recipesDirectory = getRecipeDirectory();
+ const paths = readdirSync(recipesDirectory).filter(
+ file =>
+ statSync(join(recipesDirectory, file)).isDirectory() &&
+ file !== 'temp' &&
+ file !== 'dev',
+ );
+
+ this.recipes = paths
+ .map(id => {
+ // eslint-disable-next-line import/no-dynamic-require
+ const Recipe = require(id)(RecipeModel);
+ return new Recipe(loadRecipeConfig(id));
+ })
+ .filter(recipe => recipe.id);
+
+ // eslint-disable-next-line unicorn/prefer-spread
+ this.recipes = this.recipes.concat(this._getDevRecipes());
+
+ debug('StubServerApi::getInstalledRecipes resolves', this.recipes);
+ return this.recipes;
+ }
+
+ async getRecipeUpdates(recipeVersions: any) {
+ const request = await sendAuthRequest(`${apiBase()}/recipes/update`, {
+ method: 'POST',
+ body: JSON.stringify(recipeVersions),
+ });
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ const recipes = await request.json();
+ debug('ServerApi::getRecipeUpdates resolves', recipes);
+ return recipes;
+ }
+
+ // Recipes Previews
+ async getRecipePreviews() {
+ const request = await sendAuthRequest(`${apiBase()}/recipes`);
+ if (!request.ok) throw new Error(request.statusText);
+ const data = await request.json();
+ const recipePreviews = this._mapRecipePreviewModel(data);
+ debug('ServerApi::getRecipes resolves', recipePreviews);
+ return recipePreviews;
+ }
+
+ async getFeaturedRecipePreviews() {
+ // TODO: If we are hitting the internal-server, we need to return an empty list, else we can hit the remote server and get the data
+ const request = await sendAuthRequest(`${apiBase()}/recipes/popular`);
+ if (!request.ok) throw new Error(request.statusText);
+
+ const data = await request.json();
+ const recipePreviews = this._mapRecipePreviewModel(data);
+ debug('ServerApi::getFeaturedRecipes resolves', recipePreviews);
+ return recipePreviews;
+ }
+
+ async searchRecipePreviews(needle: string) {
+ const url = `${apiBase()}/recipes/search?needle=${needle}`;
+ const request = await sendAuthRequest(url);
+ if (!request.ok) throw new Error(request.statusText);
+
+ const data = await request.json();
+ const recipePreviews = this._mapRecipePreviewModel(data);
+ debug('ServerApi::searchRecipePreviews resolves', recipePreviews);
+ return recipePreviews;
+ }
+
+ async getRecipePackage(recipeId: string) {
+ try {
+ const recipesDirectory = userDataRecipesPath();
+ const recipeTempDirectory = join(recipesDirectory, 'temp', recipeId);
+ const tempArchivePath = join(recipeTempDirectory, 'recipe.tar.gz');
+
+ const internalRecipeFile = asarRecipesPath(`${recipeId}.tar.gz`);
+
+ ensureDirSync(recipeTempDirectory);
+
+ let archivePath: PathOrFileDescriptor;
+
+ if (pathExistsSync(internalRecipeFile)) {
+ debug('[ServerApi::getRecipePackage] Using internal recipe file');
+ archivePath = internalRecipeFile;
+ } else {
+ debug('[ServerApi::getRecipePackage] Downloading recipe from server');
+ archivePath = tempArchivePath;
+
+ const packageUrl = `${apiBase()}/recipes/download/${recipeId}`;
+
+ const res = await fetch(packageUrl);
+ debug('Recipe downloaded', recipeId);
+ const buffer = await res.buffer();
+ writeFileSync(archivePath, buffer);
+ }
+ debug(archivePath);
+
+ await sleep(10);
+
+ // @ts-expect-error No overload matches this call.
+ await tar.x({
+ file: archivePath,
+ cwd: recipeTempDirectory,
+ preservePaths: true,
+ unlink: true,
+ preserveOwner: false,
+ onwarn: x => debug('warn', recipeId, x),
+ });
+
+ await sleep(10);
+
+ const { id } = readJsonSync(join(recipeTempDirectory, 'package.json'));
+ const recipeDirectory = join(recipesDirectory, id);
+ copySync(recipeTempDirectory, recipeDirectory);
+ removeSync(recipeTempDirectory);
+ removeSync(join(recipesDirectory, recipeId, 'recipe.tar.gz'));
+
+ return id;
+ } catch (error) {
+ console.error(error);
+
+ return false;
+ }
+ }
+
+ // Health Check
+ async healthCheck() {
+ if (apiBase() === SERVER_NOT_LOADED) {
+ throw new Error('Server not loaded');
+ }
+
+ const request = await sendAuthRequest(
+ `${apiBase(false)}/health`,
+ {
+ method: 'GET',
+ },
+ false,
+ );
+ if (!request.ok) {
+ throw new Error(request.statusText);
+ }
+ debug('ServerApi::healthCheck resolves');
+ }
+
+ async getLegacyServices() {
+ const file = userDataPath('settings', 'services.json');
+
+ try {
+ const config = readJsonSync(file);
+
+ if (Object.prototype.hasOwnProperty.call(config, 'services')) {
+ const services = await Promise.all(
+ config.services.map(async (s: { service: any }) => {
+ const service = s;
+ const request = await sendAuthRequest(
+ `${apiBase()}/recipes/${s.service}`,
+ );
+
+ if (request.status === 200) {
+ const data = await request.json();
+ // @ts-expect-error Property 'recipe' does not exist on type '{ service: any; }'.
+ service.recipe = new RecipePreviewModel(data);
+ }
+
+ return service;
+ }),
+ );
+
+ debug('ServerApi::getLegacyServices resolves', services);
+ return services;
+ }
+ } catch {
+ console.error('ServerApi::getLegacyServices no config found');
+ }
+
+ return [];
+ }
+
+ // Helper
+ async _mapServiceModels(services: any[]) {
+ const recipes = services.map((s: { recipeId: string }) => s.recipeId);
+ await this._bulkRecipeCheck(recipes);
+ /* eslint-disable no-return-await */
+ return Promise.all(
+ services.map(async (service: any) => this._prepareServiceModel(service)),
+ );
+ /* eslint-enable no-return-await */
+ }
+
+ async _prepareServiceModel(service: { recipeId: string }) {
+ let recipe: undefined;
+ try {
+ recipe = this.recipes.find(r => r.id === service.recipeId);
+
+ if (!recipe) {
+ console.warn(`Recipe ${service.recipeId} not loaded`);
+ return null;
+ }
+
+ return new ServiceModel(service, recipe);
+ } catch (error) {
+ debug(error);
+ return null;
+ }
+ }
+
+ async _bulkRecipeCheck(unfilteredRecipes: any[]) {
+ // Filter recipe duplicates as we don't need to download 3 Slack recipes
+ const recipes = unfilteredRecipes.filter(
+ (elem: any, pos: number, arr: string | any[]) =>
+ arr.indexOf(elem) === pos,
+ );
+
+ return Promise.all(
+ recipes.map(async (recipeId: string) => {
+ let recipe = this.recipes.find(r => r.id === recipeId);
+
+ if (!recipe) {
+ console.warn(
+ `Recipe '${recipeId}' not installed, trying to fetch from server`,
+ );
+
+ await this.getRecipePackage(recipeId);
+
+ debug('Rerun ServerAPI::getInstalledRecipes');
+ await this.getInstalledRecipes();
+
+ recipe = this.recipes.find(r => r.id === recipeId);
+
+ if (!recipe) {
+ console.warn(`Could not load recipe ${recipeId}`);
+ return null;
+ }
+ }
+
+ return recipe;
+ }),
+ ).catch(error => console.error("Can't load recipe", error));
+ }
+
+ _mapRecipePreviewModel(recipes: any[]) {
+ return recipes
+ .map(recipe => {
+ try {
+ return new RecipePreviewModel(recipe);
+ } catch (error) {
+ console.error(error);
+ return null;
+ }
+ })
+ .filter(recipe => recipe !== null);
+ }
+
+ _getDevRecipes() {
+ const recipesDirectory = getDevRecipeDirectory();
+ try {
+ const paths = readdirSync(recipesDirectory).filter(
+ file =>
+ statSync(join(recipesDirectory, file)).isDirectory() &&
+ file !== 'temp',
+ );
+
+ const recipes = paths
+ .map(id => {
+ let Recipe;
+ try {
+ // eslint-disable-next-line import/no-dynamic-require
+ Recipe = require(id)(RecipeModel);
+ return new Recipe(loadRecipeConfig(id));
+ } catch (error) {
+ console.error(error);
+ }
+
+ return false;
+ })
+ .filter(recipe => recipe.id)
+ .map(data => {
+ const recipe = data;
+
+ recipe.icons = {
+ svg: `${recipe.path}/icon.svg`,
+ };
+ recipe.local = true;
+
+ return data;
+ });
+
+ return recipes;
+ } catch {
+ debug('Could not load dev recipes');
+ return false;
+ }
+ }
+}
diff --git a/src/api/utils/auth.ts b/src/api/utils/auth.ts
index 98295d1a4..899881e88 100644
--- a/src/api/utils/auth.ts
+++ b/src/api/utils/auth.ts
@@ -31,7 +31,7 @@ export const prepareAuthRequest = (
export const sendAuthRequest = (
url: RequestInfo,
- options: { method: string } | undefined,
+ options?: { method: string; headers?: any; body?: any },
auth?: boolean,
) =>
// @ts-expect-error Argument of type '{ method: string; } & { mode: string; headers: any; }' is not assignable to parameter of type 'RequestInit | undefined'.
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js
index 187785f82..c70494edd 100644
--- a/src/components/services/content/ServiceWebview.js
+++ b/src/components/services/content/ServiceWebview.js
@@ -31,11 +31,13 @@ class ServiceWebview extends Component {
debug('Service logged a message:', e.message);
});
this.webview.view.addEventListener('did-navigate', () => {
- document.title = `Ferdi - ${this.props.service.name} ${
- this.props.service.dialogTitle
- ? ` - ${this.props.service.dialogTitle}`
- : ''
- } ${`- ${this.props.service._webview.getTitle()}`}`;
+ if (this.props.service._webview) {
+ document.title = `Ferdi - ${this.props.service.name} ${
+ this.props.service.dialogTitle
+ ? ` - ${this.props.service.dialogTitle}`
+ : ''
+ } ${`- ${this.props.service._webview.getTitle()}`}`;
+ }
});
}
},
diff --git a/src/components/ui/Tabs/TabItem.tsx b/src/components/ui/Tabs/TabItem.tsx
index 81ea0ea2b..9fcc3c41e 100644
--- a/src/components/ui/Tabs/TabItem.tsx
+++ b/src/components/ui/Tabs/TabItem.tsx
@@ -1,3 +1 @@
-export const TabItem = ({ children }) => {
- children;
-};
+export const TabItem = ({ children }) => <>{children}>;
diff --git a/src/features/communityRecipes/store.ts b/src/features/communityRecipes/store.ts
index a8d358ba0..c7a51c311 100644
--- a/src/features/communityRecipes/store.ts
+++ b/src/features/communityRecipes/store.ts
@@ -26,7 +26,7 @@ export class CommunityRecipesStore extends FeatureStore {
(recipePreview: { isDevRecipe: boolean; author: any[] }) => {
// TODO: Need to figure out if this is even necessary/used
recipePreview.isDevRecipe = !!recipePreview.author.some(
- (author: { email: any }) =>
+ (author: { email: string }) =>
author.email === this.stores.user.data.email,
);
diff --git a/src/features/publishDebugInfo/index.js b/src/features/publishDebugInfo/index.js
deleted file mode 100644
index 43841b530..000000000
--- a/src/features/publishDebugInfo/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import { state as ModalState } from './store';
-
-export { default as Component } from './Component';
-
-const state = ModalState;
-const debug = require('debug')('Ferdi:feature:publishDebugInfo');
-
-export default function initialize() {
- debug('Initialize publishDebugInfo feature');
-
- function showModal() {
- state.isModalVisible = true;
- }
-
- window['ferdi'].features.publishDebugInfo = {
- state,
- showModal,
- };
-}
diff --git a/src/features/publishDebugInfo/index.ts b/src/features/publishDebugInfo/index.ts
new file mode 100644
index 000000000..43841b530
--- /dev/null
+++ b/src/features/publishDebugInfo/index.ts
@@ -0,0 +1,19 @@
+import { state as ModalState } from './store';
+
+export { default as Component } from './Component';
+
+const state = ModalState;
+const debug = require('debug')('Ferdi:feature:publishDebugInfo');
+
+export default function initialize() {
+ debug('Initialize publishDebugInfo feature');
+
+ function showModal() {
+ state.isModalVisible = true;
+ }
+
+ window['ferdi'].features.publishDebugInfo = {
+ state,
+ showModal,
+ };
+}
diff --git a/src/i18n/translations.ts b/src/i18n/translations.ts
index cc5ecf83a..9b23497e1 100644
--- a/src/i18n/translations.ts
+++ b/src/i18n/translations.ts
@@ -1,16 +1,16 @@
-/* eslint-disable import/no-import-module-exports */
/* eslint-disable global-require */
import { APP_LOCALES } from './languages';
-const translations = [];
-for (const key of Object.keys(APP_LOCALES)) {
- try {
- // eslint-disable-next-line import/no-dynamic-require
- const translation = require(`./locales/${key}.json`);
- translations[key] = translation;
- } catch {
- console.warn(`Can't find translations for ${key}`);
+export const generatedTranslations = () => {
+ const translations = [];
+ for (const key of Object.keys(APP_LOCALES)) {
+ try {
+ // eslint-disable-next-line import/no-dynamic-require
+ const translation = require(`./locales/${key}.json`);
+ translations[key] = translation;
+ } catch {
+ console.warn(`Can't find translations for ${key}`);
+ }
}
-}
-
-module.exports = translations;
+ return translations;
+};
diff --git a/src/internal-server/database/factory.js b/src/internal-server/database/factory.js
index 8cd45a80d..8534fc20a 100644
--- a/src/internal-server/database/factory.js
+++ b/src/internal-server/database/factory.js
@@ -1,4 +1,3 @@
-/* eslint-disable unicorn/no-empty-file */
/*
|--------------------------------------------------------------------------
| Factory
diff --git a/src/routes.js b/src/routes.js
deleted file mode 100644
index 9891e5d43..000000000
--- a/src/routes.js
+++ /dev/null
@@ -1,98 +0,0 @@
-import { Component } from 'react';
-import PropTypes from 'prop-types';
-import { inject, observer } from 'mobx-react';
-import { Router, Route, IndexRedirect } from 'react-router';
-
-import AppLayoutContainer from './containers/layout/AppLayoutContainer';
-import SettingsWindow from './containers/settings/SettingsWindow';
-import RecipesScreen from './containers/settings/RecipesScreen';
-import ServicesScreen from './containers/settings/ServicesScreen';
-import EditServiceScreen from './containers/settings/EditServiceScreen';
-import AccountScreen from './containers/settings/AccountScreen';
-import TeamScreen from './containers/settings/TeamScreen';
-import EditUserScreen from './containers/settings/EditUserScreen';
-import EditSettingsScreen from './containers/settings/EditSettingsScreen';
-import InviteSettingsScreen from './containers/settings/InviteScreen';
-import SupportFerdiScreen from './containers/settings/SupportScreen';
-import WelcomeScreen from './containers/auth/WelcomeScreen';
-import LoginScreen from './containers/auth/LoginScreen';
-import LockedScreen from './containers/auth/LockedScreen';
-import PasswordScreen from './containers/auth/PasswordScreen';
-import ChangeServerScreen from './containers/auth/ChangeServerScreen';
-import SignupScreen from './containers/auth/SignupScreen';
-import ImportScreen from './containers/auth/ImportScreen';
-import SetupAssistentScreen from './containers/auth/SetupAssistantScreen';
-import InviteScreen from './containers/auth/InviteScreen';
-import AuthLayoutContainer from './containers/auth/AuthLayoutContainer';
-import WorkspacesScreen from './features/workspaces/containers/WorkspacesScreen';
-import EditWorkspaceScreen from './features/workspaces/containers/EditWorkspaceScreen';
-import { WORKSPACES_ROUTES } from './features/workspaces/constants';
-
-import SettingsStore from './stores/SettingsStore';
-
-@inject('stores', 'actions')
-@observer
-class Routes extends Component {
- render() {
- const { locked } = this.props.stores.settings.app;
-
- const { history } = this.props;
-
- if (locked) {
- return ;
- }
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-}
-
-Routes.wrappedComponent.propTypes = {
- stores: PropTypes.shape({
- settings: PropTypes.instanceOf(SettingsStore).isRequired,
- }).isRequired,
- history: PropTypes.any.isRequired,
-};
-
-export default Routes;
diff --git a/src/routes.tsx b/src/routes.tsx
new file mode 100644
index 000000000..569da06a7
--- /dev/null
+++ b/src/routes.tsx
@@ -0,0 +1,97 @@
+import { Component } from 'react';
+import { inject, observer } from 'mobx-react';
+import { Router, Route, IndexRedirect } from 'react-router';
+
+import AppLayoutContainer from './containers/layout/AppLayoutContainer';
+import SettingsWindow from './containers/settings/SettingsWindow';
+import RecipesScreen from './containers/settings/RecipesScreen';
+import ServicesScreen from './containers/settings/ServicesScreen';
+import EditServiceScreen from './containers/settings/EditServiceScreen';
+import AccountScreen from './containers/settings/AccountScreen';
+import TeamScreen from './containers/settings/TeamScreen';
+import EditUserScreen from './containers/settings/EditUserScreen';
+import EditSettingsScreen from './containers/settings/EditSettingsScreen';
+import InviteSettingsScreen from './containers/settings/InviteScreen';
+import SupportFerdiScreen from './containers/settings/SupportScreen';
+import WelcomeScreen from './containers/auth/WelcomeScreen';
+import LoginScreen from './containers/auth/LoginScreen';
+import LockedScreen from './containers/auth/LockedScreen';
+import PasswordScreen from './containers/auth/PasswordScreen';
+import ChangeServerScreen from './containers/auth/ChangeServerScreen';
+import SignupScreen from './containers/auth/SignupScreen';
+import ImportScreen from './containers/auth/ImportScreen';
+import SetupAssistentScreen from './containers/auth/SetupAssistantScreen';
+import InviteScreen from './containers/auth/InviteScreen';
+import AuthLayoutContainer from './containers/auth/AuthLayoutContainer';
+import WorkspacesScreen from './features/workspaces/containers/WorkspacesScreen';
+import EditWorkspaceScreen from './features/workspaces/containers/EditWorkspaceScreen';
+import { WORKSPACES_ROUTES } from './features/workspaces/constants';
+
+import SettingsStore from './stores/SettingsStore';
+
+type Props = {
+ stores: {
+ settings: typeof SettingsStore;
+ };
+ history: any;
+};
+
+@inject('stores', 'actions')
+@observer
+class Routes extends Component {
+ render() {
+ const { locked } = this.props.stores.settings.app;
+
+ const { history } = this.props;
+
+ if (locked) {
+ return ;
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+export default Routes;
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index d652276ea..5881e37a4 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -19,7 +19,7 @@ import Request from './lib/Request';
import { CHECK_INTERVAL, DEFAULT_APP_SETTINGS } from '../config';
import { isMac, electronVersion, osRelease } from '../environment';
import { ferdiVersion, userDataPath, ferdiLocale } from '../environment-remote';
-import locales from '../i18n/translations';
+import { generatedTranslations } from '../i18n/translations';
import { getLocale } from '../helpers/i18n-helpers';
import {
@@ -42,6 +42,8 @@ const autoLauncher = new AutoLaunch({
const CATALINA_NOTIFICATION_HACK_KEY =
'_temp_askedForCatalinaNotificationPermissions';
+const locales = generatedTranslations();
+
export default class AppStore extends Store {
updateStatusTypes = {
CHECKING: 'CHECKING',
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 16deb91c5..3d418c4c5 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -655,20 +655,20 @@ export default class ServicesStore extends Store {
@action _setWebviewReference({ serviceId, webview }) {
const service = this.one(serviceId);
-
- service.webview = webview;
-
- if (!service.isAttached) {
- debug('Webview is not attached, initializing');
- service.initializeWebViewEvents({
- handleIPCMessage: this.actions.service.handleIPCMessage,
- openWindow: this.actions.service.openWindow,
- stores: this.stores,
- });
- service.initializeWebViewListener();
+ if (service) {
+ service.webview = webview;
+
+ if (!service.isAttached) {
+ debug('Webview is not attached, initializing');
+ service.initializeWebViewEvents({
+ handleIPCMessage: this.actions.service.handleIPCMessage,
+ openWindow: this.actions.service.openWindow,
+ stores: this.stores,
+ });
+ service.initializeWebViewListener();
+ }
+ service.isAttached = true;
}
-
- service.isAttached = true;
}
@action _detachService({ service }) {
@@ -690,20 +690,22 @@ export default class ServicesStore extends Store {
// TODO: add checks to not focus service when router path is /settings or /auth
const service = this.active;
if (service) {
- document.title = `Ferdi - ${service.name} ${
- service.dialogTitle ? ` - ${service.dialogTitle}` : ''
- } ${service._webview ? `- ${service._webview.getTitle()}` : ''}`;
- this._focusService({ serviceId: service.id });
- if (this.stores.settings.app.splitMode && !focusEvent) {
- setTimeout(() => {
- document
- .querySelector('.services__webview-wrapper.is-active')
- .scrollIntoView({
- behavior: 'smooth',
- block: 'end',
- inline: 'nearest',
- });
- }, 10);
+ if (service._webview) {
+ document.title = `Ferdi - ${service.name} ${
+ service.dialogTitle ? ` - ${service.dialogTitle}` : ''
+ } ${service._webview ? `- ${service._webview.getTitle()}` : ''}`;
+ this._focusService({ serviceId: service.id });
+ if (this.stores.settings.app.splitMode && !focusEvent) {
+ setTimeout(() => {
+ document
+ .querySelector('.services__webview-wrapper.is-active')
+ .scrollIntoView({
+ behavior: 'smooth',
+ block: 'end',
+ inline: 'nearest',
+ });
+ }, 10);
+ }
}
} else {
debug('No service is active');
diff --git a/src/webview/lib/RecipeWebview.js b/src/webview/lib/RecipeWebview.js
deleted file mode 100644
index ebe88ed85..000000000
--- a/src/webview/lib/RecipeWebview.js
+++ /dev/null
@@ -1,166 +0,0 @@
-import { ipcRenderer } from 'electron';
-import { BrowserWindow } from '@electron/remote';
-import { pathExistsSync, readFileSync, existsSync } from 'fs-extra';
-
-const debug = require('debug')('Ferdi:Plugin:RecipeWebview');
-
-class RecipeWebview {
- constructor(
- badgeHandler,
- dialogTitleHandler,
- notificationsHandler,
- sessionHandler,
- ) {
- this.badgeHandler = badgeHandler;
- this.dialogTitleHandler = dialogTitleHandler;
- this.notificationsHandler = notificationsHandler;
- this.sessionHandler = sessionHandler;
-
- ipcRenderer.on('poll', () => {
- this.loopFunc();
-
- debug('Poll event');
-
- // This event is for checking if the service recipe is still actively
- // communicating with the client
- ipcRenderer.sendToHost('alive');
- });
- }
-
- loopFunc = () => null;
-
- darkModeHandler = false;
-
- // TODO Remove this once we implement a proper wrapper.
- get ipcRenderer() {
- return ipcRenderer;
- }
-
- // TODO Remove this once we implement a proper wrapper.
- get BrowserWindow() {
- return BrowserWindow;
- }
-
- /**
- * Initialize the loop
- *
- * @param {Function} Function that will be executed
- */
- loop(fn) {
- this.loopFunc = fn;
- }
-
- /**
- * Set the unread message badge
- *
- * @param {string | number | undefined | null} direct Set the count of direct messages
- * eg. Slack direct mentions, or a
- * message to @channel
- * @param {string | number | undefined | null} indirect Set a badge that defines there are
- * new messages but they do not involve
- * me directly to me eg. in a channel
- */
- setBadge(direct = 0, indirect = 0) {
- this.badgeHandler.setBadge(direct, indirect);
- }
-
- /**
- * Set the active dialog title to the app title
- *
- * @param {string | undefined | null} title Set the active dialog title
- * to the app title
- * eg. WhatsApp contact name
- */
- setDialogTitle(title) {
- this.dialogTitleHandler.setDialogTitle(title);
- }
-
- /**
- * Safely parse the given text into an integer
- *
- * @param {string | number | undefined | null} text to be parsed
- */
- safeParseInt(text) {
- return this.badgeHandler.safeParseInt(text);
- }
-
- /**
- * Injects the contents of a CSS file into the current webview
- *
- * @param {Array} files CSS files that should be injected. This must
- * be an absolute path to the file
- */
- injectCSS(...files) {
- // eslint-disable-next-line unicorn/no-array-for-each
- files.forEach(file => {
- if (pathExistsSync(file)) {
- const styles = document.createElement('style');
- styles.innerHTML = readFileSync(file, 'utf8');
-
- document.querySelector('head').append(styles);
-
- debug('Append styles', styles);
- }
- });
- }
-
- injectJSUnsafe(...files) {
- Promise.all(
- files.map(file => {
- if (existsSync(file)) {
- return readFileSync(file, 'utf8');
- }
- debug('Script not found', file);
- return null;
- }),
- ).then(scripts => {
- const scriptsFound = scripts.filter(script => script !== null);
- if (scriptsFound.length > 0) {
- debug('Inject scripts to main world', scriptsFound);
- ipcRenderer.sendToHost('inject-js-unsafe', ...scriptsFound);
- }
- });
- }
-
- /**
- * Set a custom handler for turning on and off dark mode
- *
- * @param {function} handler
- */
- handleDarkMode(handler) {
- this.darkModeHandler = handler;
- }
-
- onNotify(fn) {
- if (typeof fn === 'function') {
- this.notificationsHandler.onNotify = fn;
- }
- }
-
- initialize(fn) {
- if (typeof fn === 'function') {
- fn();
- }
- }
-
- clearStorageData(serviceId, targetsToClear) {
- ipcRenderer.send('clear-storage-data', {
- serviceId,
- targetsToClear,
- });
- }
-
- releaseServiceWorkers() {
- this.sessionHandler.releaseServiceWorkers();
- }
-
- setAvatarImage(avatarUrl) {
- ipcRenderer.sendToHost('avatar', avatarUrl);
- }
-
- openNewWindow(url) {
- ipcRenderer.sendToHost('new-window', url);
- }
-}
-
-export default RecipeWebview;
diff --git a/src/webview/lib/RecipeWebview.ts b/src/webview/lib/RecipeWebview.ts
new file mode 100644
index 000000000..09dc462ed
--- /dev/null
+++ b/src/webview/lib/RecipeWebview.ts
@@ -0,0 +1,177 @@
+import { ipcRenderer } from 'electron';
+import { BrowserWindow } from '@electron/remote';
+import { pathExistsSync, readFileSync, existsSync } from 'fs-extra';
+
+const debug = require('debug')('Ferdi:Plugin:RecipeWebview');
+
+class RecipeWebview {
+ badgeHandler: any;
+
+ dialogTitleHandler: any;
+
+ notificationsHandler: any;
+
+ sessionHandler: any;
+
+ constructor(
+ badgeHandler,
+ dialogTitleHandler,
+ notificationsHandler,
+ sessionHandler,
+ ) {
+ this.badgeHandler = badgeHandler;
+ this.dialogTitleHandler = dialogTitleHandler;
+ this.notificationsHandler = notificationsHandler;
+ this.sessionHandler = sessionHandler;
+
+ ipcRenderer.on('poll', () => {
+ this.loopFunc();
+
+ debug('Poll event');
+
+ // This event is for checking if the service recipe is still actively
+ // communicating with the client
+ ipcRenderer.sendToHost('alive');
+ });
+ }
+
+ loopFunc = () => null;
+
+ darkModeHandler = false;
+
+ // TODO Remove this once we implement a proper wrapper.
+ get ipcRenderer() {
+ return ipcRenderer;
+ }
+
+ // TODO Remove this once we implement a proper wrapper.
+ get BrowserWindow() {
+ return BrowserWindow;
+ }
+
+ /**
+ * Initialize the loop
+ *
+ * @param {Function} Function that will be executed
+ */
+ loop(fn) {
+ this.loopFunc = fn;
+ }
+
+ /**
+ * Set the unread message badge
+ *
+ * @param {string | number | undefined | null} direct Set the count of direct messages
+ * eg. Slack direct mentions, or a
+ * message to @channel
+ * @param {string | number | undefined | null} indirect Set a badge that defines there are
+ * new messages but they do not involve
+ * me directly to me eg. in a channel
+ */
+ setBadge(direct = 0, indirect = 0) {
+ this.badgeHandler.setBadge(direct, indirect);
+ }
+
+ /**
+ * Set the active dialog title to the app title
+ *
+ * @param {string | undefined | null} title Set the active dialog title
+ * to the app title
+ * eg. WhatsApp contact name
+ */
+ setDialogTitle(title) {
+ this.dialogTitleHandler.setDialogTitle(title);
+ }
+
+ /**
+ * Safely parse the given text into an integer
+ *
+ * @param {string | number | undefined | null} text to be parsed
+ */
+ safeParseInt(text) {
+ return this.badgeHandler.safeParseInt(text);
+ }
+
+ /**
+ * Injects the contents of a CSS file into the current webview
+ *
+ * @param {Array} files CSS files that should be injected. This must
+ * be an absolute path to the file
+ */
+ injectCSS(...files) {
+ // eslint-disable-next-line unicorn/no-array-for-each
+ files.forEach(file => {
+ if (pathExistsSync(file)) {
+ const styles = document.createElement('style');
+ styles.innerHTML = readFileSync(file, 'utf8');
+
+ const head = document.querySelector('head');
+
+ if (head) {
+ head.append(styles);
+ debug('Append styles', styles);
+ }
+ }
+ });
+ }
+
+ injectJSUnsafe(...files) {
+ Promise.all(
+ files.map(file => {
+ if (existsSync(file)) {
+ return readFileSync(file, 'utf8');
+ }
+ debug('Script not found', file);
+ return null;
+ }),
+ ).then(scripts => {
+ const scriptsFound = scripts.filter(script => script !== null);
+ if (scriptsFound.length > 0) {
+ debug('Inject scripts to main world', scriptsFound);
+ ipcRenderer.sendToHost('inject-js-unsafe', ...scriptsFound);
+ }
+ });
+ }
+
+ /**
+ * Set a custom handler for turning on and off dark mode
+ *
+ * @param {function} handler
+ */
+ handleDarkMode(handler) {
+ this.darkModeHandler = handler;
+ }
+
+ onNotify(fn) {
+ if (typeof fn === 'function') {
+ this.notificationsHandler.onNotify = fn;
+ }
+ }
+
+ initialize(fn) {
+ if (typeof fn === 'function') {
+ fn();
+ }
+ }
+
+ clearStorageData(serviceId, targetsToClear) {
+ ipcRenderer.send('clear-storage-data', {
+ serviceId,
+ targetsToClear,
+ });
+ }
+
+ releaseServiceWorkers() {
+ this.sessionHandler.releaseServiceWorkers();
+ }
+
+ setAvatarImage(avatarUrl) {
+ ipcRenderer.sendToHost('avatar', avatarUrl);
+ }
+
+ openNewWindow(url) {
+ ipcRenderer.sendToHost('new-window', url);
+ }
+}
+
+export default RecipeWebview;
diff --git a/src/webview/lib/Userscript.js b/src/webview/lib/Userscript.js
deleted file mode 100644
index f7bb99206..000000000
--- a/src/webview/lib/Userscript.js
+++ /dev/null
@@ -1,138 +0,0 @@
-import { ipcRenderer } from 'electron';
-
-export default class Userscript {
- // Current ./lib/RecipeWebview instance
- recipe = null;
-
- // Current ./recipe.js instance
- controller = null;
-
- // Service configuration
- config = {};
-
- // Ferdi and service settings
- settings = {};
-
- settingsUpdateHandler = null;
-
- constructor(recipe, controller, config) {
- this.recipe = recipe;
- this.controller = controller;
- this.internal_setSettings(controller.settings);
- this.config = config;
- }
-
- /**
- * Set internal copy of Ferdi's settings.
- * This is only used internally and can not be used to change any settings
- *
- * @param {*} settings
- */
- // eslint-disable-next-line camelcase
- internal_setSettings(settings) {
- // This is needed to get a clean JS object from the settings itself to provide better accessibility
- // Otherwise this will be a mobX instance
- this.settings = JSON.parse(JSON.stringify(settings));
-
- if (typeof this.settingsUpdateHandler === 'function') {
- this.settingsUpdateHandler();
- }
- }
-
- /**
- * Register a settings handler to be executed when the settings change
- *
- * @param {function} handler
- */
- onSettingsUpdate(handler) {
- this.settingsUpdateHandler = handler;
- }
-
- /**
- * Set badge count for the current service
- * @param {*} direct Direct messages
- * @param {*} indirect Indirect messages
- */
- setBadge(direct = 0, indirect = 0) {
- if (this.recipe && this.recipe.setBadge) {
- this.recipe.setBadge(direct, indirect);
- }
- }
-
- /**
- * Set active dialog title to the app title
- * @param {*} title Dialog title
- */
- setDialogTitle(title) {
- if (this.recipe && this.recipe.setDialogTitle) {
- this.recipe.setDialogTitle(title);
- }
- }
-
- /**
- * Inject CSS files into the current page
- *
- * @param {...string} files
- */
- injectCSSFiles(...files) {
- if (this.recipe && this.recipe.injectCSS) {
- this.recipe.injectCSS(...files);
- }
- }
-
- /**
- * Inject a CSS string into the page
- *
- * @param {string} css
- */
- injectCSS(css) {
- const style = document.createElement('style');
- style.textContent = css;
- document.head.append(style);
- }
-
- /**
- * Open "Find in Page" popup
- */
- openFindInPage() {
- this.controller.openFindInPage();
- }
-
- /**
- * Set or update value in storage
- *
- * @param {*} key
- * @param {*} value
- */
- set(key, value) {
- window.localStorage.setItem(`ferdi-user-${key}`, JSON.stringify(value));
- }
-
- /**
- * Get value from storage
- *
- * @param {*} key
- * @return Value of the key
- */
- get(key) {
- return JSON.parse(window.localStorage.getItem(`ferdi-user-${key}`));
- }
-
- /**
- * Open a URL in an external browser
- *
- * @param {*} url
- */
- externalOpen(url) {
- ipcRenderer.sendToHost('new-window', url);
- }
-
- /**
- * Open a URL in the current service
- *
- * @param {*} url
- */
- internalOpen(url) {
- window.location.href = url;
- }
-}
diff --git a/src/webview/lib/Userscript.ts b/src/webview/lib/Userscript.ts
new file mode 100644
index 000000000..c50941dc7
--- /dev/null
+++ b/src/webview/lib/Userscript.ts
@@ -0,0 +1,107 @@
+type Recipe = {
+ setBadge: (direct: number, indirect: number) => void;
+ setDialogTitle: (title: string) => void;
+ injectCSS: (css: string | string[]) => void;
+};
+
+export default class Userscript {
+ // Current ./lib/RecipeWebview instance
+ recipe: Recipe | null = null;
+
+ // Current ./recipe.js instance
+ controller = null;
+
+ // Service configuration
+ config = {};
+
+ // Ferdi and service settings
+ settings = {};
+
+ constructor(recipe, controller, config) {
+ this.recipe = recipe;
+ this.controller = controller;
+ this.internal_setSettings(controller.settings);
+ this.config = config;
+ }
+
+ /**
+ * Set internal copy of Ferdi's settings.
+ * This is only used internally and can not be used to change any settings
+ *
+ * @param {*} settings
+ */
+ // eslint-disable-next-line camelcase
+ internal_setSettings(settings: any) {
+ // This is needed to get a clean JS object from the settings itself to provide better accessibility
+ // Otherwise this will be a mobX instance
+ this.settings = JSON.parse(JSON.stringify(settings));
+ }
+
+ /**
+ * Set badge count for the current service
+ * @param {number} direct Direct messages
+ * @param {number} indirect Indirect messages
+ */
+ setBadge(direct: number = 0, indirect: number = 0) {
+ if (this.recipe && this.recipe.setBadge) {
+ this.recipe.setBadge(direct, indirect);
+ }
+ }
+
+ /**
+ * Set active dialog title to the app title
+ * @param {*} title Dialog title
+ */
+ setDialogTitle(title: string) {
+ if (this.recipe && this.recipe.setDialogTitle) {
+ this.recipe.setDialogTitle(title);
+ }
+ }
+
+ /**
+ * Inject CSS files into the current page
+ *
+ * @param {...string} files
+ */
+ injectCSSFiles(...files: string[]) {
+ if (this.recipe && this.recipe.injectCSS) {
+ // @ts-expect-error A spread argument must either have a tuple type or be passed to a rest parameter.
+ this.recipe.injectCSS(...files);
+ }
+ }
+
+ /**
+ * Inject a CSS string into the page
+ *
+ * @param {string} css
+ */
+ injectCSS(css: string) {
+ const style = document.createElement('style');
+ style.textContent = css;
+ document.head.append(style);
+ }
+
+ /**
+ * Set or update value in storage
+ *
+ * @param {string} key
+ * @param {any} value
+ */
+ set(key: string, value: string) {
+ window.localStorage.setItem(`ferdi-user-${key}`, JSON.stringify(value));
+ }
+
+ /**
+ * Get value from storage
+ *
+ * @param {string} key
+ * @return Value of the key
+ */
+ get(key: string) {
+ const ferdiUserKey = window.localStorage.getItem(`ferdi-user-${key}`);
+
+ if (ferdiUserKey) {
+ return JSON.parse(ferdiUserKey);
+ }
+ }
+}
--
cgit v1.2.3-70-g09d2
From 11c992b04f3cad6badf0ae86da65f490e31dd359 Mon Sep 17 00:00:00 2001
From: Markus Hatvan
Date: Sat, 4 Dec 2021 10:51:16 +0100
Subject: chore: upgrade react-jss to latest (#2302)
---
package-lock.json | 659 ++++++++++++---------
package.json | 6 +-
src/I18n.tsx | 4 +-
src/components/auth/AuthLayout.js | 3 +-
src/components/auth/ChangeServer.js | 3 +-
src/components/auth/Import.js | 3 +-
src/components/auth/Invite.js | 3 +-
src/components/auth/Locked.js | 3 +-
src/components/auth/Login.js | 4 +-
src/components/auth/Password.js | 3 +-
src/components/auth/SetupAssistant.js | 6 +-
src/components/auth/Signup.js | 4 +-
src/components/auth/Welcome.js | 4 +-
src/components/layout/AppLayout.js | 6 +-
src/components/layout/Sidebar.js | 4 +-
.../services/content/ConnectionLostBanner.js | 4 +-
.../content/ErrorHandlers/WebviewErrorHandler.js | 6 +-
src/components/services/content/ServiceDisabled.js | 3 +-
src/components/services/content/ServiceView.js | 4 +-
src/components/services/content/ServiceWebview.js | 3 +-
src/components/services/content/Services.js | 9 +-
.../services/content/WebviewCrashHandler.js | 3 +-
src/components/services/tabs/TabBarSortableList.js | 3 +-
src/components/services/tabs/TabItem.js | 11 +-
src/components/services/tabs/Tabbar.js | 3 +-
src/components/settings/SettingsLayout.js | 3 +-
.../settings/account/AccountDashboard.js | 3 +-
.../settings/navigation/SettingsNavigation.js | 4 +-
src/components/settings/recipes/RecipeItem.js | 3 +-
.../settings/recipes/RecipesDashboard.js | 28 +-
.../settings/services/EditServiceForm.js | 3 +-
src/components/settings/services/ServiceError.js | 3 +-
src/components/settings/services/ServiceItem.js | 3 +-
.../settings/services/ServicesDashboard.js | 3 +-
.../settings/settings/EditSettingsForm.js | 3 +-
src/components/settings/team/TeamDashboard.js | 6 +-
src/components/settings/user/EditUserForm.js | 3 +-
src/components/ui/AppLoader/index.tsx | 6 +-
src/components/ui/Button.js | 4 +-
src/components/ui/FAB.tsx | 3 +-
src/components/ui/FullscreenLoader/index.js | 9 +-
src/components/ui/ImageUpload.tsx | 3 +-
src/components/ui/InfoBar.js | 3 +-
src/components/ui/Infobox.js | 3 +-
src/components/ui/Input.js | 12 +-
src/components/ui/Link.js | 8 +-
src/components/ui/Loader.tsx | 4 +-
src/components/ui/Modal/index.tsx | 3 +-
src/components/ui/Radio.tsx | 3 +-
src/components/ui/SearchInput.tsx | 3 +-
src/components/ui/Select.js | 3 +-
src/components/ui/ServiceIcon.js | 6 +-
src/components/ui/Slider.js | 3 +-
src/components/ui/StatusBarTargetUrl.js | 3 +-
src/components/ui/Tabs/Tabs.js | 3 +-
src/components/ui/Toggle.js | 3 +-
src/components/ui/ToggleRaw.js | 3 +-
src/components/ui/WebviewLoader/index.js | 6 +-
src/components/ui/badge/ProBadge.tsx | 9 +-
src/components/ui/badge/index.tsx | 7 +-
src/components/ui/button/index.tsx | 14 +-
src/components/ui/error/index.tsx | 2 +-
src/components/ui/headline/index.tsx | 10 +-
src/components/ui/icon/index.tsx | 7 +-
src/components/ui/infobox/index.tsx | 9 +-
src/components/ui/input/index.tsx | 8 +-
src/components/ui/label/index.tsx | 13 +-
src/components/ui/loader/index.tsx | 18 +-
src/components/ui/select/index.tsx | 11 +-
src/components/ui/textarea/index.tsx | 10 +-
src/components/ui/toggle/index.tsx | 10 +-
src/components/ui/typings/generic.ts | 9 -
src/components/ui/wrapper/index.tsx | 9 +-
src/components/util/ErrorBoundary/index.js | 5 +-
src/containers/auth/AuthLayoutContainer.js | 6 +-
src/containers/auth/ChangeServerScreen.js | 6 +-
src/containers/auth/ImportScreen.js | 6 +-
src/containers/auth/InviteScreen.js | 6 +-
src/containers/auth/LockedScreen.js | 6 +-
src/containers/auth/LoginScreen.js | 6 +-
src/containers/auth/PasswordScreen.js | 6 +-
src/containers/auth/SetupAssistantScreen.js | 6 +-
src/containers/auth/SignupScreen.js | 6 +-
src/containers/auth/WelcomeScreen.js | 6 +-
src/containers/layout/AppLayoutContainer.js | 6 +-
src/containers/settings/AccountScreen.js | 6 +-
src/containers/settings/EditServiceScreen.js | 8 +-
src/containers/settings/EditSettingsScreen.js | 8 +-
src/containers/settings/EditUserScreen.js | 8 +-
src/containers/settings/InviteScreen.js | 6 +-
src/containers/settings/RecipesScreen.js | 6 +-
src/containers/settings/ServicesScreen.js | 6 +-
src/containers/settings/SettingsWindow.js | 6 +-
src/containers/settings/SupportScreen.js | 5 +-
src/containers/settings/TeamScreen.js | 6 +-
src/electron/ipc-api/download.ts | 2 +-
src/features/basicAuth/Component.js | 6 +-
src/features/nightlyBuilds/Component.js | 15 +-
src/features/publishDebugInfo/Component.js | 16 +-
src/features/quickSwitch/Component.js | 12 +-
src/features/todos/components/TodosWebview.js | 7 +-
src/features/todos/containers/TodosScreen.js | 6 +-
src/features/todos/store.js | 4 -
src/features/webControls/components/WebControls.js | 6 +-
.../webControls/containers/WebControlsScreen.js | 6 +-
.../workspaces/components/CreateWorkspaceForm.js | 10 +-
.../workspaces/components/EditWorkspaceForm.js | 10 +-
.../workspaces/components/WorkspaceDrawer.js | 6 +-
.../workspaces/components/WorkspaceDrawerItem.js | 6 +-
.../workspaces/components/WorkspaceItem.tsx | 6 +-
.../components/WorkspaceServiceListItem.tsx | 6 +-
.../components/WorkspaceSwitchingIndicator.js | 8 +-
.../workspaces/components/WorkspacesDashboard.js | 15 +-
.../workspaces/containers/EditWorkspaceScreen.tsx | 4 +-
.../workspaces/containers/WorkspacesScreen.tsx | 4 +-
src/lib/Form.ts | 7 +
src/routes.tsx | 4 +-
src/stores/ServicesStore.js | 2 -
118 files changed, 700 insertions(+), 673 deletions(-)
(limited to 'src/stores/ServicesStore.js')
diff --git a/package-lock.json b/package-lock.json
index eefac54e2..b145811cd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -51,8 +51,8 @@
"minimist": "^1.2.5",
"mobx": "^5.15.0",
"mobx-localstorage": "^1.2.0",
- "mobx-react": "^5.4.2",
- "mobx-react-form": "1.35.1",
+ "mobx-react": "^6.3.1",
+ "mobx-react-form": "^2.0.9",
"mobx-react-router": "^3.1.2",
"moment": "^2.29.1",
"ms": "^2.1.3",
@@ -68,7 +68,7 @@
"react-dropzone": "^11.4.2",
"react-electron-web-view": "^2.0.1",
"react-intl": "^5.21.0",
- "react-jss": "^8.6.1",
+ "react-jss": "^10.8.2",
"react-loader": "^2.4.7",
"react-modal": "^3.14.3",
"react-router": "^3.2.6",
@@ -2866,6 +2866,19 @@
"graceful-fs": "^4.1.6"
}
},
+ "node_modules/@emotion/is-prop-valid": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz",
+ "integrity": "sha512-uxJqm/sqwXw3YPA5GXX365OBcJGFtxUVkB6WyezqFHlNe9jqUWH5ur2O2M8dGBz61kn1g3ZBlzUunFQXQIClhA==",
+ "dependencies": {
+ "@emotion/memoize": "0.7.1"
+ }
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.1.tgz",
+ "integrity": "sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg=="
+ },
"node_modules/@endemolshinegroup/cosmiconfig-typescript-loader": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz",
@@ -7769,11 +7782,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/brcast": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.2.tgz",
- "integrity": "sha512-f5XwwFCCuvgqP2nMH/hJ74FqnGmb4X3D+NC//HphxJzzhsZvSZa+Hk/syB7j3ZHpPDLMoYU8oBgviRWfNvEfKA=="
- },
"node_modules/brorand": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
@@ -10098,6 +10106,16 @@
"node": ">= 0.8"
}
},
+ "node_modules/css-jss": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/css-jss/-/css-jss-10.8.2.tgz",
+ "integrity": "sha512-KjsoKnBV4C9p+F+zW9jNXCai0UYU5K+3eyo+lJX/fY8UBEQd/yNREnHsLD1VMMzBwHRvrA8eQHvqmAL+XNLYcw==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "jss-preset-default": "10.8.2"
+ }
+ },
"node_modules/css-select": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz",
@@ -10137,10 +10155,11 @@
}
},
"node_modules/css-vendor": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz",
- "integrity": "sha1-ZCHP0wNM5mT+dnOXL9ARn8KJQfo=",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
+ "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
"dependencies": {
+ "@babel/runtime": "^7.8.3",
"is-in-browser": "^1.0.2"
}
},
@@ -16616,11 +16635,6 @@
"node": ">=4"
}
},
- "node_modules/is-function": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz",
- "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ=="
- },
"node_modules/is-generator-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
@@ -19420,122 +19434,141 @@
"url": "https://opencollective.com/jss"
}
},
- "node_modules/jss-camel-case": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-6.1.0.tgz",
- "integrity": "sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ==",
+ "node_modules/jss-plugin-camel-case": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.8.2.tgz",
+ "integrity": "sha512-2INyxR+1UdNuKf4v9It3tNfPvf7IPrtkiwzofeKuMd5D58/dxDJVUQYRVg/n460rTlHUfsEQx43hDrcxi9dSPA==",
"dependencies": {
- "hyphenate-style-name": "^1.0.2"
- },
- "peerDependencies": {
- "jss": "^9.7.0"
+ "@babel/runtime": "^7.3.1",
+ "hyphenate-style-name": "^1.0.3",
+ "jss": "10.8.2"
}
},
- "node_modules/jss-compose": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/jss-compose/-/jss-compose-5.0.0.tgz",
- "integrity": "sha512-YofRYuiA0+VbeOw0VjgkyO380sA4+TWDrW52nSluD9n+1FWOlDzNbgpZ/Sb3Y46+DcAbOS21W5jo6SAqUEiuwA==",
+ "node_modules/jss-plugin-compose": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-compose/-/jss-plugin-compose-10.8.2.tgz",
+ "integrity": "sha512-X7fDQJ6IlIJoT8A3zc++LuC1hmSGKVudb3LyXp+vHv8r2hzzfXEEZty3y2CaC5CGrWcLlYquXENjqLNmLYMgMA==",
"dependencies": {
- "warning": "^3.0.0"
- },
- "peerDependencies": {
- "jss": "^9.0.0"
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "tiny-warning": "^1.0.2"
}
},
- "node_modules/jss-default-unit": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-8.0.2.tgz",
- "integrity": "sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg==",
- "peerDependencies": {
- "jss": "^9.4.0"
+ "node_modules/jss-plugin-default-unit": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.8.2.tgz",
+ "integrity": "sha512-UZ7cwT9NFYSG+SEy7noRU50s4zifulFdjkUNKE+u6mW7vFP960+RglWjTgMfh79G6OENZmaYnjHV/gcKV4nSxg==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2"
}
},
- "node_modules/jss-expand": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/jss-expand/-/jss-expand-5.3.0.tgz",
- "integrity": "sha512-NiM4TbDVE0ykXSAw6dfFmB1LIqXP/jdd0ZMnlvlGgEMkMt+weJIl8Ynq1DsuBY9WwkNyzWktdqcEW2VN0RAtQg==",
- "peerDependencies": {
- "jss": "^9.4.0"
+ "node_modules/jss-plugin-expand": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-expand/-/jss-plugin-expand-10.8.2.tgz",
+ "integrity": "sha512-Iy4qsZbEcomXz5aBZJYGwnzK23vK3hqlwGleqmd19fY3L+WbqTmUnW8W0fWeXSuCkw2NknBTAJuEpFcgm3b0Pw==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2"
}
},
- "node_modules/jss-extend": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/jss-extend/-/jss-extend-6.2.0.tgz",
- "integrity": "sha512-YszrmcB6o9HOsKPszK7NeDBNNjVyiW864jfoiHoMlgMIg2qlxKw70axZHqgczXHDcoyi/0/ikP1XaHDPRvYtEA==",
+ "node_modules/jss-plugin-extend": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-extend/-/jss-plugin-extend-10.8.2.tgz",
+ "integrity": "sha512-NYu0cJ/Zb50ySPkegzbXQQfhXza0VpaRVXdXDex30yXqZpGcAdmhSg4HTv8vzHiL1v3uIOm641FYQX9WvLgSWw==",
"dependencies": {
- "warning": "^3.0.0"
- },
- "peerDependencies": {
- "jss": "^9.7.0"
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "tiny-warning": "^1.0.2"
}
},
- "node_modules/jss-global": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/jss-global/-/jss-global-3.0.0.tgz",
- "integrity": "sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q==",
- "peerDependencies": {
- "jss": "^9.0.0"
+ "node_modules/jss-plugin-global": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.8.2.tgz",
+ "integrity": "sha512-UaYMSPsYZ7s/ECGoj4KoHC2jwQd5iQ7K+FFGnCAILdQrv7hPmvM2Ydg45ThT/sH46DqktCRV2SqjRuxeBH8nRA==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2"
}
},
- "node_modules/jss-nested": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-6.0.1.tgz",
- "integrity": "sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA==",
+ "node_modules/jss-plugin-nested": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.8.2.tgz",
+ "integrity": "sha512-acRvuPJOb930fuYmhkJaa994EADpt8TxI63Iyg96C8FJ9T2xRyU5T6R1IYKRwUiqZo+2Sr7fdGzRTDD4uBZaMA==",
"dependencies": {
- "warning": "^3.0.0"
- },
- "peerDependencies": {
- "jss": "^9.0.0"
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "tiny-warning": "^1.0.2"
}
},
- "node_modules/jss-preset-default": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-4.5.0.tgz",
- "integrity": "sha512-qZbpRVtHT7hBPpZEBPFfafZKWmq3tA/An5RNqywDsZQGrlinIF/mGD9lmj6jGqu8GrED2SMHZ3pPKLmjCZoiaQ==",
- "dependencies": {
- "jss-camel-case": "^6.1.0",
- "jss-compose": "^5.0.0",
- "jss-default-unit": "^8.0.2",
- "jss-expand": "^5.3.0",
- "jss-extend": "^6.2.0",
- "jss-global": "^3.0.0",
- "jss-nested": "^6.0.1",
- "jss-props-sort": "^6.0.0",
- "jss-template": "^1.0.1",
- "jss-vendor-prefixer": "^7.0.0"
- },
- "peerDependencies": {
- "jss": "^9.7.0"
+ "node_modules/jss-plugin-props-sort": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.8.2.tgz",
+ "integrity": "sha512-wqdcjayKRWBZnNpLUrXvsWqh+5J5YToAQ+8HNBNw0kZxVvCDwzhK2Nx6AKs7p+5/MbAh2PLgNW5Ym/ysbVAuqQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2"
}
},
- "node_modules/jss-props-sort": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-6.0.0.tgz",
- "integrity": "sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g==",
- "peerDependencies": {
- "jss": "^9.0.0"
+ "node_modules/jss-plugin-rule-value-function": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.8.2.tgz",
+ "integrity": "sha512-bW0EKAs+0HXpb6BKJhrn94IDdiWb0CnSluTkh0rGEgyzY/nmD1uV/Wf6KGlesGOZ9gmJzQy+9FFdxIUID1c9Ug==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "tiny-warning": "^1.0.2"
}
},
- "node_modules/jss-template": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/jss-template/-/jss-template-1.0.1.tgz",
- "integrity": "sha512-m5BqEWha17fmIVXm1z8xbJhY6GFJxNB9H68GVnCWPyGYfxiAgY9WTQyvDAVj+pYRgrXSOfN5V1T4+SzN1sJTeg==",
+ "node_modules/jss-plugin-rule-value-observable": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-observable/-/jss-plugin-rule-value-observable-10.8.2.tgz",
+ "integrity": "sha512-NaJCfsEg8/6l/E8HstwL2w8kHj2LHhwoG4fXxefmdvNKmJMwBpnjech5dEPL72It4bZfIIYoynWbyxo3Q0ZKQQ==",
"dependencies": {
- "warning": "^3.0.0"
- },
- "peerDependencies": {
- "jss": "^9.0.0"
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "symbol-observable": "^1.2.0"
}
},
- "node_modules/jss-vendor-prefixer": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz",
- "integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==",
+ "node_modules/jss-plugin-template": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-template/-/jss-plugin-template-10.8.2.tgz",
+ "integrity": "sha512-oTVwYRUCuCLslHxuH73F15kFmDxc4YEJIn8kHBnNpGr99ZbQdRIgPabosVTfkgE8czuyTx0KM5u8zEeuL+v66A==",
"dependencies": {
- "css-vendor": "^0.3.8"
- },
- "peerDependencies": {
- "jss": "^9.0.0"
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "tiny-warning": "^1.0.2"
+ }
+ },
+ "node_modules/jss-plugin-vendor-prefixer": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.8.2.tgz",
+ "integrity": "sha512-DeGv18QsSiYLSVIEB2+l0af6OToUe0JB+trpzUxyqD2QRC/5AzzDrCrYffO5AHZ81QbffYvSN/pkfZaTWpRXlg==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "css-vendor": "^2.0.8",
+ "jss": "10.8.2"
+ }
+ },
+ "node_modules/jss-preset-default": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-10.8.2.tgz",
+ "integrity": "sha512-mgkr6DAZuvkEleHFEpOkm8Y+sTdK/r0HH8PxToLHgaWHbYS0JAb0g1tBSUMG24kFj98VOYLTllK1o0J4lWU/uw==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "jss-plugin-camel-case": "10.8.2",
+ "jss-plugin-compose": "10.8.2",
+ "jss-plugin-default-unit": "10.8.2",
+ "jss-plugin-expand": "10.8.2",
+ "jss-plugin-extend": "10.8.2",
+ "jss-plugin-global": "10.8.2",
+ "jss-plugin-nested": "10.8.2",
+ "jss-plugin-props-sort": "10.8.2",
+ "jss-plugin-rule-value-function": "10.8.2",
+ "jss-plugin-rule-value-observable": "10.8.2",
+ "jss-plugin-template": "10.8.2",
+ "jss-plugin-vendor-prefixer": "10.8.2"
}
},
"node_modules/jsx-ast-utils": {
@@ -21173,32 +21206,48 @@
}
},
"node_modules/mobx-react": {
- "version": "5.4.4",
- "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-5.4.4.tgz",
- "integrity": "sha512-2mTzpyEjVB/RGk2i6KbcmP4HWcAUFox5ZRCrGvSyz49w20I4C4qql63grPpYrS9E9GKwgydBHQlA4y665LuRCQ==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-6.3.1.tgz",
+ "integrity": "sha512-IOxdJGnRSNSJrL2uGpWO5w9JH5q5HoxEqwOF4gye1gmZYdjoYkkMzSGMDnRCUpN/BNzZcFoMdHXrjvkwO7KgaQ==",
"dependencies": {
- "hoist-non-react-statics": "^3.0.0",
- "react-lifecycles-compat": "^3.0.2"
+ "mobx-react-lite": "^2.2.0"
},
"peerDependencies": {
- "mobx": "^4.0.0 || ^5.0.0",
- "react": "^0.13.0 || ^0.14.0 || ^15.0.0 || ^16.0.0"
+ "mobx": "^5.15.4 || ^4.15.4",
+ "react": "^16.8.0 || 16.9.0-alpha.0"
}
},
"node_modules/mobx-react-form": {
- "version": "1.35.1",
- "resolved": "https://registry.npmjs.org/mobx-react-form/-/mobx-react-form-1.35.1.tgz",
- "integrity": "sha1-iSrsZykiThHCl4+4LmetxOgOOmo=",
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/mobx-react-form/-/mobx-react-form-2.0.9.tgz",
+ "integrity": "sha512-YLbtXVUF6BtifeVr6XWJ76dQWJs3T/+aPNI/DKvNs1Opcl4jNCzENahqlqNsNI+RgXZbP36zck//IGWBNZsr0A==",
"dependencies": {
- "lodash": "^4.16.2"
+ "lodash": "^4.17.11"
},
"engines": {
- "node": ">=6.0.0"
+ "node": ">=8.0.0"
},
"peerDependencies": {
"mobx": "^2.5.0 || ^3.0.0 || ^4.0.0 || ^5.0.0"
}
},
+ "node_modules/mobx-react-lite": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-2.2.2.tgz",
+ "integrity": "sha512-2SlXALHIkyUPDsV4VTKVR9DW7K3Ksh1aaIv3NrNJygTbhXe2A9GrcKHZ2ovIiOp/BXilOcTYemfHHZubP431dg==",
+ "peerDependencies": {
+ "mobx": "^4.0.0 || ^5.0.0",
+ "react": "^16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
"node_modules/mobx-react-router": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/mobx-react-router/-/mobx-react-router-3.1.2.tgz",
@@ -24552,6 +24601,11 @@
"react": "^16.3.0 || ^17.0.1"
}
},
+ "node_modules/react-display-name": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/react-display-name/-/react-display-name-0.2.5.tgz",
+ "integrity": "sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg=="
+ },
"node_modules/react-dom": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
@@ -24625,40 +24679,24 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-jss": {
- "version": "8.6.1",
- "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.6.1.tgz",
- "integrity": "sha512-SH6XrJDJkAphp602J14JTy3puB2Zxz1FkM3bKVE8wON+va99jnUTKWnzGECb3NfIn9JPR5vHykge7K3/A747xQ==",
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-10.8.2.tgz",
+ "integrity": "sha512-/lLFIv1H6GA5RkvNb7TdXcJMBaSvSpfmSYsDisj4WI7MmqXUouoKfkZUJzG7CWq8xnIxik0WWYjFcGOvx0Sasw==",
"dependencies": {
- "hoist-non-react-statics": "^2.5.0",
- "jss": "^9.7.0",
- "jss-preset-default": "^4.3.0",
+ "@babel/runtime": "^7.3.1",
+ "@emotion/is-prop-valid": "^0.7.3",
+ "css-jss": "10.8.2",
+ "hoist-non-react-statics": "^3.2.0",
+ "is-in-browser": "^1.1.3",
+ "jss": "10.8.2",
+ "jss-preset-default": "10.8.2",
"prop-types": "^15.6.0",
- "theming": "^1.3.0"
- },
- "engines": {
- "node": ">=4"
+ "shallow-equal": "^1.2.0",
+ "theming": "^3.3.0",
+ "tiny-warning": "^1.0.2"
},
"peerDependencies": {
- "react": ">=0.13"
- }
- },
- "node_modules/react-jss/node_modules/hoist-non-react-statics": {
- "version": "2.5.5",
- "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
- "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
- },
- "node_modules/react-jss/node_modules/jss": {
- "version": "9.8.7",
- "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz",
- "integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==",
- "hasInstallScript": true,
- "dependencies": {
- "is-in-browser": "^1.1.3",
- "symbol-observable": "^1.1.0",
- "warning": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
+ "react": ">=16.8.6"
}
},
"node_modules/react-lifecycles-compat": {
@@ -26490,6 +26528,11 @@
"node": ">=8"
}
},
+ "node_modules/shallow-equal": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
+ "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -28065,17 +28108,20 @@
"dev": true
},
"node_modules/theming": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/theming/-/theming-1.3.0.tgz",
- "integrity": "sha512-ya5Ef7XDGbTPBv5ENTwrwkPUexrlPeiAg/EI9kdlUAZhNlRbCdhMKRgjNX1IcmsmiPcqDQZE6BpSaH+cr31FKw==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/theming/-/theming-3.3.0.tgz",
+ "integrity": "sha512-u6l4qTJRDaWZsqa8JugaNt7Xd8PPl9+gonZaIe28vAhqgHMIG/DOyFPqiKN/gQLQYj05tHv+YQdNILL4zoiAVA==",
"dependencies": {
- "brcast": "^3.0.1",
- "is-function": "^1.0.1",
- "is-plain-object": "^2.0.1",
- "prop-types": "^15.5.8"
+ "hoist-non-react-statics": "^3.3.0",
+ "prop-types": "^15.5.8",
+ "react-display-name": "^0.2.4",
+ "tiny-warning": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=8"
},
"peerDependencies": {
- "react": ">=0.15"
+ "react": ">=16.3"
}
},
"node_modules/throat": {
@@ -33729,6 +33775,19 @@
}
}
},
+ "@emotion/is-prop-valid": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz",
+ "integrity": "sha512-uxJqm/sqwXw3YPA5GXX365OBcJGFtxUVkB6WyezqFHlNe9jqUWH5ur2O2M8dGBz61kn1g3ZBlzUunFQXQIClhA==",
+ "requires": {
+ "@emotion/memoize": "0.7.1"
+ }
+ },
+ "@emotion/memoize": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.1.tgz",
+ "integrity": "sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg=="
+ },
"@endemolshinegroup/cosmiconfig-typescript-loader": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz",
@@ -37695,11 +37754,6 @@
"to-regex": "^3.0.1"
}
},
- "brcast": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.2.tgz",
- "integrity": "sha512-f5XwwFCCuvgqP2nMH/hJ74FqnGmb4X3D+NC//HphxJzzhsZvSZa+Hk/syB7j3ZHpPDLMoYU8oBgviRWfNvEfKA=="
- },
"brorand": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
@@ -39589,6 +39643,16 @@
"uid-safe": "2.1.5"
}
},
+ "css-jss": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/css-jss/-/css-jss-10.8.2.tgz",
+ "integrity": "sha512-KjsoKnBV4C9p+F+zW9jNXCai0UYU5K+3eyo+lJX/fY8UBEQd/yNREnHsLD1VMMzBwHRvrA8eQHvqmAL+XNLYcw==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "jss-preset-default": "10.8.2"
+ }
+ },
"css-select": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz",
@@ -39621,10 +39685,11 @@
}
},
"css-vendor": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz",
- "integrity": "sha1-ZCHP0wNM5mT+dnOXL9ARn8KJQfo=",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
+ "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
"requires": {
+ "@babel/runtime": "^7.8.3",
"is-in-browser": "^1.0.2"
}
},
@@ -44767,11 +44832,6 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
},
- "is-function": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz",
- "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ=="
- },
"is-generator-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
@@ -46868,89 +46928,141 @@
"tiny-warning": "^1.0.2"
}
},
- "jss-camel-case": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-6.1.0.tgz",
- "integrity": "sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ==",
+ "jss-plugin-camel-case": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.8.2.tgz",
+ "integrity": "sha512-2INyxR+1UdNuKf4v9It3tNfPvf7IPrtkiwzofeKuMd5D58/dxDJVUQYRVg/n460rTlHUfsEQx43hDrcxi9dSPA==",
"requires": {
- "hyphenate-style-name": "^1.0.2"
+ "@babel/runtime": "^7.3.1",
+ "hyphenate-style-name": "^1.0.3",
+ "jss": "10.8.2"
}
},
- "jss-compose": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/jss-compose/-/jss-compose-5.0.0.tgz",
- "integrity": "sha512-YofRYuiA0+VbeOw0VjgkyO380sA4+TWDrW52nSluD9n+1FWOlDzNbgpZ/Sb3Y46+DcAbOS21W5jo6SAqUEiuwA==",
+ "jss-plugin-compose": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-compose/-/jss-plugin-compose-10.8.2.tgz",
+ "integrity": "sha512-X7fDQJ6IlIJoT8A3zc++LuC1hmSGKVudb3LyXp+vHv8r2hzzfXEEZty3y2CaC5CGrWcLlYquXENjqLNmLYMgMA==",
"requires": {
- "warning": "^3.0.0"
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "tiny-warning": "^1.0.2"
}
},
- "jss-default-unit": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-8.0.2.tgz",
- "integrity": "sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg=="
+ "jss-plugin-default-unit": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.8.2.tgz",
+ "integrity": "sha512-UZ7cwT9NFYSG+SEy7noRU50s4zifulFdjkUNKE+u6mW7vFP960+RglWjTgMfh79G6OENZmaYnjHV/gcKV4nSxg==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2"
+ }
},
- "jss-expand": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/jss-expand/-/jss-expand-5.3.0.tgz",
- "integrity": "sha512-NiM4TbDVE0ykXSAw6dfFmB1LIqXP/jdd0ZMnlvlGgEMkMt+weJIl8Ynq1DsuBY9WwkNyzWktdqcEW2VN0RAtQg=="
+ "jss-plugin-expand": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-expand/-/jss-plugin-expand-10.8.2.tgz",
+ "integrity": "sha512-Iy4qsZbEcomXz5aBZJYGwnzK23vK3hqlwGleqmd19fY3L+WbqTmUnW8W0fWeXSuCkw2NknBTAJuEpFcgm3b0Pw==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2"
+ }
},
- "jss-extend": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/jss-extend/-/jss-extend-6.2.0.tgz",
- "integrity": "sha512-YszrmcB6o9HOsKPszK7NeDBNNjVyiW864jfoiHoMlgMIg2qlxKw70axZHqgczXHDcoyi/0/ikP1XaHDPRvYtEA==",
+ "jss-plugin-extend": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-extend/-/jss-plugin-extend-10.8.2.tgz",
+ "integrity": "sha512-NYu0cJ/Zb50ySPkegzbXQQfhXza0VpaRVXdXDex30yXqZpGcAdmhSg4HTv8vzHiL1v3uIOm641FYQX9WvLgSWw==",
"requires": {
- "warning": "^3.0.0"
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "tiny-warning": "^1.0.2"
}
},
- "jss-global": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/jss-global/-/jss-global-3.0.0.tgz",
- "integrity": "sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q=="
+ "jss-plugin-global": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.8.2.tgz",
+ "integrity": "sha512-UaYMSPsYZ7s/ECGoj4KoHC2jwQd5iQ7K+FFGnCAILdQrv7hPmvM2Ydg45ThT/sH46DqktCRV2SqjRuxeBH8nRA==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2"
+ }
},
- "jss-nested": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-6.0.1.tgz",
- "integrity": "sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA==",
+ "jss-plugin-nested": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.8.2.tgz",
+ "integrity": "sha512-acRvuPJOb930fuYmhkJaa994EADpt8TxI63Iyg96C8FJ9T2xRyU5T6R1IYKRwUiqZo+2Sr7fdGzRTDD4uBZaMA==",
"requires": {
- "warning": "^3.0.0"
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "tiny-warning": "^1.0.2"
}
},
- "jss-preset-default": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-4.5.0.tgz",
- "integrity": "sha512-qZbpRVtHT7hBPpZEBPFfafZKWmq3tA/An5RNqywDsZQGrlinIF/mGD9lmj6jGqu8GrED2SMHZ3pPKLmjCZoiaQ==",
- "requires": {
- "jss-camel-case": "^6.1.0",
- "jss-compose": "^5.0.0",
- "jss-default-unit": "^8.0.2",
- "jss-expand": "^5.3.0",
- "jss-extend": "^6.2.0",
- "jss-global": "^3.0.0",
- "jss-nested": "^6.0.1",
- "jss-props-sort": "^6.0.0",
- "jss-template": "^1.0.1",
- "jss-vendor-prefixer": "^7.0.0"
- }
- },
- "jss-props-sort": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-6.0.0.tgz",
- "integrity": "sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g=="
+ "jss-plugin-props-sort": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.8.2.tgz",
+ "integrity": "sha512-wqdcjayKRWBZnNpLUrXvsWqh+5J5YToAQ+8HNBNw0kZxVvCDwzhK2Nx6AKs7p+5/MbAh2PLgNW5Ym/ysbVAuqQ==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2"
+ }
},
- "jss-template": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/jss-template/-/jss-template-1.0.1.tgz",
- "integrity": "sha512-m5BqEWha17fmIVXm1z8xbJhY6GFJxNB9H68GVnCWPyGYfxiAgY9WTQyvDAVj+pYRgrXSOfN5V1T4+SzN1sJTeg==",
+ "jss-plugin-rule-value-function": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.8.2.tgz",
+ "integrity": "sha512-bW0EKAs+0HXpb6BKJhrn94IDdiWb0CnSluTkh0rGEgyzY/nmD1uV/Wf6KGlesGOZ9gmJzQy+9FFdxIUID1c9Ug==",
"requires": {
- "warning": "^3.0.0"
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "tiny-warning": "^1.0.2"
}
},
- "jss-vendor-prefixer": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz",
- "integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==",
+ "jss-plugin-rule-value-observable": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-observable/-/jss-plugin-rule-value-observable-10.8.2.tgz",
+ "integrity": "sha512-NaJCfsEg8/6l/E8HstwL2w8kHj2LHhwoG4fXxefmdvNKmJMwBpnjech5dEPL72It4bZfIIYoynWbyxo3Q0ZKQQ==",
"requires": {
- "css-vendor": "^0.3.8"
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "symbol-observable": "^1.2.0"
+ }
+ },
+ "jss-plugin-template": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-template/-/jss-plugin-template-10.8.2.tgz",
+ "integrity": "sha512-oTVwYRUCuCLslHxuH73F15kFmDxc4YEJIn8kHBnNpGr99ZbQdRIgPabosVTfkgE8czuyTx0KM5u8zEeuL+v66A==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "tiny-warning": "^1.0.2"
+ }
+ },
+ "jss-plugin-vendor-prefixer": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.8.2.tgz",
+ "integrity": "sha512-DeGv18QsSiYLSVIEB2+l0af6OToUe0JB+trpzUxyqD2QRC/5AzzDrCrYffO5AHZ81QbffYvSN/pkfZaTWpRXlg==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "css-vendor": "^2.0.8",
+ "jss": "10.8.2"
+ }
+ },
+ "jss-preset-default": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-10.8.2.tgz",
+ "integrity": "sha512-mgkr6DAZuvkEleHFEpOkm8Y+sTdK/r0HH8PxToLHgaWHbYS0JAb0g1tBSUMG24kFj98VOYLTllK1o0J4lWU/uw==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.8.2",
+ "jss-plugin-camel-case": "10.8.2",
+ "jss-plugin-compose": "10.8.2",
+ "jss-plugin-default-unit": "10.8.2",
+ "jss-plugin-expand": "10.8.2",
+ "jss-plugin-extend": "10.8.2",
+ "jss-plugin-global": "10.8.2",
+ "jss-plugin-nested": "10.8.2",
+ "jss-plugin-props-sort": "10.8.2",
+ "jss-plugin-rule-value-function": "10.8.2",
+ "jss-plugin-rule-value-observable": "10.8.2",
+ "jss-plugin-template": "10.8.2",
+ "jss-plugin-vendor-prefixer": "10.8.2"
}
},
"jsx-ast-utils": {
@@ -48251,22 +48363,26 @@
}
},
"mobx-react": {
- "version": "5.4.4",
- "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-5.4.4.tgz",
- "integrity": "sha512-2mTzpyEjVB/RGk2i6KbcmP4HWcAUFox5ZRCrGvSyz49w20I4C4qql63grPpYrS9E9GKwgydBHQlA4y665LuRCQ==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-6.3.1.tgz",
+ "integrity": "sha512-IOxdJGnRSNSJrL2uGpWO5w9JH5q5HoxEqwOF4gye1gmZYdjoYkkMzSGMDnRCUpN/BNzZcFoMdHXrjvkwO7KgaQ==",
"requires": {
- "hoist-non-react-statics": "^3.0.0",
- "react-lifecycles-compat": "^3.0.2"
+ "mobx-react-lite": "^2.2.0"
}
},
"mobx-react-form": {
- "version": "1.35.1",
- "resolved": "https://registry.npmjs.org/mobx-react-form/-/mobx-react-form-1.35.1.tgz",
- "integrity": "sha1-iSrsZykiThHCl4+4LmetxOgOOmo=",
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/mobx-react-form/-/mobx-react-form-2.0.9.tgz",
+ "integrity": "sha512-YLbtXVUF6BtifeVr6XWJ76dQWJs3T/+aPNI/DKvNs1Opcl4jNCzENahqlqNsNI+RgXZbP36zck//IGWBNZsr0A==",
"requires": {
- "lodash": "^4.16.2"
+ "lodash": "^4.17.11"
}
},
+ "mobx-react-lite": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-2.2.2.tgz",
+ "integrity": "sha512-2SlXALHIkyUPDsV4VTKVR9DW7K3Ksh1aaIv3NrNJygTbhXe2A9GrcKHZ2ovIiOp/BXilOcTYemfHHZubP431dg=="
+ },
"mobx-react-router": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/mobx-react-router/-/mobx-react-router-3.1.2.tgz",
@@ -50927,6 +51043,11 @@
"tween-functions": "^1.2.0"
}
},
+ "react-display-name": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/react-display-name/-/react-display-name-0.2.5.tgz",
+ "integrity": "sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg=="
+ },
"react-dom": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
@@ -50978,32 +51099,21 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"react-jss": {
- "version": "8.6.1",
- "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.6.1.tgz",
- "integrity": "sha512-SH6XrJDJkAphp602J14JTy3puB2Zxz1FkM3bKVE8wON+va99jnUTKWnzGECb3NfIn9JPR5vHykge7K3/A747xQ==",
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-10.8.2.tgz",
+ "integrity": "sha512-/lLFIv1H6GA5RkvNb7TdXcJMBaSvSpfmSYsDisj4WI7MmqXUouoKfkZUJzG7CWq8xnIxik0WWYjFcGOvx0Sasw==",
"requires": {
- "hoist-non-react-statics": "^2.5.0",
- "jss": "^9.7.0",
- "jss-preset-default": "^4.3.0",
+ "@babel/runtime": "^7.3.1",
+ "@emotion/is-prop-valid": "^0.7.3",
+ "css-jss": "10.8.2",
+ "hoist-non-react-statics": "^3.2.0",
+ "is-in-browser": "^1.1.3",
+ "jss": "10.8.2",
+ "jss-preset-default": "10.8.2",
"prop-types": "^15.6.0",
- "theming": "^1.3.0"
- },
- "dependencies": {
- "hoist-non-react-statics": {
- "version": "2.5.5",
- "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
- "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
- },
- "jss": {
- "version": "9.8.7",
- "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz",
- "integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==",
- "requires": {
- "is-in-browser": "^1.1.3",
- "symbol-observable": "^1.1.0",
- "warning": "^3.0.0"
- }
- }
+ "shallow-equal": "^1.2.0",
+ "theming": "^3.3.0",
+ "tiny-warning": "^1.0.2"
}
},
"react-lifecycles-compat": {
@@ -52484,6 +52594,11 @@
"kind-of": "^6.0.2"
}
},
+ "shallow-equal": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
+ "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
+ },
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -53776,14 +53891,14 @@
"dev": true
},
"theming": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/theming/-/theming-1.3.0.tgz",
- "integrity": "sha512-ya5Ef7XDGbTPBv5ENTwrwkPUexrlPeiAg/EI9kdlUAZhNlRbCdhMKRgjNX1IcmsmiPcqDQZE6BpSaH+cr31FKw==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/theming/-/theming-3.3.0.tgz",
+ "integrity": "sha512-u6l4qTJRDaWZsqa8JugaNt7Xd8PPl9+gonZaIe28vAhqgHMIG/DOyFPqiKN/gQLQYj05tHv+YQdNILL4zoiAVA==",
"requires": {
- "brcast": "^3.0.1",
- "is-function": "^1.0.1",
- "is-plain-object": "^2.0.1",
- "prop-types": "^15.5.8"
+ "hoist-non-react-statics": "^3.3.0",
+ "prop-types": "^15.5.8",
+ "react-display-name": "^0.2.4",
+ "tiny-warning": "^1.0.2"
}
},
"throat": {
diff --git a/package.json b/package.json
index 5f733a501..8135f0ba3 100644
--- a/package.json
+++ b/package.json
@@ -88,8 +88,8 @@
"minimist": "^1.2.5",
"mobx": "^5.15.0",
"mobx-localstorage": "^1.2.0",
- "mobx-react": "^5.4.2",
- "mobx-react-form": "1.35.1",
+ "mobx-react": "^6.3.1",
+ "mobx-react-form": "^2.0.9",
"mobx-react-router": "^3.1.2",
"moment": "^2.29.1",
"ms": "^2.1.3",
@@ -105,7 +105,7 @@
"react-dropzone": "^11.4.2",
"react-electron-web-view": "^2.0.1",
"react-intl": "^5.21.0",
- "react-jss": "^8.6.1",
+ "react-jss": "^10.8.2",
"react-loader": "^2.4.7",
"react-modal": "^3.14.3",
"react-router": "^3.2.6",
diff --git a/src/I18n.tsx b/src/I18n.tsx
index 39b5273c1..5d969da1f 100644
--- a/src/I18n.tsx
+++ b/src/I18n.tsx
@@ -16,8 +16,6 @@ type Props = {
children: ReactNode;
};
-@inject('stores')
-@observer
class I18N extends Component {
componentDidUpdate() {
window['ferdi'].menu.rebuild();
@@ -39,4 +37,4 @@ class I18N extends Component {
}
}
-export default I18N;
+export default inject('stores')(observer(I18N));
diff --git a/src/components/auth/AuthLayout.js b/src/components/auth/AuthLayout.js
index f26282cfc..94ff5d54d 100644
--- a/src/components/auth/AuthLayout.js
+++ b/src/components/auth/AuthLayout.js
@@ -19,7 +19,6 @@ import AppUpdateInfoBar from '../AppUpdateInfoBar';
import { GITHUB_FERDI_URL } from '../../config';
import { Icon } from '../ui/icon';
-@observer
class AuthLayout extends Component {
static propTypes = {
children: oneOrManyChildElements.isRequired,
@@ -107,4 +106,4 @@ class AuthLayout extends Component {
}
}
-export default injectIntl(AuthLayout);
+export default injectIntl(observer(AuthLayout));
diff --git a/src/components/auth/ChangeServer.js b/src/components/auth/ChangeServer.js
index 9aeebc5c8..c284c0d19 100644
--- a/src/components/auth/ChangeServer.js
+++ b/src/components/auth/ChangeServer.js
@@ -34,7 +34,6 @@ const messages = defineMessages({
},
});
-@observer
class ChangeServer extends Component {
static propTypes = {
onSubmit: PropTypes.func.isRequired,
@@ -131,4 +130,4 @@ class ChangeServer extends Component {
}
}
-export default injectIntl(ChangeServer);
+export default injectIntl(observer(ChangeServer));
diff --git a/src/components/auth/Import.js b/src/components/auth/Import.js
index fe2fe9872..8f70318ed 100644
--- a/src/components/auth/Import.js
+++ b/src/components/auth/Import.js
@@ -28,7 +28,6 @@ const messages = defineMessages({
},
});
-@observer
class Import extends Component {
static propTypes = {
services: MobxPropTypes.arrayOrObservableArray.isRequired,
@@ -166,4 +165,4 @@ class Import extends Component {
}
}
-export default injectIntl(Import);
+export default injectIntl(observer(Import));
diff --git a/src/components/auth/Invite.js b/src/components/auth/Invite.js
index dd71c2450..a23af7c6b 100644
--- a/src/components/auth/Invite.js
+++ b/src/components/auth/Invite.js
@@ -43,7 +43,6 @@ const messages = defineMessages({
},
});
-@observer
class Invite extends Component {
static propTypes = {
onSubmit: PropTypes.func.isRequired,
@@ -198,4 +197,4 @@ class Invite extends Component {
}
}
-export default injectIntl(Invite);
+export default injectIntl(observer(Invite));
diff --git a/src/components/auth/Locked.js b/src/components/auth/Locked.js
index 5b36b9fc2..2ed429199 100644
--- a/src/components/auth/Locked.js
+++ b/src/components/auth/Locked.js
@@ -48,7 +48,6 @@ const messages = defineMessages({
},
});
-@observer
class Locked extends Component {
static propTypes = {
onSubmit: PropTypes.func.isRequired,
@@ -149,4 +148,4 @@ class Locked extends Component {
}
}
-export default injectIntl(Locked);
+export default injectIntl(observer(Locked));
diff --git a/src/components/auth/Login.js b/src/components/auth/Login.js
index 0c327d67e..c1602a047 100644
--- a/src/components/auth/Login.js
+++ b/src/components/auth/Login.js
@@ -71,8 +71,6 @@ const messages = defineMessages({
},
});
-@inject('actions')
-@observer
class Login extends Component {
static propTypes = {
onSubmit: PropTypes.func.isRequired,
@@ -215,4 +213,4 @@ class Login extends Component {
}
}
-export default injectIntl(Login);
+export default injectIntl(inject('actions')(observer(Login)));
diff --git a/src/components/auth/Password.js b/src/components/auth/Password.js
index d5bc7fa80..b4d51f43d 100644
--- a/src/components/auth/Password.js
+++ b/src/components/auth/Password.js
@@ -38,7 +38,6 @@ const messages = defineMessages({
},
});
-@observer
class Password extends Component {
static propTypes = {
onSubmit: PropTypes.func.isRequired,
@@ -119,4 +118,4 @@ class Password extends Component {
}
}
-export default injectIntl(Password);
+export default injectIntl(observer(Password));
diff --git a/src/components/auth/SetupAssistant.js b/src/components/auth/SetupAssistant.js
index 47fe88f43..a24f4e4d5 100644
--- a/src/components/auth/SetupAssistant.js
+++ b/src/components/auth/SetupAssistant.js
@@ -131,8 +131,6 @@ const styles = theme => ({
},
});
-@injectSheet(styles)
-@observer
class SetupAssistant extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -327,4 +325,6 @@ class SetupAssistant extends Component {
}
}
-export default injectIntl(SetupAssistant);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(SetupAssistant)),
+);
diff --git a/src/components/auth/Signup.js b/src/components/auth/Signup.js
index 00625a3ac..ac86dcdc3 100644
--- a/src/components/auth/Signup.js
+++ b/src/components/auth/Signup.js
@@ -75,8 +75,6 @@ const messages = defineMessages({
},
});
-@inject('actions')
-@observer
class Signup extends Component {
static propTypes = {
onSubmit: PropTypes.func.isRequired,
@@ -217,4 +215,4 @@ class Signup extends Component {
}
}
-export default injectIntl(Signup);
+export default injectIntl(inject('actions')(observer(Signup)));
diff --git a/src/components/auth/Welcome.js b/src/components/auth/Welcome.js
index 809ec67a7..794c78987 100644
--- a/src/components/auth/Welcome.js
+++ b/src/components/auth/Welcome.js
@@ -22,8 +22,6 @@ const messages = defineMessages({
},
});
-@inject('actions')
-@observer
class Login extends Component {
static propTypes = {
loginRoute: PropTypes.string.isRequired,
@@ -93,4 +91,4 @@ class Login extends Component {
}
}
-export default injectIntl(Login);
+export default injectIntl(inject('actions')(observer(Login)));
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index a31419a5e..084d93ecd 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -74,8 +74,6 @@ const toggleFullScreen = () => {
ipcRenderer.send('window.toolbar-double-clicked');
};
-@injectSheet(styles)
-@observer
class AppLayout extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -208,4 +206,6 @@ class AppLayout extends Component {
}
}
-export default injectIntl(AppLayout);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(AppLayout)),
+);
diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js
index 728613f42..4f67a8719 100644
--- a/src/components/layout/Sidebar.js
+++ b/src/components/layout/Sidebar.js
@@ -66,8 +66,6 @@ const messages = defineMessages({
},
});
-@inject('stores', 'actions')
-@observer
class Sidebar extends Component {
static propTypes = {
openSettings: PropTypes.func.isRequired,
@@ -262,4 +260,4 @@ class Sidebar extends Component {
}
}
-export default injectIntl(Sidebar);
+export default injectIntl(inject('stores', 'actions')(observer(Sidebar)));
diff --git a/src/components/services/content/ConnectionLostBanner.js b/src/components/services/content/ConnectionLostBanner.js
index b9e7eca53..5adb22c84 100644
--- a/src/components/services/content/ConnectionLostBanner.js
+++ b/src/components/services/content/ConnectionLostBanner.js
@@ -68,8 +68,6 @@ const styles = theme => ({
},
});
-@injectSheet(styles)
-@observer
class ConnectionLostBanner extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -103,4 +101,4 @@ class ConnectionLostBanner extends Component {
}
}
-export default injectIntl(ConnectionLostBanner);
+export default injectIntl(injectSheet(styles)(observer(ConnectionLostBanner)));
diff --git a/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js b/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js
index 5c93de80f..d605b3a52 100644
--- a/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js
+++ b/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js
@@ -31,8 +31,6 @@ const messages = defineMessages({
},
});
-@injectSheet(styles)
-@observer
class WebviewErrorHandler extends Component {
static propTypes = {
name: PropTypes.string.isRequired,
@@ -71,4 +69,6 @@ class WebviewErrorHandler extends Component {
}
}
-export default injectIntl(WebviewErrorHandler);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(WebviewErrorHandler)),
+);
diff --git a/src/components/services/content/ServiceDisabled.js b/src/components/services/content/ServiceDisabled.js
index f60d4bca6..b4658618e 100644
--- a/src/components/services/content/ServiceDisabled.js
+++ b/src/components/services/content/ServiceDisabled.js
@@ -16,7 +16,6 @@ const messages = defineMessages({
},
});
-@observer
class ServiceDisabled extends Component {
static propTypes = {
name: PropTypes.string.isRequired,
@@ -40,4 +39,4 @@ class ServiceDisabled extends Component {
}
}
-export default injectIntl(ServiceDisabled);
+export default injectIntl(observer(ServiceDisabled));
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js
index 1ffdd2153..6fc1f1400 100644
--- a/src/components/services/content/ServiceView.js
+++ b/src/components/services/content/ServiceView.js
@@ -16,8 +16,6 @@ import SettingsStore from '../../../stores/SettingsStore';
import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen';
import { CUSTOM_WEBSITE_RECIPE_ID } from '../../../config';
-@inject('stores', 'actions')
-@observer
class ServiceView extends Component {
static propTypes = {
service: PropTypes.instanceOf(ServiceModel).isRequired,
@@ -163,4 +161,4 @@ class ServiceView extends Component {
}
}
-export default ServiceView;
+export default inject('stores', 'actions')(observer(ServiceView));
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js
index c70494edd..713a0c21d 100644
--- a/src/components/services/content/ServiceWebview.js
+++ b/src/components/services/content/ServiceWebview.js
@@ -9,7 +9,6 @@ import ServiceModel from '../../../models/Service';
const debug = require('debug')('Ferdi:Services');
-@observer
class ServiceWebview extends Component {
static propTypes = {
service: PropTypes.instanceOf(ServiceModel).isRequired,
@@ -116,4 +115,4 @@ class ServiceWebview extends Component {
}
}
-export default ServiceWebview;
+export default observer(ServiceWebview);
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js
index 1edf31bd3..0587b553f 100644
--- a/src/components/services/content/Services.js
+++ b/src/components/services/content/Services.js
@@ -44,9 +44,6 @@ const styles = {
},
};
-@injectSheet(styles)
-@inject('actions')
-@observer
class Services extends Component {
static propTypes = {
services: MobxPropTypes.arrayOrObservableArray,
@@ -197,4 +194,8 @@ class Services extends Component {
}
}
-export default injectIntl(Services);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(
+ inject('actions')(observer(Services)),
+ ),
+);
diff --git a/src/components/services/content/WebviewCrashHandler.js b/src/components/services/content/WebviewCrashHandler.js
index 3607435b3..1ca5ba415 100644
--- a/src/components/services/content/WebviewCrashHandler.js
+++ b/src/components/services/content/WebviewCrashHandler.js
@@ -26,7 +26,6 @@ const messages = defineMessages({
},
});
-@observer
class WebviewCrashHandler extends Component {
static propTypes = {
name: PropTypes.string.isRequired,
@@ -81,4 +80,4 @@ class WebviewCrashHandler extends Component {
}
}
-export default injectIntl(WebviewCrashHandler);
+export default injectIntl(observer(WebviewCrashHandler));
diff --git a/src/components/services/tabs/TabBarSortableList.js b/src/components/services/tabs/TabBarSortableList.js
index 3049b6efa..e01461e5c 100644
--- a/src/components/services/tabs/TabBarSortableList.js
+++ b/src/components/services/tabs/TabBarSortableList.js
@@ -5,7 +5,6 @@ import { SortableContainer } from 'react-sortable-hoc';
import TabItem from './TabItem';
-@observer
class TabBarSortableList extends Component {
static propTypes = {
services: MobxPropTypes.arrayOrObservableArray.isRequired,
@@ -75,4 +74,4 @@ class TabBarSortableList extends Component {
}
}
-export default SortableContainer(TabBarSortableList);
+export default SortableContainer(observer(TabBarSortableList));
diff --git a/src/components/services/tabs/TabItem.js b/src/components/services/tabs/TabItem.js
index 14be37153..8e163bce6 100644
--- a/src/components/services/tabs/TabItem.js
+++ b/src/components/services/tabs/TabItem.js
@@ -114,9 +114,6 @@ const styles = {
},
};
-@injectSheet(styles)
-@inject('stores')
-@observer
class TabItem extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -402,4 +399,10 @@ class TabItem extends Component {
}
}
-export default injectIntl(SortableElement(TabItem));
+export default injectIntl(
+ SortableElement(
+ injectSheet(styles, { injectTheme: true })(
+ inject('stores')(observer(TabItem)),
+ ),
+ ),
+);
diff --git a/src/components/services/tabs/Tabbar.js b/src/components/services/tabs/Tabbar.js
index 94d6f33c1..d9e11df41 100644
--- a/src/components/services/tabs/Tabbar.js
+++ b/src/components/services/tabs/Tabbar.js
@@ -4,7 +4,6 @@ import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
import TabBarSortableList from './TabBarSortableList';
-@observer
class TabBar extends Component {
static propTypes = {
services: MobxPropTypes.arrayOrObservableArray.isRequired,
@@ -120,4 +119,4 @@ class TabBar extends Component {
}
}
-export default TabBar;
+export default observer(TabBar);
diff --git a/src/components/settings/SettingsLayout.js b/src/components/settings/SettingsLayout.js
index e9119a944..de13e95ab 100644
--- a/src/components/settings/SettingsLayout.js
+++ b/src/components/settings/SettingsLayout.js
@@ -16,7 +16,6 @@ const messages = defineMessages({
},
});
-@observer
class SettingsLayout extends Component {
static propTypes = {
navigation: PropTypes.element.isRequired,
@@ -78,4 +77,4 @@ class SettingsLayout extends Component {
}
}
-export default injectIntl(SettingsLayout);
+export default injectIntl(observer(SettingsLayout));
diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js
index 6c489e64b..d0c56af05 100644
--- a/src/components/settings/account/AccountDashboard.js
+++ b/src/components/settings/account/AccountDashboard.js
@@ -64,7 +64,6 @@ const messages = defineMessages({
},
});
-@observer
class AccountDashboard extends Component {
static propTypes = {
user: MobxPropTypes.observableObject.isRequired,
@@ -229,4 +228,4 @@ class AccountDashboard extends Component {
}
}
-export default injectIntl(AccountDashboard);
+export default injectIntl(observer(AccountDashboard));
diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.js
index dbb1365b0..2fdb6e574 100644
--- a/src/components/settings/navigation/SettingsNavigation.js
+++ b/src/components/settings/navigation/SettingsNavigation.js
@@ -42,8 +42,6 @@ const messages = defineMessages({
},
});
-@inject('stores', 'actions')
-@observer
class SettingsNavigation extends Component {
static propTypes = {
stores: PropTypes.shape({
@@ -175,4 +173,4 @@ class SettingsNavigation extends Component {
}
}
-export default injectIntl(SettingsNavigation);
+export default injectIntl(inject('stores', 'actions')(observer(SettingsNavigation)));
diff --git a/src/components/settings/recipes/RecipeItem.js b/src/components/settings/recipes/RecipeItem.js
index 1e910e6dc..df5b42222 100644
--- a/src/components/settings/recipes/RecipeItem.js
+++ b/src/components/settings/recipes/RecipeItem.js
@@ -4,7 +4,6 @@ import { observer } from 'mobx-react';
import RecipePreviewModel from '../../../models/RecipePreview';
-@observer
class RecipeItem extends Component {
static propTypes = {
recipe: PropTypes.instanceOf(RecipePreviewModel).isRequired,
@@ -31,4 +30,4 @@ class RecipeItem extends Component {
}
}
-export default RecipeItem;
+export default observer(RecipeItem);
diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js
index 7ec285431..d9f53d74e 100644
--- a/src/components/settings/recipes/RecipesDashboard.js
+++ b/src/components/settings/recipes/RecipesDashboard.js
@@ -105,8 +105,6 @@ const styles = {
},
};
-@injectSheet(styles)
-@observer
class RecipesDashboard extends Component {
static propTypes = {
recipes: MobxPropTypes.arrayOrObservableArray.isRequired,
@@ -247,16 +245,18 @@ class RecipesDashboard extends Component {
{intl.formatMessage(messages.nothingFound)}
-
- isLoggedIn &&
- showAddServiceInterface({
- recipeId: customWebsiteRecipe.id,
- })
- }
- />
+ {customWebsiteRecipe && customWebsiteRecipe.id && (
+
+ isLoggedIn &&
+ showAddServiceInterface({
+ recipeId: customWebsiteRecipe.id,
+ })
+ }
+ />
+ )}
)}
{communityRecipes.map(recipe => (
@@ -295,4 +295,6 @@ class RecipesDashboard extends Component {
}
}
-export default injectIntl(RecipesDashboard);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(RecipesDashboard)),
+);
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js
index 6b4cc721d..f0e791b87 100644
--- a/src/components/settings/services/EditServiceForm.js
+++ b/src/components/settings/services/EditServiceForm.js
@@ -134,7 +134,6 @@ const messages = defineMessages({
},
});
-@observer
class EditServiceForm extends Component {
static propTypes = {
recipe: PropTypes.instanceOf(Recipe).isRequired,
@@ -500,4 +499,4 @@ class EditServiceForm extends Component {
}
}
-export default injectIntl(EditServiceForm);
+export default injectIntl(observer(EditServiceForm));
diff --git a/src/components/settings/services/ServiceError.js b/src/components/settings/services/ServiceError.js
index 6dd53a102..bcbbca3de 100644
--- a/src/components/settings/services/ServiceError.js
+++ b/src/components/settings/services/ServiceError.js
@@ -25,7 +25,6 @@ const messages = defineMessages({
},
});
-@observer
class ServiceError extends Component {
render() {
const { intl } = this.props;
@@ -60,4 +59,4 @@ class ServiceError extends Component {
}
}
-export default injectIntl(ServiceError);
+export default injectIntl(observer(ServiceError));
diff --git a/src/components/settings/services/ServiceItem.js b/src/components/settings/services/ServiceItem.js
index d83e5fd56..23250ad09 100644
--- a/src/components/settings/services/ServiceItem.js
+++ b/src/components/settings/services/ServiceItem.js
@@ -24,7 +24,6 @@ const messages = defineMessages({
},
});
-@observer
class ServiceItem extends Component {
static propTypes = {
service: PropTypes.instanceOf(ServiceModel).isRequired,
@@ -91,4 +90,4 @@ class ServiceItem extends Component {
}
}
-export default injectIntl(ServiceItem);
+export default injectIntl(observer(ServiceItem));
diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js
index aae6eb855..81c5faa70 100644
--- a/src/components/settings/services/ServicesDashboard.js
+++ b/src/components/settings/services/ServicesDashboard.js
@@ -51,7 +51,6 @@ const messages = defineMessages({
},
});
-@observer
class ServicesDashboard extends Component {
static propTypes = {
services: MobxPropTypes.arrayOrObservableArray.isRequired,
@@ -188,4 +187,4 @@ class ServicesDashboard extends Component {
}
}
-export default injectIntl(ServicesDashboard);
+export default injectIntl(observer(ServicesDashboard));
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js
index 9f51b54d5..d9df9c41c 100644
--- a/src/components/settings/settings/EditSettingsForm.js
+++ b/src/components/settings/settings/EditSettingsForm.js
@@ -188,7 +188,6 @@ const messages = defineMessages({
const Hr = () =>
;
-@observer
class EditSettingsForm extends Component {
static propTypes = {
checkForUpdates: PropTypes.func.isRequired,
@@ -847,4 +846,4 @@ class EditSettingsForm extends Component {
}
}
-export default injectIntl(EditSettingsForm);
+export default injectIntl(observer(EditSettingsForm));
diff --git a/src/components/settings/team/TeamDashboard.js b/src/components/settings/team/TeamDashboard.js
index 38d124266..802284051 100644
--- a/src/components/settings/team/TeamDashboard.js
+++ b/src/components/settings/team/TeamDashboard.js
@@ -90,8 +90,6 @@ const styles = {
},
};
-@injectSheet(styles)
-@observer
class TeamDashboard extends Component {
static propTypes = {
isLoading: PropTypes.bool.isRequired,
@@ -197,4 +195,6 @@ class TeamDashboard extends Component {
}
}
-export default injectIntl(TeamDashboard);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(TeamDashboard)),
+);
diff --git a/src/components/settings/user/EditUserForm.js b/src/components/settings/user/EditUserForm.js
index 1b8a4f25a..95498d9bb 100644
--- a/src/components/settings/user/EditUserForm.js
+++ b/src/components/settings/user/EditUserForm.js
@@ -37,7 +37,6 @@ const messages = defineMessages({
},
});
-@observer
class EditUserForm extends Component {
static propTypes = {
status: MobxPropTypes.observableArray.isRequired,
@@ -128,4 +127,4 @@ class EditUserForm extends Component {
}
}
-export default injectIntl(EditUserForm);
+export default injectIntl(observer(EditUserForm));
diff --git a/src/components/ui/AppLoader/index.tsx b/src/components/ui/AppLoader/index.tsx
index c7c290a57..0bb9cb50f 100644
--- a/src/components/ui/AppLoader/index.tsx
+++ b/src/components/ui/AppLoader/index.tsx
@@ -1,7 +1,7 @@
import { Component } from 'react';
-import injectSheet, { withTheme } from 'react-jss';
import classnames from 'classnames';
+import injectStyle from 'react-jss';
import FullscreenLoader from '../FullscreenLoader';
import { shuffleArray } from '../../../helpers/array-helpers';
@@ -24,8 +24,6 @@ type Props = {
texts: string[];
};
-@injectSheet(styles)
-@withTheme
class AppLoader extends Component {
static defaultProps = {
texts: textList,
@@ -77,4 +75,4 @@ class AppLoader extends Component {
}
}
-export default AppLoader;
+export default injectStyle(styles, { injectTheme: true })(AppLoader);
diff --git a/src/components/ui/Button.js b/src/components/ui/Button.js
index d90a8d62d..a52f1cadb 100644
--- a/src/components/ui/Button.js
+++ b/src/components/ui/Button.js
@@ -4,8 +4,6 @@ import { observer, inject } from 'mobx-react';
import Loader from 'react-loader';
import classnames from 'classnames';
-@inject('stores')
-@observer
class Button extends Component {
static propTypes = {
className: PropTypes.string,
@@ -90,4 +88,4 @@ class Button extends Component {
}
}
-export default Button;
+export default inject('stores')(observer(Button));
diff --git a/src/components/ui/FAB.tsx b/src/components/ui/FAB.tsx
index 0d871e948..cb9c5f126 100644
--- a/src/components/ui/FAB.tsx
+++ b/src/components/ui/FAB.tsx
@@ -14,7 +14,6 @@ type Props = {
htmlForm: string;
};
-@observer
class Button extends Component {
static defaultProps = {
disabled: false,
@@ -46,4 +45,4 @@ class Button extends Component {
}
}
-export default Button;
+export default observer(Button);
diff --git a/src/components/ui/FullscreenLoader/index.js b/src/components/ui/FullscreenLoader/index.js
index f5943f3f3..39b6c5a4c 100644
--- a/src/components/ui/FullscreenLoader/index.js
+++ b/src/components/ui/FullscreenLoader/index.js
@@ -1,16 +1,13 @@
import { Component } from 'react';
import PropTypes from 'prop-types';
import { observer } from 'mobx-react';
-import injectSheet, { withTheme } from 'react-jss';
+import injectStyle from 'react-jss';
import classnames from 'classnames';
import Loader from '../Loader';
import styles from './styles';
-@withTheme
-@injectSheet(styles)
-@observer
class FullscreenLoader extends Component {
static propTypes = {
className: PropTypes.string,
@@ -48,4 +45,6 @@ class FullscreenLoader extends Component {
}
}
-export default FullscreenLoader;
+export default injectStyle(styles, { injectTheme: true })(
+ observer(FullscreenLoader),
+);
diff --git a/src/components/ui/ImageUpload.tsx b/src/components/ui/ImageUpload.tsx
index 52c097ef0..b07e211c2 100644
--- a/src/components/ui/ImageUpload.tsx
+++ b/src/components/ui/ImageUpload.tsx
@@ -15,7 +15,6 @@ type Props = {
textUpload: string;
};
-@observer
class ImageUpload extends Component {
static defaultProps = {
multiple: false,
@@ -102,4 +101,4 @@ class ImageUpload extends Component {
}
}
-export default ImageUpload;
+export default observer(ImageUpload);
diff --git a/src/components/ui/InfoBar.js b/src/components/ui/InfoBar.js
index 89b085907..c1a6013c2 100644
--- a/src/components/ui/InfoBar.js
+++ b/src/components/ui/InfoBar.js
@@ -16,7 +16,6 @@ const messages = defineMessages({
},
});
-@observer
class InfoBar extends Component {
static propTypes = {
// eslint-disable-next-line react/forbid-prop-types
@@ -102,4 +101,4 @@ class InfoBar extends Component {
}
}
-export default injectIntl(InfoBar);
+export default injectIntl(observer(InfoBar));
diff --git a/src/components/ui/Infobox.js b/src/components/ui/Infobox.js
index c0ba8f13c..6634a6808 100644
--- a/src/components/ui/Infobox.js
+++ b/src/components/ui/Infobox.js
@@ -19,7 +19,6 @@ const messages = defineMessages({
},
});
-@observer
class Infobox extends Component {
static propTypes = {
// eslint-disable-next-line react/forbid-prop-types
@@ -112,4 +111,4 @@ class Infobox extends Component {
}
}
-export default injectIntl(Infobox);
+export default injectIntl(observer(Infobox));
diff --git a/src/components/ui/Input.js b/src/components/ui/Input.js
index 8d37d7a05..fa1b44699 100644
--- a/src/components/ui/Input.js
+++ b/src/components/ui/Input.js
@@ -5,7 +5,9 @@ import { Field } from 'mobx-react-form';
import classnames from 'classnames';
import { defineMessages, injectIntl } from 'react-intl';
+import { mdiEye, mdiEyeOff } from '@mdi/js';
import { scorePassword as scorePasswordFunc } from '../../helpers/password-helpers';
+import { Icon } from './icon';
const messages = defineMessages({
passwordToggle: {
@@ -14,7 +16,6 @@ const messages = defineMessages({
},
});
-@observer
class Input extends Component {
static propTypes = {
field: PropTypes.instanceOf(Field).isRequired,
@@ -115,9 +116,6 @@ class Input extends Component {
type="button"
className={classnames({
'franz-form__input-modifier': true,
- mdi: true,
- 'mdi-eye': !this.state.showPassword,
- 'mdi-eye-off': this.state.showPassword,
})}
onClick={() =>
this.setState(prevState => ({
@@ -126,7 +124,9 @@ class Input extends Component {
}
tabIndex={-1}
aria-label={intl.formatMessage(messages.passwordToggle)}
- />
+ >
+
+
)}
{scorePassword && (
@@ -152,4 +152,4 @@ class Input extends Component {
}
}
-export default injectIntl(Input);
+export default injectIntl(observer(Input));
diff --git a/src/components/ui/Link.js b/src/components/ui/Link.js
index 40766c984..565547736 100644
--- a/src/components/ui/Link.js
+++ b/src/components/ui/Link.js
@@ -9,8 +9,6 @@ import { matchRoute } from '../../helpers/routing-helpers';
import { openExternalUrl } from '../../helpers/url-helpers';
// TODO: create container component for this component
-@inject('stores')
-@observer
class Link extends Component {
onClick(e) {
if (this.props.disabled) {
@@ -60,7 +58,7 @@ class Link extends Component {
}
}
-Link.wrappedComponent.propTypes = {
+Link.propTypes = {
stores: PropTypes.shape({
router: PropTypes.instanceOf(RouterStore).isRequired,
}).isRequired,
@@ -75,7 +73,7 @@ Link.wrappedComponent.propTypes = {
disabled: PropTypes.bool,
};
-Link.wrappedComponent.defaultProps = {
+Link.defaultProps = {
className: '',
activeClassName: '',
strictFilter: false,
@@ -84,4 +82,4 @@ Link.wrappedComponent.defaultProps = {
style: {},
};
-export default Link;
+export default inject('stores')(observer(Link));
diff --git a/src/components/ui/Loader.tsx b/src/components/ui/Loader.tsx
index 1173c11e7..171d0e290 100644
--- a/src/components/ui/Loader.tsx
+++ b/src/components/ui/Loader.tsx
@@ -12,8 +12,6 @@ type Props = {
stores: FerdiStores;
};
-@inject('stores')
-@observer
class LoaderComponent extends Component
{
static defaultProps = {
loaded: false,
@@ -43,4 +41,4 @@ class LoaderComponent extends Component {
}
}
-export default LoaderComponent;
+export default inject('stores')(observer(LoaderComponent));
diff --git a/src/components/ui/Modal/index.tsx b/src/components/ui/Modal/index.tsx
index f2f4461b8..c3c78b419 100644
--- a/src/components/ui/Modal/index.tsx
+++ b/src/components/ui/Modal/index.tsx
@@ -18,7 +18,6 @@ type Props = {
showClose: boolean;
};
-@injectCSS(styles)
class Modal extends Component {
static defaultProps = {
className: null,
@@ -64,4 +63,4 @@ class Modal extends Component {
}
}
-export default Modal;
+export default injectCSS(styles)(Modal);
diff --git a/src/components/ui/Radio.tsx b/src/components/ui/Radio.tsx
index 594ea70e4..a033a5fe0 100644
--- a/src/components/ui/Radio.tsx
+++ b/src/components/ui/Radio.tsx
@@ -10,7 +10,6 @@ type Props = {
showLabel: boolean;
};
-@observer
class Radio extends Component {
static defaultProps = {
focus: false,
@@ -74,4 +73,4 @@ class Radio extends Component {
}
}
-export default Radio;
+export default observer(Radio);
diff --git a/src/components/ui/SearchInput.tsx b/src/components/ui/SearchInput.tsx
index 49a50a4a0..6a6a1692e 100644
--- a/src/components/ui/SearchInput.tsx
+++ b/src/components/ui/SearchInput.tsx
@@ -17,7 +17,6 @@ type Props = {
autoFocus: boolean;
};
-@observer
class SearchInput extends Component {
static defaultProps = {
value: '',
@@ -115,4 +114,4 @@ class SearchInput extends Component {
}
}
-export default SearchInput;
+export default observer(SearchInput);
diff --git a/src/components/ui/Select.js b/src/components/ui/Select.js
index a560da332..0fc32e573 100644
--- a/src/components/ui/Select.js
+++ b/src/components/ui/Select.js
@@ -4,7 +4,6 @@ import { observer } from 'mobx-react';
import { Field } from 'mobx-react-form';
import classnames from 'classnames';
-@observer
class Select extends Component {
static propTypes = {
field: PropTypes.instanceOf(Field).isRequired,
@@ -98,4 +97,4 @@ class Select extends Component {
}
}
-export default Select;
+export default observer(Select);
diff --git a/src/components/ui/ServiceIcon.js b/src/components/ui/ServiceIcon.js
index f067f8955..d403d107d 100644
--- a/src/components/ui/ServiceIcon.js
+++ b/src/components/ui/ServiceIcon.js
@@ -24,8 +24,6 @@ const styles = theme => ({
},
});
-@injectSheet(styles)
-@observer
class ServiceIcon extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -56,4 +54,6 @@ class ServiceIcon extends Component {
}
}
-export default ServiceIcon;
+export default injectSheet(styles, { injectTheme: true })(
+ observer(ServiceIcon),
+);
diff --git a/src/components/ui/Slider.js b/src/components/ui/Slider.js
index dea6e0563..a581e7a65 100644
--- a/src/components/ui/Slider.js
+++ b/src/components/ui/Slider.js
@@ -4,7 +4,6 @@ import { observer } from 'mobx-react';
import classnames from 'classnames';
import { Field } from 'mobx-react-form';
-@observer
class Slider extends Component {
static propTypes = {
field: PropTypes.instanceOf(Field).isRequired,
@@ -64,4 +63,4 @@ class Slider extends Component {
}
}
-export default Slider;
+export default observer(Slider);
diff --git a/src/components/ui/StatusBarTargetUrl.js b/src/components/ui/StatusBarTargetUrl.js
index 38b436742..d8d329d52 100644
--- a/src/components/ui/StatusBarTargetUrl.js
+++ b/src/components/ui/StatusBarTargetUrl.js
@@ -5,7 +5,6 @@ import classnames from 'classnames';
import Appear from './effects/Appear';
-@observer
class StatusBarTargetUrl extends Component {
static propTypes = {
className: PropTypes.string,
@@ -33,4 +32,4 @@ class StatusBarTargetUrl extends Component {
}
}
-export default StatusBarTargetUrl;
+export default observer(StatusBarTargetUrl);
diff --git a/src/components/ui/Tabs/Tabs.js b/src/components/ui/Tabs/Tabs.js
index 77803974b..5d2da6293 100644
--- a/src/components/ui/Tabs/Tabs.js
+++ b/src/components/ui/Tabs/Tabs.js
@@ -5,7 +5,6 @@ import classnames from 'classnames';
import { oneOrManyChildElements } from '../../../prop-types';
-@observer
class Tab extends Component {
constructor(props) {
super(props);
@@ -69,4 +68,4 @@ class Tab extends Component {
}
}
-export default Tab;
+export default observer(Tab);
diff --git a/src/components/ui/Toggle.js b/src/components/ui/Toggle.js
index dfc319735..a82be690e 100644
--- a/src/components/ui/Toggle.js
+++ b/src/components/ui/Toggle.js
@@ -4,7 +4,6 @@ import { observer } from 'mobx-react';
import classnames from 'classnames';
import { Field } from 'mobx-react-form';
-@observer
class Toggle extends Component {
static propTypes = {
field: PropTypes.instanceOf(Field).isRequired,
@@ -69,4 +68,4 @@ class Toggle extends Component {
}
}
-export default Toggle;
+export default observer(Toggle);
diff --git a/src/components/ui/ToggleRaw.js b/src/components/ui/ToggleRaw.js
index 74292a870..e482b97b4 100644
--- a/src/components/ui/ToggleRaw.js
+++ b/src/components/ui/ToggleRaw.js
@@ -6,7 +6,6 @@ import PropTypes from 'prop-types';
import { observer } from 'mobx-react';
import classnames from 'classnames';
-@observer
class ToggleRaw extends Component {
static propTypes = {
onChange: PropTypes.func.isRequired,
@@ -74,4 +73,4 @@ class ToggleRaw extends Component {
}
}
-export default ToggleRaw;
+export default observer(ToggleRaw);
diff --git a/src/components/ui/WebviewLoader/index.js b/src/components/ui/WebviewLoader/index.js
index 8d4513172..20945d191 100644
--- a/src/components/ui/WebviewLoader/index.js
+++ b/src/components/ui/WebviewLoader/index.js
@@ -14,8 +14,6 @@ const messages = defineMessages({
},
});
-@injectSheet(styles)
-@observer
class WebviewLoader extends Component {
static propTypes = {
name: PropTypes.string.isRequired,
@@ -34,4 +32,6 @@ class WebviewLoader extends Component {
}
}
-export default injectIntl(WebviewLoader);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(WebviewLoader)),
+);
diff --git a/src/components/ui/badge/ProBadge.tsx b/src/components/ui/badge/ProBadge.tsx
index dc1e76f7f..410748a64 100644
--- a/src/components/ui/badge/ProBadge.tsx
+++ b/src/components/ui/badge/ProBadge.tsx
@@ -1,14 +1,13 @@
import { mdiStar } from '@mdi/js';
import classnames from 'classnames';
import { Component } from 'react';
-import injectStyle from 'react-jss';
+import injectStyle, { WithStylesProps } from 'react-jss';
import { Theme } from '../../../themes';
import { Icon } from '../icon';
import { Badge } from './index';
-import { IWithStyle } from '../typings/generic';
-interface IProps extends IWithStyle {
+interface IProps extends WithStylesProps {
badgeClasses?: string;
iconClasses?: string;
inverted?: boolean;
@@ -61,4 +60,6 @@ class ProBadgeComponent extends Component {
}
}
-export const ProBadge = injectStyle(styles)(ProBadgeComponent);
+export const ProBadge = injectStyle(styles, { injectTheme: true })(
+ ProBadgeComponent,
+);
diff --git a/src/components/ui/badge/index.tsx b/src/components/ui/badge/index.tsx
index 61bede937..a7ed866a5 100644
--- a/src/components/ui/badge/index.tsx
+++ b/src/components/ui/badge/index.tsx
@@ -1,11 +1,10 @@
import classnames from 'classnames';
import { Component, ReactNode } from 'react';
-import injectStyle from 'react-jss';
+import injectStyle, { WithStylesProps } from 'react-jss';
import { Theme } from '../../../themes';
-import { IWithStyle } from '../typings/generic';
-interface IProps extends IWithStyle {
+interface IProps extends WithStylesProps {
type: string;
className?: string;
children: ReactNode;
@@ -68,4 +67,4 @@ class BadgeComponent extends Component {
}
}
-export const Badge = injectStyle(styles)(BadgeComponent);
+export const Badge = injectStyle(styles, { injectTheme: true })(BadgeComponent);
diff --git a/src/components/ui/button/index.tsx b/src/components/ui/button/index.tsx
index 12e5e4449..d91b1ee19 100644
--- a/src/components/ui/button/index.tsx
+++ b/src/components/ui/button/index.tsx
@@ -2,11 +2,11 @@ import Icon from '@mdi/react';
import classnames from 'classnames';
import { Property } from 'csstype';
import { Component, MouseEvent } from 'react';
-import injectStyle, { withTheme } from 'react-jss';
+import injectStyle, { WithStylesProps } from 'react-jss';
import Loader from 'react-loader';
import { Theme } from '../../../themes';
-import { IFormField, IWithStyle } from '../typings/generic';
+import { IFormField } from '../typings/generic';
type ButtonType =
| 'primary'
@@ -16,7 +16,7 @@ type ButtonType =
| 'warning'
| 'inverted';
-interface IProps extends IFormField, IWithStyle {
+interface IProps extends IFormField, WithStylesProps {
className?: string;
disabled?: boolean;
id?: string;
@@ -179,7 +179,7 @@ class ButtonComponent extends Component {
const {
classes,
className,
- theme,
+ // theme,
disabled,
id,
label,
@@ -213,7 +213,7 @@ class ButtonComponent extends Component {
loaded={false}
width={4}
scale={0.45}
- color={theme.buttonLoaderColor[buttonType!]}
+ // color={theme.buttonLoaderColor[buttonType!]}
parentClassName={classes.loader}
/>
)}
@@ -262,4 +262,6 @@ class ButtonComponent extends Component {
}
}
-export const Button = injectStyle(styles)(withTheme(ButtonComponent));
+export const Button = injectStyle(styles, { injectTheme: true })(
+ ButtonComponent,
+);
diff --git a/src/components/ui/error/index.tsx b/src/components/ui/error/index.tsx
index 8439bfc8b..ff3bc31c6 100644
--- a/src/components/ui/error/index.tsx
+++ b/src/components/ui/error/index.tsx
@@ -17,4 +17,4 @@ class ErrorComponent extends Component {
}
}
-export const Error = injectSheet(styles)(ErrorComponent);
+export const Error = injectSheet(styles, { injectTheme: true })(ErrorComponent);
diff --git a/src/components/ui/headline/index.tsx b/src/components/ui/headline/index.tsx
index ea2949102..d9954c38f 100644
--- a/src/components/ui/headline/index.tsx
+++ b/src/components/ui/headline/index.tsx
@@ -1,11 +1,11 @@
import classnames from 'classnames';
import { Component, createElement, ReactNode } from 'react';
-import injectStyle from 'react-jss';
+import injectStyle, { WithStylesProps } from 'react-jss';
import { Theme } from '../../../themes';
-import { IWithStyle, Omit } from '../typings/generic';
+import { Omit } from '../typings/generic';
-interface IProps extends IWithStyle {
+interface IProps extends WithStylesProps {
level?: number;
className?: string;
children: string | ReactNode;
@@ -55,9 +55,9 @@ class HeadlineComponent extends Component {
}
}
-const Headline = injectStyle(styles)(HeadlineComponent);
+const Headline = injectStyle(styles, { injectTheme: true })(HeadlineComponent);
-const createH = (level: number) => (props: Omit) =>
+const createH = (level: number) => (props: Omit) =>
(
{props.children}
diff --git a/src/components/ui/icon/index.tsx b/src/components/ui/icon/index.tsx
index 85bb61d13..52f61d2d7 100644
--- a/src/components/ui/icon/index.tsx
+++ b/src/components/ui/icon/index.tsx
@@ -1,12 +1,11 @@
import MdiIcon from '@mdi/react';
import classnames from 'classnames';
import { Component } from 'react';
-import injectStyle from 'react-jss';
+import injectStyle, { WithStylesProps } from 'react-jss';
import { Theme } from '../../../themes';
-import { IWithStyle } from '../typings/generic';
-interface IProps extends IWithStyle {
+interface IProps extends WithStylesProps {
icon: string;
size?: number;
className?: string;
@@ -43,4 +42,4 @@ class IconComponent extends Component {
}
}
-export const Icon = injectStyle(styles)(IconComponent);
+export const Icon = injectStyle(styles, { injectTheme: true })(IconComponent);
diff --git a/src/components/ui/infobox/index.tsx b/src/components/ui/infobox/index.tsx
index 87940c4d4..7b2ce527b 100644
--- a/src/components/ui/infobox/index.tsx
+++ b/src/components/ui/infobox/index.tsx
@@ -1,13 +1,12 @@
import { mdiClose } from '@mdi/js';
import classnames from 'classnames';
import { Component, ReactNode } from 'react';
-import injectStyle from 'react-jss';
+import injectStyle, { WithStylesProps } from 'react-jss';
import { Theme } from '../../../themes';
import { Icon } from '../icon';
-import { IWithStyle } from '../typings/generic';
-interface IProps extends IWithStyle {
+interface IProps extends WithStylesProps {
icon?: string;
type?: string;
dismissable?: boolean;
@@ -202,4 +201,6 @@ class InfoboxComponent extends Component {
}
}
-export const Infobox = injectStyle(styles)(InfoboxComponent);
+export const Infobox = injectStyle(styles, { injectTheme: true })(
+ InfoboxComponent,
+);
diff --git a/src/components/ui/input/index.tsx b/src/components/ui/input/index.tsx
index c46cafc5c..bfbee33b9 100644
--- a/src/components/ui/input/index.tsx
+++ b/src/components/ui/input/index.tsx
@@ -2,9 +2,9 @@ import { mdiEye, mdiEyeOff } from '@mdi/js';
import Icon from '@mdi/react';
import classnames from 'classnames';
import { Component, createRef, InputHTMLAttributes } from 'react';
-import injectSheet from 'react-jss';
+import injectSheet, { WithStylesProps } from 'react-jss';
-import { IFormField, IWithStyle } from '../typings/generic';
+import { IFormField } from '../typings/generic';
import { Error } from '../error';
import { Label } from '../label';
@@ -20,7 +20,7 @@ interface IData {
interface IProps
extends InputHTMLAttributes,
IFormField,
- IWithStyle {
+ WithStylesProps {
focus?: boolean;
prefix?: string;
suffix?: string;
@@ -205,4 +205,4 @@ class InputComponent extends Component {
}
}
-export const Input = injectSheet(styles)(InputComponent);
+export const Input = injectSheet(styles, { injectTheme: true })(InputComponent);
diff --git a/src/components/ui/label/index.tsx b/src/components/ui/label/index.tsx
index 4d86f23f7..dcc14bff4 100644
--- a/src/components/ui/label/index.tsx
+++ b/src/components/ui/label/index.tsx
@@ -1,15 +1,16 @@
import classnames from 'classnames';
-import { Classes } from 'jss';
import { Component, LabelHTMLAttributes } from 'react';
-import injectSheet from 'react-jss';
+import injectSheet, { WithStylesProps } from 'react-jss';
import { IFormField } from '../typings/generic';
import styles from './styles';
-interface ILabel extends IFormField, LabelHTMLAttributes {
- classes: Classes;
- isRequired: boolean;
+interface ILabel
+ extends IFormField,
+ LabelHTMLAttributes,
+ WithStylesProps {
+ isRequired?: boolean;
}
class LabelComponent extends Component {
@@ -49,4 +50,4 @@ class LabelComponent extends Component {
}
}
-export const Label = injectSheet(styles)(LabelComponent);
+export const Label = injectSheet(styles, { injectTheme: true })(LabelComponent);
diff --git a/src/components/ui/loader/index.tsx b/src/components/ui/loader/index.tsx
index 0607bd48b..d56995ccc 100644
--- a/src/components/ui/loader/index.tsx
+++ b/src/components/ui/loader/index.tsx
@@ -1,25 +1,25 @@
import classnames from 'classnames';
import { Component } from 'react';
-import injectStyle, { withTheme } from 'react-jss';
+import injectStyle, { WithStylesProps } from 'react-jss';
import ReactLoader from 'react-loader';
-import { IWithStyle } from '../typings/generic';
-
-interface IProps extends IWithStyle {
+interface IProps extends WithStylesProps {
className?: string;
color?: string;
}
-const styles = () => ({
+const styles = theme => ({
container: {
position: 'relative',
height: 60,
},
+ loader: {},
+ color: theme.colorText,
});
class LoaderComponent extends Component {
render() {
- const { classes, className, color, theme } = this.props;
+ const { classes, className, color } = this.props;
return (
{
loaded={false}
width={4}
scale={0.75}
- color={color || theme.colorText}
+ color={color || classes.color}
parentClassName={classes.loader}
/>
@@ -41,4 +41,6 @@ class LoaderComponent extends Component {
}
}
-export const Loader = injectStyle(styles)(withTheme(LoaderComponent));
+export const Loader = injectStyle(styles, { injectTheme: true })(
+ LoaderComponent,
+);
diff --git a/src/components/ui/select/index.tsx b/src/components/ui/select/index.tsx
index 2605503a3..ac509aa7c 100644
--- a/src/components/ui/select/index.tsx
+++ b/src/components/ui/select/index.tsx
@@ -6,10 +6,10 @@ import {
import Icon from '@mdi/react';
import classnames from 'classnames';
import { ChangeEvent, Component, createRef } from 'react';
-import injectStyle from 'react-jss';
+import injectStyle, { WithStylesProps } from 'react-jss';
import { Theme } from '../../../themes';
-import { IFormField, IWithStyle } from '../typings/generic';
+import { IFormField } from '../typings/generic';
import { Error } from '../error';
import { Label } from '../label';
@@ -23,7 +23,7 @@ interface IData {
[index: string]: string;
}
-interface IProps extends IFormField, IWithStyle {
+interface IProps extends IFormField, WithStylesProps {
actionText: string;
className?: string;
inputClassName?: string;
@@ -146,6 +146,7 @@ const styles = (theme: Theme) => ({
disabled: {
opacity: theme.selectDisabledOpacity,
},
+ input: {},
});
class SelectComponent extends Component {
@@ -457,4 +458,6 @@ class SelectComponent extends Component {
}
}
-export const Select = injectStyle(styles)(SelectComponent);
+export const Select = injectStyle(styles, { injectTheme: true })(
+ SelectComponent,
+);
diff --git a/src/components/ui/textarea/index.tsx b/src/components/ui/textarea/index.tsx
index 1b16698eb..a47465806 100644
--- a/src/components/ui/textarea/index.tsx
+++ b/src/components/ui/textarea/index.tsx
@@ -1,8 +1,8 @@
import classnames from 'classnames';
import { Component, createRef, TextareaHTMLAttributes } from 'react';
-import injectSheet from 'react-jss';
+import injectSheet, { WithStylesProps } from 'react-jss';
-import { IFormField, IWithStyle } from '../typings/generic';
+import { IFormField } from '../typings/generic';
import { Error } from '../error';
import { Label } from '../label';
@@ -17,7 +17,7 @@ interface IData {
interface IProps
extends TextareaHTMLAttributes,
IFormField,
- IWithStyle {
+ WithStylesProps {
focus?: boolean;
data: IData;
textareaClassName?: string;
@@ -123,4 +123,6 @@ class TextareaComponent extends Component {
}
}
-export const Textarea = injectSheet(styles)(TextareaComponent);
+export const Textarea = injectSheet(styles, { injectTheme: true })(
+ TextareaComponent,
+);
diff --git a/src/components/ui/toggle/index.tsx b/src/components/ui/toggle/index.tsx
index 7b6ba147f..856581a21 100644
--- a/src/components/ui/toggle/index.tsx
+++ b/src/components/ui/toggle/index.tsx
@@ -1,10 +1,10 @@
import classnames from 'classnames';
import { Property } from 'csstype';
import { Component, InputHTMLAttributes } from 'react';
-import injectStyle from 'react-jss';
+import injectStyle, { WithStylesProps } from 'react-jss';
import { Theme } from '../../../themes';
-import { IFormField, IWithStyle } from '../typings/generic';
+import { IFormField } from '../typings/generic';
import { Error } from '../error';
import { Label } from '../label';
@@ -13,7 +13,7 @@ import { Wrapper } from '../wrapper';
interface IProps
extends InputHTMLAttributes,
IFormField,
- IWithStyle {
+ WithStylesProps {
className?: string;
}
@@ -122,4 +122,6 @@ class ToggleComponent extends Component {
}
}
-export const Toggle = injectStyle(styles)(ToggleComponent);
+export const Toggle = injectStyle(styles, { injectTheme: true })(
+ ToggleComponent,
+);
diff --git a/src/components/ui/typings/generic.ts b/src/components/ui/typings/generic.ts
index 65b996d59..3aec0bc40 100644
--- a/src/components/ui/typings/generic.ts
+++ b/src/components/ui/typings/generic.ts
@@ -1,7 +1,3 @@
-import { Classes } from 'jss';
-
-import { Theme } from '../../../themes';
-
export interface IFormField {
showLabel?: boolean;
label?: string;
@@ -10,10 +6,5 @@ export interface IFormField {
noMargin?: boolean;
}
-export interface IWithStyle {
- classes: Classes;
- theme: Theme;
-}
-
export type Merge = Omit> & N;
export type Omit = Pick>;
diff --git a/src/components/ui/wrapper/index.tsx b/src/components/ui/wrapper/index.tsx
index ffcd6fe0b..bc385d319 100644
--- a/src/components/ui/wrapper/index.tsx
+++ b/src/components/ui/wrapper/index.tsx
@@ -1,9 +1,8 @@
import classnames from 'classnames';
import { Component, ReactNode } from 'react';
-import injectStyle from 'react-jss';
-import { IWithStyle } from '../typings/generic';
+import injectStyle, { WithStylesProps } from 'react-jss';
-interface IProps extends IWithStyle {
+interface IProps extends WithStylesProps {
children: ReactNode;
className?: string;
identifier: string;
@@ -34,4 +33,6 @@ class WrapperComponent extends Component {
}
}
-export const Wrapper = injectStyle(styles)(WrapperComponent);
+export const Wrapper = injectStyle(styles, { injectTheme: true })(
+ WrapperComponent,
+);
diff --git a/src/components/util/ErrorBoundary/index.js b/src/components/util/ErrorBoundary/index.js
index cddcd91c2..6a8b126f1 100644
--- a/src/components/util/ErrorBoundary/index.js
+++ b/src/components/util/ErrorBoundary/index.js
@@ -18,7 +18,6 @@ const messages = defineMessages({
},
});
-@injectSheet(styles)
class ErrorBoundary extends Component {
state = {
hasError: false,
@@ -56,4 +55,6 @@ class ErrorBoundary extends Component {
}
}
-export default injectIntl(ErrorBoundary);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(ErrorBoundary),
+);
diff --git a/src/containers/auth/AuthLayoutContainer.js b/src/containers/auth/AuthLayoutContainer.js
index aa36e3969..e6d6dcf8a 100644
--- a/src/containers/auth/AuthLayoutContainer.js
+++ b/src/containers/auth/AuthLayoutContainer.js
@@ -14,8 +14,6 @@ import AppLoader from '../../components/ui/AppLoader';
import { oneOrManyChildElements } from '../../prop-types';
import FeaturesStore from '../../stores/FeaturesStore';
-@inject('stores', 'actions')
-@observer
class AuthLayoutContainer extends Component {
static propTypes = {
children: oneOrManyChildElements.isRequired,
@@ -71,7 +69,7 @@ class AuthLayoutContainer extends Component {
}
}
-AuthLayoutContainer.wrappedComponent.propTypes = {
+AuthLayoutContainer.propTypes = {
stores: PropTypes.shape({
app: PropTypes.instanceOf(AppStore).isRequired,
features: PropTypes.instanceOf(FeaturesStore).isRequired,
@@ -85,4 +83,4 @@ AuthLayoutContainer.wrappedComponent.propTypes = {
}).isRequired,
};
-export default AuthLayoutContainer;
+export default inject('stores', 'actions')(observer(AuthLayoutContainer));
diff --git a/src/containers/auth/ChangeServerScreen.js b/src/containers/auth/ChangeServerScreen.js
index dcc913c39..60bfde088 100644
--- a/src/containers/auth/ChangeServerScreen.js
+++ b/src/containers/auth/ChangeServerScreen.js
@@ -5,8 +5,6 @@ import { RouterStore } from 'mobx-react-router';
import ChangeServer from '../../components/auth/ChangeServer';
import SettingsStore from '../../stores/SettingsStore';
-@inject('stores', 'actions')
-@observer
class ChangeServerScreen extends Component {
constructor(props) {
super(props);
@@ -34,7 +32,7 @@ class ChangeServerScreen extends Component {
}
}
-ChangeServerScreen.wrappedComponent.propTypes = {
+ChangeServerScreen.propTypes = {
actions: PropTypes.shape({
settings: PropTypes.instanceOf(SettingsStore).isRequired,
}).isRequired,
@@ -44,4 +42,4 @@ ChangeServerScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default ChangeServerScreen;
+export default inject('stores', 'actions')(observer(ChangeServerScreen));
diff --git a/src/containers/auth/ImportScreen.js b/src/containers/auth/ImportScreen.js
index 46e2d41f0..c01c3d355 100644
--- a/src/containers/auth/ImportScreen.js
+++ b/src/containers/auth/ImportScreen.js
@@ -5,8 +5,6 @@ import { RouterStore } from 'mobx-react-router';
import Import from '../../components/auth/Import';
import UserStore from '../../stores/UserStore';
-@inject('stores', 'actions')
-@observer
class ImportScreen extends Component {
render() {
const { actions, stores } = this.props;
@@ -26,7 +24,7 @@ class ImportScreen extends Component {
}
}
-ImportScreen.wrappedComponent.propTypes = {
+ImportScreen.propTypes = {
actions: PropTypes.shape({
user: PropTypes.instanceOf(UserStore).isRequired,
}).isRequired,
@@ -36,4 +34,4 @@ ImportScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default ImportScreen;
+export default inject('stores', 'actions')(observer(ImportScreen));
diff --git a/src/containers/auth/InviteScreen.js b/src/containers/auth/InviteScreen.js
index e252242ae..fc66227cc 100644
--- a/src/containers/auth/InviteScreen.js
+++ b/src/containers/auth/InviteScreen.js
@@ -3,8 +3,6 @@ import PropTypes from 'prop-types';
import { inject, observer } from 'mobx-react';
import Invite from '../../components/auth/Invite';
-@inject('stores', 'actions')
-@observer
class InviteScreen extends Component {
render() {
const { actions } = this.props;
@@ -13,7 +11,7 @@ class InviteScreen extends Component {
}
}
-InviteScreen.wrappedComponent.propTypes = {
+InviteScreen.propTypes = {
actions: PropTypes.shape({
user: PropTypes.shape({
invite: PropTypes.func.isRequired,
@@ -21,4 +19,4 @@ InviteScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default InviteScreen;
+export default inject('stores', 'actions')(observer(InviteScreen));
diff --git a/src/containers/auth/LockedScreen.js b/src/containers/auth/LockedScreen.js
index 945e41284..87a00800f 100644
--- a/src/containers/auth/LockedScreen.js
+++ b/src/containers/auth/LockedScreen.js
@@ -7,8 +7,6 @@ import SettingsStore from '../../stores/SettingsStore';
import { hash } from '../../helpers/password-helpers';
import UserStore from '../../stores/UserStore';
-@inject('stores', 'actions')
-@observer
class LockedScreen extends Component {
state = {
error: false,
@@ -76,7 +74,7 @@ class LockedScreen extends Component {
}
}
-LockedScreen.wrappedComponent.propTypes = {
+LockedScreen.propTypes = {
actions: PropTypes.shape({
settings: PropTypes.instanceOf(SettingsStore).isRequired,
}).isRequired,
@@ -86,4 +84,4 @@ LockedScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default LockedScreen;
+export default inject('stores', 'actions')(observer(LockedScreen));
diff --git a/src/containers/auth/LoginScreen.js b/src/containers/auth/LoginScreen.js
index 3f8c67fa8..572a38ea1 100644
--- a/src/containers/auth/LoginScreen.js
+++ b/src/containers/auth/LoginScreen.js
@@ -6,8 +6,6 @@ import UserStore from '../../stores/UserStore';
import { globalError as globalErrorPropType } from '../../prop-types';
-@inject('stores', 'actions')
-@observer
class LoginScreen extends Component {
static propTypes = {
error: globalErrorPropType.isRequired,
@@ -32,7 +30,7 @@ class LoginScreen extends Component {
}
}
-LoginScreen.wrappedComponent.propTypes = {
+LoginScreen.propTypes = {
actions: PropTypes.shape({
user: PropTypes.instanceOf(UserStore).isRequired,
}).isRequired,
@@ -41,4 +39,4 @@ LoginScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default LoginScreen;
+export default inject('stores', 'actions')(observer(LoginScreen));
diff --git a/src/containers/auth/PasswordScreen.js b/src/containers/auth/PasswordScreen.js
index 836d4cc88..4b2c1b4a2 100644
--- a/src/containers/auth/PasswordScreen.js
+++ b/src/containers/auth/PasswordScreen.js
@@ -4,8 +4,6 @@ import { inject, observer } from 'mobx-react';
import Password from '../../components/auth/Password';
import UserStore from '../../stores/UserStore';
-@inject('stores', 'actions')
-@observer
class PasswordScreen extends Component {
render() {
const { actions, stores } = this.props;
@@ -22,7 +20,7 @@ class PasswordScreen extends Component {
}
}
-PasswordScreen.wrappedComponent.propTypes = {
+PasswordScreen.propTypes = {
actions: PropTypes.shape({
user: PropTypes.instanceOf(UserStore).isRequired,
}).isRequired,
@@ -31,4 +29,4 @@ PasswordScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default PasswordScreen;
+export default inject('stores', 'actions')(observer(PasswordScreen));
diff --git a/src/containers/auth/SetupAssistantScreen.js b/src/containers/auth/SetupAssistantScreen.js
index 8cdd95a88..f6392712d 100644
--- a/src/containers/auth/SetupAssistantScreen.js
+++ b/src/containers/auth/SetupAssistantScreen.js
@@ -14,8 +14,6 @@ import ServicesStore from '../../stores/ServicesStore';
import RecipesStore from '../../stores/RecipesStore';
import UserStore from '../../stores/UserStore';
-@inject('stores', 'actions')
-@observer
class SetupAssistantScreen extends Component {
constructor(props) {
super(props);
@@ -120,7 +118,7 @@ class SetupAssistantScreen extends Component {
}
}
-SetupAssistantScreen.wrappedComponent.propTypes = {
+SetupAssistantScreen.propTypes = {
stores: PropTypes.shape({
services: PropTypes.instanceOf(ServicesStore),
router: PropTypes.instanceOf(RouterStore).isRequired,
@@ -134,4 +132,4 @@ SetupAssistantScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default SetupAssistantScreen;
+export default inject('stores', 'actions')(observer(SetupAssistantScreen));
diff --git a/src/containers/auth/SignupScreen.js b/src/containers/auth/SignupScreen.js
index 3b19f3c50..1dd8d0772 100644
--- a/src/containers/auth/SignupScreen.js
+++ b/src/containers/auth/SignupScreen.js
@@ -8,8 +8,6 @@ import FeaturesStore from '../../stores/FeaturesStore';
import { globalError as globalErrorPropType } from '../../prop-types';
-@inject('stores', 'actions')
-@observer
class SignupScreen extends Component {
static propTypes = {
error: globalErrorPropType.isRequired,
@@ -36,7 +34,7 @@ class SignupScreen extends Component {
}
}
-SignupScreen.wrappedComponent.propTypes = {
+SignupScreen.propTypes = {
actions: PropTypes.shape({
user: PropTypes.instanceOf(UserStore).isRequired,
}).isRequired,
@@ -46,4 +44,4 @@ SignupScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default SignupScreen;
+export default inject('stores', 'actions')(observer(SignupScreen));
diff --git a/src/containers/auth/WelcomeScreen.js b/src/containers/auth/WelcomeScreen.js
index 7a23d9ba9..18b6b2eda 100644
--- a/src/containers/auth/WelcomeScreen.js
+++ b/src/containers/auth/WelcomeScreen.js
@@ -6,8 +6,6 @@ import Welcome from '../../components/auth/Welcome';
import UserStore from '../../stores/UserStore';
import RecipePreviewsStore from '../../stores/RecipePreviewsStore';
-@inject('stores', 'actions')
-@observer
class LoginScreen extends Component {
render() {
const { user, recipePreviews } = this.props.stores;
@@ -23,11 +21,11 @@ class LoginScreen extends Component {
}
}
-LoginScreen.wrappedComponent.propTypes = {
+LoginScreen.propTypes = {
stores: PropTypes.shape({
user: PropTypes.instanceOf(UserStore).isRequired,
recipePreviews: PropTypes.instanceOf(RecipePreviewsStore).isRequired,
}).isRequired,
};
-export default LoginScreen;
+export default inject('stores', 'actions')(observer(LoginScreen));
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js
index 50a28803f..9b0edc85e 100644
--- a/src/containers/layout/AppLayoutContainer.js
+++ b/src/containers/layout/AppLayoutContainer.js
@@ -24,8 +24,6 @@ import WorkspaceDrawer from '../../features/workspaces/components/WorkspaceDrawe
import { workspaceStore } from '../../features/workspaces';
import WorkspacesStore from '../../features/workspaces/store';
-@inject('stores', 'actions')
-@observer
class AppLayoutContainer extends Component {
static defaultProps = {
children: null,
@@ -171,7 +169,7 @@ class AppLayoutContainer extends Component {
}
}
-AppLayoutContainer.wrappedComponent.propTypes = {
+AppLayoutContainer.propTypes = {
stores: PropTypes.shape({
services: PropTypes.instanceOf(ServicesStore).isRequired,
features: PropTypes.instanceOf(FeaturesStore).isRequired,
@@ -194,4 +192,4 @@ AppLayoutContainer.wrappedComponent.propTypes = {
children: oneOrManyChildElements,
};
-export default AppLayoutContainer;
+export default inject('stores', 'actions')(observer(AppLayoutContainer));
diff --git a/src/containers/settings/AccountScreen.js b/src/containers/settings/AccountScreen.js
index f7c9b8164..aae230577 100644
--- a/src/containers/settings/AccountScreen.js
+++ b/src/containers/settings/AccountScreen.js
@@ -12,8 +12,6 @@ import ErrorBoundary from '../../components/util/ErrorBoundary';
import { LIVE_FRANZ_API } from '../../config';
import { WEBSITE } from '../../environment-remote';
-@inject('stores', 'actions')
-@observer
class AccountScreen extends Component {
onCloseWindow() {
const { user, features } = this.props.stores;
@@ -74,7 +72,7 @@ class AccountScreen extends Component {
}
}
-AccountScreen.wrappedComponent.propTypes = {
+AccountScreen.propTypes = {
stores: PropTypes.shape({
user: PropTypes.instanceOf(UserStore).isRequired,
features: PropTypes.instanceOf(FeaturesStore).isRequired,
@@ -87,4 +85,4 @@ AccountScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default AccountScreen;
+export default inject('stores', 'actions')(observer(AccountScreen));
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js
index ddf7fab36..24b827993 100644
--- a/src/containers/settings/EditServiceScreen.js
+++ b/src/containers/settings/EditServiceScreen.js
@@ -111,8 +111,6 @@ const messages = defineMessages({
},
});
-@inject('stores', 'actions')
-@observer
class EditServiceScreen extends Component {
onSubmit(data) {
const { action } = this.props.router.params;
@@ -438,7 +436,7 @@ class EditServiceScreen extends Component {
}
}
-EditServiceScreen.wrappedComponent.propTypes = {
+EditServiceScreen.propTypes = {
stores: PropTypes.shape({
user: PropTypes.instanceOf(UserStore).isRequired,
recipes: PropTypes.instanceOf(RecipesStore).isRequired,
@@ -451,4 +449,6 @@ EditServiceScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default injectIntl(EditServiceScreen);
+export default injectIntl(
+ inject('stores', 'actions')(observer(EditServiceScreen)),
+);
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js
index 720f2c8a1..ddf6876b9 100644
--- a/src/containers/settings/EditSettingsScreen.js
+++ b/src/containers/settings/EditSettingsScreen.js
@@ -245,8 +245,6 @@ const messages = defineMessages({
},
});
-@inject('stores', 'actions')
-@observer
class EditSettingsScreen extends Component {
constructor(props) {
super(props);
@@ -753,7 +751,7 @@ class EditSettingsScreen extends Component {
}
}
-EditSettingsScreen.wrappedComponent.propTypes = {
+EditSettingsScreen.propTypes = {
stores: PropTypes.shape({
app: PropTypes.instanceOf(AppStore).isRequired,
user: PropTypes.instanceOf(UserStore).isRequired,
@@ -771,4 +769,6 @@ EditSettingsScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default injectIntl(EditSettingsScreen);
+export default injectIntl(
+ inject('stores', 'actions')(observer(EditSettingsScreen)),
+);
diff --git a/src/containers/settings/EditUserScreen.js b/src/containers/settings/EditUserScreen.js
index 1dc0aa8e6..baa2d7b71 100644
--- a/src/containers/settings/EditUserScreen.js
+++ b/src/containers/settings/EditUserScreen.js
@@ -49,8 +49,6 @@ const messages = defineMessages({
},
});
-@inject('stores', 'actions')
-@observer
class EditUserScreen extends Component {
componentWillUnmount() {
this.props.actions.user.resetStatus();
@@ -150,7 +148,7 @@ class EditUserScreen extends Component {
}
}
-EditUserScreen.wrappedComponent.propTypes = {
+EditUserScreen.propTypes = {
stores: PropTypes.shape({
user: PropTypes.instanceOf(UserStore).isRequired,
}).isRequired,
@@ -159,4 +157,6 @@ EditUserScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default injectIntl(EditUserScreen);
+export default injectIntl(
+ inject('stores', 'actions')(observer(EditUserScreen)),
+);
diff --git a/src/containers/settings/InviteScreen.js b/src/containers/settings/InviteScreen.js
index 592b4b11c..86723554c 100644
--- a/src/containers/settings/InviteScreen.js
+++ b/src/containers/settings/InviteScreen.js
@@ -6,8 +6,6 @@ import Invite from '../../components/auth/Invite';
import ErrorBoundary from '../../components/util/ErrorBoundary';
import UserStore from '../../stores/UserStore';
-@inject('stores', 'actions')
-@observer
class InviteScreen extends Component {
componentWillUnmount() {
this.props.stores.user.inviteRequest.reset();
@@ -32,7 +30,7 @@ class InviteScreen extends Component {
}
}
-InviteScreen.wrappedComponent.propTypes = {
+InviteScreen.propTypes = {
actions: PropTypes.shape({
user: PropTypes.instanceOf(UserStore).isRequired,
}).isRequired,
@@ -41,4 +39,4 @@ InviteScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default InviteScreen;
+export default inject('stores', 'actions')(observer(InviteScreen));
diff --git a/src/containers/settings/RecipesScreen.js b/src/containers/settings/RecipesScreen.js
index 7f55e54c5..6b629d3d8 100644
--- a/src/containers/settings/RecipesScreen.js
+++ b/src/containers/settings/RecipesScreen.js
@@ -19,8 +19,6 @@ import RecipePreview from '../../models/RecipePreview';
import AppStore from '../../stores/AppStore';
import { openPath } from '../../helpers/url-helpers';
-@inject('stores', 'actions')
-@observer
class RecipesScreen extends Component {
static propTypes = {
params: PropTypes.shape({
@@ -182,7 +180,7 @@ class RecipesScreen extends Component {
}
}
-RecipesScreen.wrappedComponent.propTypes = {
+RecipesScreen.propTypes = {
stores: PropTypes.shape({
recipePreviews: PropTypes.instanceOf(RecipePreviewsStore).isRequired,
recipes: PropTypes.instanceOf(RecipeStore).isRequired,
@@ -198,4 +196,4 @@ RecipesScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default RecipesScreen;
+export default inject('stores', 'actions')(observer(RecipesScreen));
diff --git a/src/containers/settings/ServicesScreen.js b/src/containers/settings/ServicesScreen.js
index a657b6e6c..2970b2a54 100644
--- a/src/containers/settings/ServicesScreen.js
+++ b/src/containers/settings/ServicesScreen.js
@@ -10,8 +10,6 @@ import ServiceStore from '../../stores/ServicesStore';
import ServicesDashboard from '../../components/settings/services/ServicesDashboard';
import ErrorBoundary from '../../components/util/ErrorBoundary';
-@inject('stores', 'actions')
-@observer
class ServicesScreen extends Component {
componentWillUnmount() {
this.props.actions.service.resetFilter();
@@ -57,7 +55,7 @@ class ServicesScreen extends Component {
}
}
-ServicesScreen.wrappedComponent.propTypes = {
+ServicesScreen.propTypes = {
stores: PropTypes.shape({
user: PropTypes.instanceOf(UserStore).isRequired,
services: PropTypes.instanceOf(ServiceStore).isRequired,
@@ -68,4 +66,4 @@ ServicesScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default ServicesScreen;
+export default inject('stores', 'actions')(observer(ServicesScreen));
diff --git a/src/containers/settings/SettingsWindow.js b/src/containers/settings/SettingsWindow.js
index 35db3a434..0e6ce4df3 100644
--- a/src/containers/settings/SettingsWindow.js
+++ b/src/containers/settings/SettingsWindow.js
@@ -11,8 +11,6 @@ import ErrorBoundary from '../../components/util/ErrorBoundary';
import { workspaceStore } from '../../features/workspaces';
import UIStore from '../../stores/UIStore';
-@inject('stores', 'actions')
-@observer
class SettingsContainer extends Component {
portalRoot = document.querySelector('#portalContainer');
@@ -48,7 +46,7 @@ class SettingsContainer extends Component {
}
}
-SettingsContainer.wrappedComponent.propTypes = {
+SettingsContainer.propTypes = {
children: PropTypes.element.isRequired,
stores: PropTypes.shape({
services: PropTypes.instanceOf(ServicesStore).isRequired,
@@ -58,4 +56,4 @@ SettingsContainer.wrappedComponent.propTypes = {
}).isRequired,
};
-export default SettingsContainer;
+export default inject('stores', 'actions')(observer(SettingsContainer));
diff --git a/src/containers/settings/SupportScreen.js b/src/containers/settings/SupportScreen.js
index d3600f8ea..b4ad952b2 100644
--- a/src/containers/settings/SupportScreen.js
+++ b/src/containers/settings/SupportScreen.js
@@ -6,7 +6,6 @@ import SupportFerdi from '../../components/settings/supportFerdi/SupportFerdiDas
import ErrorBoundary from '../../components/util/ErrorBoundary';
import AppStore from '../../stores/AppStore';
-@inject('actions')
class SupportScreen extends Component {
constructor(props) {
super(props);
@@ -27,10 +26,10 @@ class SupportScreen extends Component {
}
}
-SupportScreen.wrappedComponent.propTypes = {
+SupportScreen.propTypes = {
actions: PropTypes.shape({
app: PropTypes.instanceOf(AppStore).isRequired,
}).isRequired,
};
-export default SupportScreen;
+export default inject('actions')(SupportScreen);
diff --git a/src/containers/settings/TeamScreen.js b/src/containers/settings/TeamScreen.js
index 928262a59..0a8b92b47 100644
--- a/src/containers/settings/TeamScreen.js
+++ b/src/containers/settings/TeamScreen.js
@@ -10,8 +10,6 @@ import TeamDashboard from '../../components/settings/team/TeamDashboard';
import ErrorBoundary from '../../components/util/ErrorBoundary';
import { DEV_API_FRANZ_WEBSITE } from '../../config';
-@inject('stores', 'actions')
-@observer
class TeamScreen extends Component {
handleWebsiteLink(route) {
const { actions, stores } = this.props;
@@ -44,7 +42,7 @@ class TeamScreen extends Component {
}
}
-TeamScreen.wrappedComponent.propTypes = {
+TeamScreen.propTypes = {
stores: PropTypes.shape({
user: PropTypes.instanceOf(UserStore).isRequired,
app: PropTypes.instanceOf(AppStore).isRequired,
@@ -56,4 +54,4 @@ TeamScreen.wrappedComponent.propTypes = {
}).isRequired,
};
-export default TeamScreen;
+export default inject('stores', 'actions')(observer(TeamScreen));
diff --git a/src/electron/ipc-api/download.ts b/src/electron/ipc-api/download.ts
index af15b157e..95f211e52 100644
--- a/src/electron/ipc-api/download.ts
+++ b/src/electron/ipc-api/download.ts
@@ -48,7 +48,7 @@ export default (params: { mainWindow: BrowserWindow }) => {
debug('File blob saved to', saveDialog.filePath);
} catch (error) {
- console.log(error);
+ console.error(error);
}
}
} catch (error) {
diff --git a/src/features/basicAuth/Component.js b/src/features/basicAuth/Component.js
index 652233e55..89b0a4e72 100644
--- a/src/features/basicAuth/Component.js
+++ b/src/features/basicAuth/Component.js
@@ -22,8 +22,6 @@ const messages = defineMessages({
},
});
-@injectSheet(styles)
-@observer
class BasicAuthModal extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -97,4 +95,6 @@ class BasicAuthModal extends Component {
);
}
}
-export default injectIntl(BasicAuthModal);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(BasicAuthModal)),
+);
diff --git a/src/features/nightlyBuilds/Component.js b/src/features/nightlyBuilds/Component.js
index 64f782c8f..0966480d0 100644
--- a/src/features/nightlyBuilds/Component.js
+++ b/src/features/nightlyBuilds/Component.js
@@ -29,7 +29,7 @@ const messages = defineMessages({
},
});
-const styles = () => ({
+const styles = {
info: {
paddingTop: 20,
paddingBottom: 20,
@@ -51,11 +51,8 @@ const styles = () => ({
background: '#c45a5a !important',
color: '#ffffff !important',
},
-});
+};
-@injectSheet(styles)
-@inject('stores', 'actions')
-@observer
class NightlyBuildsModal extends Component {
close() {
ModalState.isModalVisible = false;
@@ -119,7 +116,7 @@ class NightlyBuildsModal extends Component {
}
}
-NightlyBuildsModal.wrappedComponent.propTypes = {
+NightlyBuildsModal.propTypes = {
stores: PropTypes.shape({
settings: PropTypes.instanceOf(SettingsStore).isRequired,
}).isRequired,
@@ -131,4 +128,8 @@ NightlyBuildsModal.wrappedComponent.propTypes = {
classes: PropTypes.object.isRequired,
};
-export default injectIntl(NightlyBuildsModal);
+export default injectIntl(
+ injectSheet(styles)(
+ inject('stores', 'actions')(observer(NightlyBuildsModal)),
+ ),
+);
diff --git a/src/features/publishDebugInfo/Component.js b/src/features/publishDebugInfo/Component.js
index 30bdc13b6..953fc7c21 100644
--- a/src/features/publishDebugInfo/Component.js
+++ b/src/features/publishDebugInfo/Component.js
@@ -85,14 +85,7 @@ const styles = theme => ({
},
});
-@injectSheet(styles)
-@inject('stores', 'actions')
-@observer
class PublishDebugLogModal extends Component {
- static propTypes = {
- classes: PropTypes.object.isRequired,
- };
-
state = {
log: null,
error: false,
@@ -221,13 +214,18 @@ class PublishDebugLogModal extends Component {
}
}
-PublishDebugLogModal.wrappedComponent.propTypes = {
+PublishDebugLogModal.propTypes = {
stores: PropTypes.shape({
app: PropTypes.instanceOf(AppStore).isRequired,
}).isRequired,
actions: PropTypes.shape({
service: PropTypes.instanceOf(ServicesStore).isRequired,
}).isRequired,
+ classes: PropTypes.object.isRequired,
};
-export default injectIntl(PublishDebugLogModal);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(
+ inject('stores', 'actions')(observer(PublishDebugLogModal)),
+ ),
+);
diff --git a/src/features/quickSwitch/Component.js b/src/features/quickSwitch/Component.js
index 75587cc1d..7f9424b6d 100644
--- a/src/features/quickSwitch/Component.js
+++ b/src/features/quickSwitch/Component.js
@@ -81,9 +81,6 @@ const styles = theme => ({
},
});
-@injectSheet(styles)
-@inject('stores', 'actions')
-@observer
class QuickSwitchModal extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -349,13 +346,18 @@ class QuickSwitchModal extends Component {
}
}
-QuickSwitchModal.wrappedComponent.propTypes = {
+QuickSwitchModal.propTypes = {
stores: PropTypes.shape({
services: PropTypes.instanceOf(ServicesStore).isRequired,
}).isRequired,
actions: PropTypes.shape({
service: PropTypes.instanceOf(ServicesStore).isRequired,
}).isRequired,
+ classes: PropTypes.object.isRequired,
};
-export default injectIntl(QuickSwitchModal);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(
+ inject('stores', 'actions')(observer(QuickSwitchModal)),
+ ),
+);
diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js
index 1d423544b..780864b91 100644
--- a/src/features/todos/components/TodosWebview.js
+++ b/src/features/todos/components/TodosWebview.js
@@ -48,8 +48,6 @@ const styles = theme => ({
},
});
-@injectSheet(styles)
-@observer
class TodosWebview extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -128,7 +126,6 @@ class TodosWebview extends Component {
const { handleClientMessage } = this.props;
if (!this.webview) return;
this.webview.addEventListener('ipc-message', e => {
- // console.log(e);
handleClientMessage({ channel: e.channel, message: e.args[0] });
});
}
@@ -201,4 +198,6 @@ class TodosWebview extends Component {
}
}
-export default TodosWebview;
+export default injectSheet(styles, { injectTheme: true })(
+ observer(TodosWebview),
+);
diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js
index 536810d2d..b97506767 100644
--- a/src/features/todos/containers/TodosScreen.js
+++ b/src/features/todos/containers/TodosScreen.js
@@ -10,8 +10,6 @@ import { TODOS_MIN_WIDTH } from '../../../config';
import { todoActions } from '../actions';
import ServicesStore from '../../../stores/ServicesStore';
-@inject('stores', 'actions')
-@observer
class TodosScreen extends Component {
render() {
if (
@@ -44,9 +42,9 @@ class TodosScreen extends Component {
}
}
-export default TodosScreen;
+export default inject('stores', 'actions')(observer(TodosScreen));
-TodosScreen.wrappedComponent.propTypes = {
+TodosScreen.propTypes = {
stores: PropTypes.shape({
features: PropTypes.instanceOf(FeaturesStore).isRequired,
services: PropTypes.instanceOf(ServicesStore).isRequired,
diff --git a/src/features/todos/store.js b/src/features/todos/store.js
index d158ed480..2bf4e8fab 100644
--- a/src/features/todos/store.js
+++ b/src/features/todos/store.js
@@ -187,10 +187,6 @@ export default class TodoStore extends FeatureStore {
break;
default:
debug('Other message received', channel, message);
- console.log(
- 'this.stores.services.isTodosServiceAdded',
- this.stores.services.isTodosServiceAdded,
- );
if (this.stores.services.isTodosServiceAdded) {
this.actions.service.handleIPCMessage({
serviceId: this.stores.services.isTodosServiceAdded.id,
diff --git a/src/features/webControls/components/WebControls.js b/src/features/webControls/components/WebControls.js
index 5650d4cd1..99d78eda0 100644
--- a/src/features/webControls/components/WebControls.js
+++ b/src/features/webControls/components/WebControls.js
@@ -94,8 +94,6 @@ const styles = theme => ({
},
});
-@injectSheet(styles)
-@observer
class WebControls extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -238,4 +236,6 @@ class WebControls extends Component {
}
}
-export default injectIntl(WebControls);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(WebControls)),
+);
diff --git a/src/features/webControls/containers/WebControlsScreen.js b/src/features/webControls/containers/WebControlsScreen.js
index 6fba5db86..3dac6997c 100644
--- a/src/features/webControls/containers/WebControlsScreen.js
+++ b/src/features/webControls/containers/WebControlsScreen.js
@@ -16,8 +16,6 @@ const URL_EVENTS = [
'did-navigate-in-page',
];
-@inject('stores', 'actions')
-@observer
class WebControlsScreen extends Component {
@observable url = '';
@@ -125,9 +123,9 @@ class WebControlsScreen extends Component {
}
}
-export default WebControlsScreen;
+export default inject('stores', 'actions')(observer(WebControlsScreen));
-WebControlsScreen.wrappedComponent.propTypes = {
+WebControlsScreen.propTypes = {
service: PropTypes.instanceOf(Service).isRequired,
stores: PropTypes.shape({
services: PropTypes.instanceOf(ServicesStore).isRequired,
diff --git a/src/features/workspaces/components/CreateWorkspaceForm.js b/src/features/workspaces/components/CreateWorkspaceForm.js
index 75f6d9f4a..54475eccb 100644
--- a/src/features/workspaces/components/CreateWorkspaceForm.js
+++ b/src/features/workspaces/components/CreateWorkspaceForm.js
@@ -21,7 +21,7 @@ const messages = defineMessages({
},
});
-const styles = () => ({
+const styles = {
form: {
display: 'flex',
},
@@ -32,10 +32,8 @@ const styles = () => ({
submitButton: {
height: 'inherit',
},
-});
+};
-@injectSheet(styles)
-@observer
class CreateWorkspaceForm extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -94,4 +92,6 @@ class CreateWorkspaceForm extends Component {
}
}
-export default injectIntl(CreateWorkspaceForm);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(CreateWorkspaceForm)),
+);
diff --git a/src/features/workspaces/components/EditWorkspaceForm.js b/src/features/workspaces/components/EditWorkspaceForm.js
index fa3ea4289..e8bd9d60c 100644
--- a/src/features/workspaces/components/EditWorkspaceForm.js
+++ b/src/features/workspaces/components/EditWorkspaceForm.js
@@ -58,7 +58,7 @@ const messages = defineMessages({
},
});
-const styles = () => ({
+const styles = {
nameInput: {
height: 'auto',
},
@@ -68,10 +68,8 @@ const styles = () => ({
keepLoadedInfo: {
marginBottom: '2rem !important',
},
-});
+};
-@injectSheet(styles)
-@observer
class EditWorkspaceForm extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -230,4 +228,6 @@ class EditWorkspaceForm extends Component {
}
}
-export default injectIntl(EditWorkspaceForm);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(EditWorkspaceForm)),
+);
diff --git a/src/features/workspaces/components/WorkspaceDrawer.js b/src/features/workspaces/components/WorkspaceDrawer.js
index d66e0f10d..4fd2b1153 100644
--- a/src/features/workspaces/components/WorkspaceDrawer.js
+++ b/src/features/workspaces/components/WorkspaceDrawer.js
@@ -88,8 +88,6 @@ const styles = theme => ({
},
});
-@injectSheet(styles)
-@observer
class WorkspaceDrawer extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -175,4 +173,6 @@ class WorkspaceDrawer extends Component {
}
}
-export default injectIntl(WorkspaceDrawer);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(WorkspaceDrawer)),
+);
diff --git a/src/features/workspaces/components/WorkspaceDrawerItem.js b/src/features/workspaces/components/WorkspaceDrawerItem.js
index d3c9fa767..22c0a39d9 100644
--- a/src/features/workspaces/components/WorkspaceDrawerItem.js
+++ b/src/features/workspaces/components/WorkspaceDrawerItem.js
@@ -65,8 +65,6 @@ const styles = theme => ({
},
});
-@injectSheet(styles)
-@observer
class WorkspaceDrawerItem extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -150,4 +148,6 @@ class WorkspaceDrawerItem extends Component {
}
}
-export default injectIntl(WorkspaceDrawerItem);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(observer(WorkspaceDrawerItem)),
+);
diff --git a/src/features/workspaces/components/WorkspaceItem.tsx b/src/features/workspaces/components/WorkspaceItem.tsx
index 6fb02d2f5..f46375c7a 100644
--- a/src/features/workspaces/components/WorkspaceItem.tsx
+++ b/src/features/workspaces/components/WorkspaceItem.tsx
@@ -22,8 +22,6 @@ type Props = {
onItemClick: (workspace) => void;
};
-@injectSheet(styles)
-@observer
class WorkspaceItem extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -42,4 +40,6 @@ class WorkspaceItem extends Component {
}
}
-export default WorkspaceItem;
+export default injectSheet(styles, { injectTheme: true })(
+ observer(WorkspaceItem),
+);
diff --git a/src/features/workspaces/components/WorkspaceServiceListItem.tsx b/src/features/workspaces/components/WorkspaceServiceListItem.tsx
index 6e012eb1e..46fda0103 100644
--- a/src/features/workspaces/components/WorkspaceServiceListItem.tsx
+++ b/src/features/workspaces/components/WorkspaceServiceListItem.tsx
@@ -36,8 +36,6 @@ type Props = {
service: any;
};
-@injectSheet(styles)
-@observer
class WorkspaceServiceListItem extends Component {
render() {
const { classes, isInWorkspace, onToggle, service } = this.props;
@@ -63,4 +61,6 @@ class WorkspaceServiceListItem extends Component {
}
}
-export default WorkspaceServiceListItem;
+export default injectSheet(styles, { injectTheme: true })(
+ observer(WorkspaceServiceListItem),
+);
diff --git a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js
index ff4e9475a..b2e0adfe7 100644
--- a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js
+++ b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js
@@ -53,8 +53,6 @@ const styles = theme => ({
},
});
-@injectSheet(styles)
-@observer
class WorkspaceSwitchingIndicator extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -85,4 +83,8 @@ class WorkspaceSwitchingIndicator extends Component {
}
}
-export default injectIntl(WorkspaceSwitchingIndicator);
+export default injectIntl(
+ injectSheet(styles, { injectTheme: true })(
+ observer(WorkspaceSwitchingIndicator),
+ ),
+);
diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js
index 1087580b1..9c2f65731 100644
--- a/src/features/workspaces/components/WorkspacesDashboard.js
+++ b/src/features/workspaces/components/WorkspacesDashboard.js
@@ -49,7 +49,7 @@ const messages = defineMessages({
},
});
-const styles = () => ({
+const styles = {
table: {
width: '100%',
'& td': {
@@ -67,11 +67,8 @@ const styles = () => ({
margin: [-8, 0, 0, 20],
alignSelf: 'center',
},
-});
+};
-@inject('stores')
-@injectSheet(styles)
-@observer
class WorkspacesDashboard extends Component {
static propTypes = {
classes: PropTypes.object.isRequired,
@@ -190,9 +187,13 @@ class WorkspacesDashboard extends Component {
}
}
-export default injectIntl(WorkspacesDashboard);
+export default injectIntl(
+ inject('stores')(
+ injectSheet(styles, { injectTheme: true })(observer(WorkspacesDashboard)),
+ ),
+);
-WorkspacesDashboard.wrappedComponent.propTypes = {
+WorkspacesDashboard.propTypes = {
stores: PropTypes.shape({
ui: PropTypes.instanceOf(UIStore).isRequired,
}).isRequired,
diff --git a/src/features/workspaces/containers/EditWorkspaceScreen.tsx b/src/features/workspaces/containers/EditWorkspaceScreen.tsx
index 8e8f8179d..0351ddafb 100644
--- a/src/features/workspaces/containers/EditWorkspaceScreen.tsx
+++ b/src/features/workspaces/containers/EditWorkspaceScreen.tsx
@@ -17,8 +17,6 @@ type Props = {
};
};
-@inject('stores', 'actions')
-@observer
class EditWorkspaceScreen extends Component {
// @ts-expect-error Not all code paths return a value.
onDelete = () => {
@@ -58,4 +56,4 @@ class EditWorkspaceScreen extends Component {
}
}
-export default EditWorkspaceScreen;
+export default inject('stores', 'actions')(observer(EditWorkspaceScreen));
diff --git a/src/features/workspaces/containers/WorkspacesScreen.tsx b/src/features/workspaces/containers/WorkspacesScreen.tsx
index a07e92439..33808b69d 100644
--- a/src/features/workspaces/containers/WorkspacesScreen.tsx
+++ b/src/features/workspaces/containers/WorkspacesScreen.tsx
@@ -17,8 +17,6 @@ type Props = {
};
};
-@inject('stores', 'actions')
-@observer
class WorkspacesScreen extends Component {
render() {
const { actions } = this.props;
@@ -38,4 +36,4 @@ class WorkspacesScreen extends Component {
}
}
-export default WorkspacesScreen;
+export default inject('stores', 'actions')(observer(WorkspacesScreen));
diff --git a/src/lib/Form.ts b/src/lib/Form.ts
index 9b8321948..14ea82948 100644
--- a/src/lib/Form.ts
+++ b/src/lib/Form.ts
@@ -1,4 +1,5 @@
import Form from 'mobx-react-form';
+import vjf from 'mobx-react-form/lib/validators/VJF';
export default class DefaultForm extends Form {
bindings() {
@@ -29,4 +30,10 @@ export default class DefaultForm extends Form {
// // },
};
}
+
+ plugins() {
+ return {
+ vjf: vjf(),
+ };
+ }
}
diff --git a/src/routes.tsx b/src/routes.tsx
index 569da06a7..192090737 100644
--- a/src/routes.tsx
+++ b/src/routes.tsx
@@ -36,8 +36,6 @@ type Props = {
history: any;
};
-@inject('stores', 'actions')
-@observer
class Routes extends Component {
render() {
const { locked } = this.props.stores.settings.app;
@@ -94,4 +92,4 @@ class Routes extends Component {
}
}
-export default Routes;
+export default inject('stores', 'actions')(observer(Routes));
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 3d418c4c5..09ee8890a 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -799,8 +799,6 @@ export default class ServicesStore extends Store {
options.icon = '/assets/img/notification-badge.gif';
}
- console.log(title, options);
-
this.actions.app.notify({
notificationId: args[0].notificationId,
title,
--
cgit v1.2.3-70-g09d2
From f53fe4ee6cb169ab688e4d8562a94532753a5382 Mon Sep 17 00:00:00 2001
From: kytwb
Date: Wed, 15 Dec 2021 19:02:35 +0100
Subject: Enable hibernate/wake-up calls of active service via context menu
---
src/stores/ServicesStore.js | 4 ----
1 file changed, 4 deletions(-)
(limited to 'src/stores/ServicesStore.js')
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 09ee8890a..e546850f9 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -1036,10 +1036,6 @@ export default class ServicesStore extends Store {
if (!service.canHibernate) {
return;
}
- if (service.isActive) {
- debug(`Skipping service hibernation for ${service.name}`);
- return;
- }
debug(`Hibernate ${service.name}`);
--
cgit v1.2.3-70-g09d2