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