aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/announcements/store.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/features/announcements/store.js')
-rw-r--r--src/features/announcements/store.js128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/features/announcements/store.js b/src/features/announcements/store.js
new file mode 100644
index 000000000..0bebf29fd
--- /dev/null
+++ b/src/features/announcements/store.js
@@ -0,0 +1,128 @@
1import {
2 action,
3 computed,
4 observable,
5 reaction,
6} from 'mobx';
7import semver from 'semver';
8import localStorage from 'mobx-localstorage';
9
10import { FeatureStore } from '../utils/FeatureStore';
11import { getAnnouncementRequest, getChangelogRequest, getCurrentVersionRequest } from './api';
12import { announcementActions } from './actions';
13import { createActionBindings } from '../utils/ActionBinding';
14import { createReactions } from '../../stores/lib/Reaction';
15
16const LOCAL_STORAGE_KEY = 'announcements';
17
18const debug = require('debug')('Franz:feature:announcements:store');
19
20export class AnnouncementsStore extends FeatureStore {
21 @observable targetVersion = null;
22
23 @observable isAnnouncementVisible = false;
24
25 @observable isFeatureActive = false;
26
27 @computed get changelog() {
28 return getChangelogRequest.result;
29 }
30
31 @computed get announcement() {
32 return getAnnouncementRequest.result;
33 }
34
35 @computed get settings() {
36 return localStorage.getItem(LOCAL_STORAGE_KEY) || {};
37 }
38
39 @computed get lastSeenAnnouncementVersion() {
40 return this.settings.lastSeenAnnouncementVersion || null;
41 }
42
43 @computed get currentVersion() {
44 return getCurrentVersionRequest.result;
45 }
46
47 @computed get isNewUser() {
48 return this.stores.settings.stats.appStarts <= 1;
49 }
50
51 async start(stores, actions) {
52 debug('AnnouncementsStore::start');
53 this.stores = stores;
54 this.actions = actions;
55 getCurrentVersionRequest.execute();
56
57 this._registerActions(createActionBindings([
58 [announcementActions.show, this._showAnnouncement],
59 ]));
60
61 this._reactions = createReactions([
62 this._fetchAnnouncements,
63 this._showAnnouncementToUsersWhoUpdatedApp,
64 ]);
65 this._registerReactions(this._reactions);
66 this.isFeatureActive = true;
67 }
68
69 stop() {
70 super.stop();
71 debug('AnnouncementsStore::stop');
72 this.isFeatureActive = false;
73 this.isAnnouncementVisible = false;
74 }
75
76 // ======= HELPERS ======= //
77
78 _updateSettings = (changes) => {
79 localStorage.setItem(LOCAL_STORAGE_KEY, {
80 ...this.settings,
81 ...changes,
82 });
83 };
84
85 // ======= ACTIONS ======= //
86
87 @action _showAnnouncement = ({ targetVersion } = {}) => {
88 this.targetVersion = targetVersion || this.currentVersion;
89 this.isAnnouncementVisible = true;
90 this.actions.service.blurActive();
91 this._updateSettings({
92 lastSeenAnnouncementVersion: this.currentVersion,
93 });
94 const dispose = reaction(
95 () => this.stores.services.active,
96 () => {
97 this._hideAnnouncement();
98 dispose();
99 },
100 );
101 };
102
103 @action _hideAnnouncement() {
104 this.isAnnouncementVisible = false;
105 }
106
107 // ======= REACTIONS ========
108
109 _showAnnouncementToUsersWhoUpdatedApp = () => {
110 const { announcement, isNewUser } = this;
111 // Check if there is an announcement and on't show announcements to new users
112 if (!announcement || isNewUser) return;
113
114 // Check if the user has already used current version (= has seen the announcement)
115 const { currentVersion, lastSeenAnnouncementVersion } = this;
116 if (semver.gt(currentVersion, lastSeenAnnouncementVersion)) {
117 debug(`${currentVersion} < ${lastSeenAnnouncementVersion}: announcement is shown`);
118 this._showAnnouncement();
119 }
120 };
121
122 _fetchAnnouncements = () => {
123 const targetVersion = this.targetVersion || this.currentVersion;
124 if (!targetVersion) return;
125 getChangelogRequest.execute(targetVersion);
126 getAnnouncementRequest.execute(targetVersion);
127 }
128}