diff options
Diffstat (limited to 'src/features/announcements/store.js')
-rw-r--r-- | src/features/announcements/store.js | 128 |
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 @@ | |||
1 | import { | ||
2 | action, | ||
3 | computed, | ||
4 | observable, | ||
5 | reaction, | ||
6 | } from 'mobx'; | ||
7 | import semver from 'semver'; | ||
8 | import localStorage from 'mobx-localstorage'; | ||
9 | |||
10 | import { FeatureStore } from '../utils/FeatureStore'; | ||
11 | import { getAnnouncementRequest, getChangelogRequest, getCurrentVersionRequest } from './api'; | ||
12 | import { announcementActions } from './actions'; | ||
13 | import { createActionBindings } from '../utils/ActionBinding'; | ||
14 | import { createReactions } from '../../stores/lib/Reaction'; | ||
15 | |||
16 | const LOCAL_STORAGE_KEY = 'announcements'; | ||
17 | |||
18 | const debug = require('debug')('Franz:feature:announcements:store'); | ||
19 | |||
20 | export 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 | } | ||