aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Dominik Guzei <dominik.guzei@gmail.com>2019-04-11 12:53:16 +0200
committerLibravatar Dominik Guzei <dominik.guzei@gmail.com>2019-04-11 12:53:16 +0200
commitca9d5863f9067f2a32498da763cd536e0bcc5c77 (patch)
tree30d0f41f9db7c499cc3e1f2f1e39004294be7f80 /src
parentmerge-in workspace feature (diff)
downloadferdium-app-ca9d5863f9067f2a32498da763cd536e0bcc5c77.tar.gz
ferdium-app-ca9d5863f9067f2a32498da763cd536e0bcc5c77.tar.zst
ferdium-app-ca9d5863f9067f2a32498da763cd536e0bcc5c77.zip
refactor announcements to newest feature pattern
Diffstat (limited to 'src')
-rw-r--r--src/components/layout/AppLayout.js2
-rw-r--r--src/containers/layout/AppLayoutContainer.js5
-rw-r--r--src/features/announcements/api.js6
-rw-r--r--src/features/announcements/components/AnnouncementScreen.js (renamed from src/features/announcements/Component.js)10
-rw-r--r--src/features/announcements/index.js17
-rw-r--r--src/features/announcements/state.js17
-rw-r--r--src/features/announcements/store.js49
-rw-r--r--src/i18n/locales/defaultMessages.json18
-rw-r--r--src/i18n/messages/src/features/announcements/components/AnnouncementScreen.json15
9 files changed, 83 insertions, 56 deletions
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index 985475c8d..eb3f03f12 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -14,7 +14,7 @@ import ErrorBoundary from '../util/ErrorBoundary';
14// import globalMessages from '../../i18n/globalMessages'; 14// import globalMessages from '../../i18n/globalMessages';
15 15
16import { isWindows } from '../../environment'; 16import { isWindows } from '../../environment';
17import AnnouncementScreen from '../../features/announcements/Component'; 17import AnnouncementScreen from '../../features/announcements/components/AnnouncementScreen';
18import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator'; 18import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator';
19import { workspaceStore } from '../../features/workspaces'; 19import { workspaceStore } from '../../features/workspaces';
20 20
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js
index 0357f63bd..8a0e105e7 100644
--- a/src/containers/layout/AppLayoutContainer.js
+++ b/src/containers/layout/AppLayoutContainer.js
@@ -20,10 +20,11 @@ import Services from '../../components/services/content/Services';
20import AppLoader from '../../components/ui/AppLoader'; 20import AppLoader from '../../components/ui/AppLoader';
21 21
22import { state as delayAppState } from '../../features/delayApp'; 22import { state as delayAppState } from '../../features/delayApp';
23import { announcementsState } from '../../features/announcements/state'; 23import { } from '../../features/announcements/store';
24import { workspaceActions } from '../../features/workspaces/actions'; 24import { workspaceActions } from '../../features/workspaces/actions';
25import WorkspaceDrawer from '../../features/workspaces/components/WorkspaceDrawer'; 25import WorkspaceDrawer from '../../features/workspaces/components/WorkspaceDrawer';
26import { workspaceStore } from '../../features/workspaces'; 26import { workspaceStore } from '../../features/workspaces';
27import { announcementsStore } from '../../features/announcements';
27 28
28export default @inject('stores', 'actions') @observer class AppLayoutContainer extends Component { 29export default @inject('stores', 'actions') @observer class AppLayoutContainer extends Component {
29 static defaultProps = { 30 static defaultProps = {
@@ -150,7 +151,7 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e
150 areRequiredRequestsLoading={requests.areRequiredRequestsLoading} 151 areRequiredRequestsLoading={requests.areRequiredRequestsLoading}
151 darkMode={settings.all.app.darkMode} 152 darkMode={settings.all.app.darkMode}
152 isDelayAppScreenVisible={delayAppState.isDelayAppScreenVisible} 153 isDelayAppScreenVisible={delayAppState.isDelayAppScreenVisible}
153 isAnnouncementVisible={announcementsState.isAnnouncementVisible} 154 isAnnouncementVisible={announcementsStore.isAnnouncementVisible}
154 > 155 >
155 {React.Children.count(children) > 0 ? children : null} 156 {React.Children.count(children) > 0 ? children : null}
156 </AppLayout> 157 </AppLayout>
diff --git a/src/features/announcements/api.js b/src/features/announcements/api.js
index ec16066a6..09fcb8235 100644
--- a/src/features/announcements/api.js
+++ b/src/features/announcements/api.js
@@ -1,8 +1,9 @@
1import { remote } from 'electron'; 1import { remote } from 'electron';
2import Request from '../../stores/lib/Request';
2 3
3const debug = require('debug')('Franz:feature:announcements:api'); 4const debug = require('debug')('Franz:feature:announcements:api');
4 5
5export default { 6export const announcementsApi = {
6 async getCurrentVersion() { 7 async getCurrentVersion() {
7 debug('getting current version of electron app'); 8 debug('getting current version of electron app');
8 return Promise.resolve(remote.app.getVersion()); 9 return Promise.resolve(remote.app.getVersion());
@@ -17,3 +18,6 @@ export default {
17 return data.body; 18 return data.body;
18 }, 19 },
19}; 20};
21
22export const getCurrentVersionRequest = new Request(announcementsApi, 'getCurrentVersion');
23export const getAnnouncementRequest = new Request(announcementsApi, 'getAnnouncementForVersion');
diff --git a/src/features/announcements/Component.js b/src/features/announcements/components/AnnouncementScreen.js
index 5d95f5d84..5b3e7aeaa 100644
--- a/src/features/announcements/Component.js
+++ b/src/features/announcements/components/AnnouncementScreen.js
@@ -4,8 +4,8 @@ import PropTypes from 'prop-types';
4import { inject, observer } from 'mobx-react'; 4import { inject, observer } from 'mobx-react';
5import { defineMessages, intlShape } from 'react-intl'; 5import { defineMessages, intlShape } from 'react-intl';
6import injectSheet from 'react-jss'; 6import injectSheet from 'react-jss';
7import { themeSidebarWidth } from '@meetfranz/theme/lib/themes/legacy'; 7import { themeSidebarWidth } from '../../../../packages/theme/lib/themes/legacy';
8import state from './state'; 8import { announcementsStore } from '../index';
9 9
10const messages = defineMessages({ 10const messages = defineMessages({
11 headline: { 11 headline: {
@@ -61,12 +61,14 @@ class AnnouncementScreen extends Component {
61 return ( 61 return (
62 <div className={`${classes.container}`}> 62 <div className={`${classes.container}`}>
63 <h1 className={classes.headline}> 63 <h1 className={classes.headline}>
64 {intl.formatMessage(messages.headline, { version: state.currentVersion })} 64 {intl.formatMessage(messages.headline, {
65 version: announcementsStore.currentVersion,
66 })}
65 </h1> 67 </h1>
66 <div 68 <div
67 className={classes.body} 69 className={classes.body}
68 dangerouslySetInnerHTML={{ 70 dangerouslySetInnerHTML={{
69 __html: marked(state.announcement, { sanitize: true }), 71 __html: marked(announcementsStore.announcement, { sanitize: true }),
70 }} 72 }}
71 /> 73 />
72 </div> 74 </div>
diff --git a/src/features/announcements/index.js b/src/features/announcements/index.js
index 5ea74e0af..c087689a7 100644
--- a/src/features/announcements/index.js
+++ b/src/features/announcements/index.js
@@ -1,11 +1,9 @@
1import { reaction, runInAction } from 'mobx'; 1import { reaction } from 'mobx';
2import { AnnouncementsStore } from './store'; 2import { AnnouncementsStore } from './store';
3import api from './api';
4import state, { resetState } from './state';
5 3
6const debug = require('debug')('Franz:feature:announcements'); 4const debug = require('debug')('Franz:feature:announcements');
7 5
8let store = null; 6export const announcementsStore = new AnnouncementsStore();
9 7
10export default function initAnnouncements(stores, actions) { 8export default function initAnnouncements(stores, actions) {
11 // const { features } = stores; 9 // const { features } = stores;
@@ -19,15 +17,10 @@ export default function initAnnouncements(stores, actions) {
19 (isEnabled) => { 17 (isEnabled) => {
20 if (isEnabled) { 18 if (isEnabled) {
21 debug('Initializing `announcements` feature'); 19 debug('Initializing `announcements` feature');
22 store = new AnnouncementsStore(stores, api, actions, state); 20 announcementsStore.start(stores, actions);
23 store.initialize(); 21 } else if (announcementsStore.isFeatureActive) {
24 runInAction(() => { state.isFeatureActive = true; });
25 } else if (store) {
26 debug('Disabling `announcements` feature'); 22 debug('Disabling `announcements` feature');
27 runInAction(() => { state.isFeatureActive = false; }); 23 announcementsStore.stop();
28 store.teardown();
29 store = null;
30 resetState(); // Reset state to default
31 } 24 }
32 }, 25 },
33 { 26 {
diff --git a/src/features/announcements/state.js b/src/features/announcements/state.js
deleted file mode 100644
index 81b632253..000000000
--- a/src/features/announcements/state.js
+++ /dev/null
@@ -1,17 +0,0 @@
1import { observable } from 'mobx';
2
3const defaultState = {
4 announcement: null,
5 currentVersion: null,
6 lastUsedVersion: null,
7 isAnnouncementVisible: false,
8 isFeatureActive: false,
9};
10
11export const announcementsState = observable(defaultState);
12
13export function resetState() {
14 Object.assign(announcementsState, defaultState);
15}
16
17export default announcementsState;
diff --git a/src/features/announcements/store.js b/src/features/announcements/store.js
index 004a44062..c59700926 100644
--- a/src/features/announcements/store.js
+++ b/src/features/announcements/store.js
@@ -1,28 +1,39 @@
1import { action, observable, reaction } from 'mobx'; 1import { action, observable, reaction } from 'mobx';
2import semver from 'semver'; 2import semver from 'semver';
3 3import { FeatureStore } from '../utils/FeatureStore';
4import Request from '../../stores/lib/Request'; 4import { getAnnouncementRequest, getCurrentVersionRequest } from './api';
5import Store from '../../stores/lib/Store';
6 5
7const debug = require('debug')('Franz:feature:announcements:store'); 6const debug = require('debug')('Franz:feature:announcements:store');
8 7
9export class AnnouncementsStore extends Store { 8export class AnnouncementsStore extends FeatureStore {
10 @observable getCurrentVersion = new Request(this.api, 'getCurrentVersion');
11 9
12 @observable getAnnouncement = new Request(this.api, 'getAnnouncementForVersion'); 10 @observable announcement = null;
13 11
14 constructor(stores, api, actions, state) { 12 @observable currentVersion = null;
15 super(stores, api, actions); 13
16 this.state = state; 14 @observable lastUsedVersion = null;
17 } 15
16 @observable isAnnouncementVisible = false;
18 17
19 async setup() { 18 @observable isFeatureActive = false;
19
20 async start(stores, actions) {
21 debug('AnnouncementsStore::start');
22 this.stores = stores;
23 this.actions = actions;
20 await this.fetchLastUsedVersion(); 24 await this.fetchLastUsedVersion();
21 await this.fetchCurrentVersion(); 25 await this.fetchCurrentVersion();
22 await this.fetchReleaseAnnouncement(); 26 await this.fetchReleaseAnnouncement();
23 this.showAnnouncementIfNotSeenYet(); 27 this.showAnnouncementIfNotSeenYet();
24 28
25 this.actions.announcements.show.listen(this._showAnnouncement.bind(this)); 29 this.actions.announcements.show.listen(this._showAnnouncement.bind(this));
30 this.isFeatureActive = true;
31 }
32
33 stop() {
34 debug('AnnouncementsStore::stop');
35 this.isFeatureActive = false;
36 this.isAnnouncementVisible = false;
26 } 37 }
27 38
28 // ====== PUBLIC ====== 39 // ====== PUBLIC ======
@@ -35,14 +46,14 @@ export class AnnouncementsStore extends Store {
35 46
36 async fetchCurrentVersion() { 47 async fetchCurrentVersion() {
37 debug('getting current version from api'); 48 debug('getting current version from api');
38 const version = await this.getCurrentVersion.execute(); 49 const version = await getCurrentVersionRequest.execute();
39 this._setCurrentVersion(version); 50 this._setCurrentVersion(version);
40 } 51 }
41 52
42 async fetchReleaseAnnouncement() { 53 async fetchReleaseAnnouncement() {
43 debug('getting release announcement from api'); 54 debug('getting release announcement from api');
44 try { 55 try {
45 const announcement = await this.getAnnouncement.execute(this.state.currentVersion); 56 const announcement = await getAnnouncementRequest.execute(this.currentVersion);
46 this._setAnnouncement(announcement); 57 this._setAnnouncement(announcement);
47 } catch (error) { 58 } catch (error) {
48 this._setAnnouncement(null); 59 this._setAnnouncement(null);
@@ -50,7 +61,7 @@ export class AnnouncementsStore extends Store {
50 } 61 }
51 62
52 showAnnouncementIfNotSeenYet() { 63 showAnnouncementIfNotSeenYet() {
53 const { announcement, currentVersion, lastUsedVersion } = this.state; 64 const { announcement, currentVersion, lastUsedVersion } = this;
54 if (announcement && semver.gt(currentVersion, lastUsedVersion)) { 65 if (announcement && semver.gt(currentVersion, lastUsedVersion)) {
55 debug(`${currentVersion} < ${lastUsedVersion}: announcement is shown`); 66 debug(`${currentVersion} < ${lastUsedVersion}: announcement is shown`);
56 this._showAnnouncement(); 67 this._showAnnouncement();
@@ -64,21 +75,21 @@ export class AnnouncementsStore extends Store {
64 75
65 @action _setCurrentVersion(version) { 76 @action _setCurrentVersion(version) {
66 debug(`setting current version to ${version}`); 77 debug(`setting current version to ${version}`);
67 this.state.currentVersion = version; 78 this.currentVersion = version;
68 } 79 }
69 80
70 @action _setLastUsedVersion(version) { 81 @action _setLastUsedVersion(version) {
71 debug(`setting last used version to ${version}`); 82 debug(`setting last used version to ${version}`);
72 this.state.lastUsedVersion = version; 83 this.lastUsedVersion = version;
73 } 84 }
74 85
75 @action _setAnnouncement(announcement) { 86 @action _setAnnouncement(announcement) {
76 debug(`setting announcement to ${announcement}`); 87 debug(`setting announcement to ${announcement}`);
77 this.state.announcement = announcement; 88 this.announcement = announcement;
78 } 89 }
79 90
80 @action _showAnnouncement() { 91 @action _showAnnouncement() {
81 this.state.isAnnouncementVisible = true; 92 this.isAnnouncementVisible = true;
82 this.actions.service.blurActive(); 93 this.actions.service.blurActive();
83 const dispose = reaction( 94 const dispose = reaction(
84 () => this.stores.services.active, 95 () => this.stores.services.active,
@@ -90,6 +101,6 @@ export class AnnouncementsStore extends Store {
90 } 101 }
91 102
92 @action _hideAnnouncement() { 103 @action _hideAnnouncement() {
93 this.state.isAnnouncementVisible = false; 104 this.isAnnouncementVisible = false;
94 } 105 }
95} 106}
diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json
index 698698515..1dd31324e 100644
--- a/src/i18n/locales/defaultMessages.json
+++ b/src/i18n/locales/defaultMessages.json
@@ -3100,6 +3100,24 @@
3100 { 3100 {
3101 "descriptors": [ 3101 "descriptors": [
3102 { 3102 {
3103 "defaultMessage": "!!!What's new in Franz {version}?",
3104 "end": {
3105 "column": 3,
3106 "line": 14
3107 },
3108 "file": "src/features/announcements/components/AnnouncementScreen.js",
3109 "id": "feature.announcements.headline",
3110 "start": {
3111 "column": 12,
3112 "line": 11
3113 }
3114 }
3115 ],
3116 "path": "src/features/announcements/components/AnnouncementScreen.json"
3117 },
3118 {
3119 "descriptors": [
3120 {
3103 "defaultMessage": "!!!Please purchase license to skip waiting", 3121 "defaultMessage": "!!!Please purchase license to skip waiting",
3104 "end": { 3122 "end": {
3105 "column": 3, 3123 "column": 3,
diff --git a/src/i18n/messages/src/features/announcements/components/AnnouncementScreen.json b/src/i18n/messages/src/features/announcements/components/AnnouncementScreen.json
new file mode 100644
index 000000000..225670ee2
--- /dev/null
+++ b/src/i18n/messages/src/features/announcements/components/AnnouncementScreen.json
@@ -0,0 +1,15 @@
1[
2 {
3 "id": "feature.announcements.headline",
4 "defaultMessage": "!!!What's new in Franz {version}?",
5 "file": "src/features/announcements/components/AnnouncementScreen.js",
6 "start": {
7 "line": 11,
8 "column": 12
9 },
10 "end": {
11 "line": 14,
12 "column": 3
13 }
14 }
15] \ No newline at end of file