aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/todos/store.js
diff options
context:
space:
mode:
authorLibravatar vantezzen <properly@protonmail.com>2019-09-07 15:50:23 +0200
committerLibravatar vantezzen <properly@protonmail.com>2019-09-07 15:50:23 +0200
commite7a74514c1e7c3833dfdcf5900cb87f9e6e8354e (patch)
treeb8314e4155503b135dcb07e8b4a0e847e25c19cf /src/features/todos/store.js
parentUpdate CHANGELOG.md (diff)
parentUpdate CHANGELOG.md (diff)
downloadferdium-app-e7a74514c1e7c3833dfdcf5900cb87f9e6e8354e.tar.gz
ferdium-app-e7a74514c1e7c3833dfdcf5900cb87f9e6e8354e.tar.zst
ferdium-app-e7a74514c1e7c3833dfdcf5900cb87f9e6e8354e.zip
Merge branch 'master' of https://github.com/meetfranz/franz into franz-5.3.0
Diffstat (limited to 'src/features/todos/store.js')
-rw-r--r--src/features/todos/store.js213
1 files changed, 213 insertions, 0 deletions
diff --git a/src/features/todos/store.js b/src/features/todos/store.js
new file mode 100644
index 000000000..05eef4ec1
--- /dev/null
+++ b/src/features/todos/store.js
@@ -0,0 +1,213 @@
1import { ThemeType } from '@meetfranz/theme';
2import {
3 computed,
4 action,
5 observable,
6} from 'mobx';
7import localStorage from 'mobx-localstorage';
8
9import { todoActions } from './actions';
10import { FeatureStore } from '../utils/FeatureStore';
11import { createReactions } from '../../stores/lib/Reaction';
12import { createActionBindings } from '../utils/ActionBinding';
13import {
14 DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH, DEFAULT_TODOS_VISIBLE, TODOS_ROUTES, DEFAULT_IS_FEATURE_ENABLED_BY_USER,
15} from '.';
16import { IPC } from './constants';
17import { state as delayAppState } from '../delayApp';
18
19const debug = require('debug')('Franz:feature:todos:store');
20
21export default class TodoStore extends FeatureStore {
22 @observable isFeatureEnabled = false;
23
24 @observable isFeatureActive = false;
25
26 webview = null;
27
28 @computed get width() {
29 const width = this.settings.width || DEFAULT_TODOS_WIDTH;
30
31 return width < TODOS_MIN_WIDTH ? TODOS_MIN_WIDTH : width;
32 }
33
34 @computed get isTodosPanelForceHidden() {
35 const { isAnnouncementShown } = this.stores.announcements;
36 return delayAppState.isDelayAppScreenVisible || !this.settings.isFeatureEnabledByUser || isAnnouncementShown;
37 }
38
39 @computed get isTodosPanelVisible() {
40 if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE;
41 return this.settings.isTodosPanelVisible;
42 }
43
44 @computed get settings() {
45 return localStorage.getItem('todos') || {};
46 }
47
48 // ========== PUBLIC API ========= //
49
50 @action start(stores, actions) {
51 debug('TodoStore::start');
52 this.stores = stores;
53 this.actions = actions;
54
55 // ACTIONS
56
57 this._registerActions(createActionBindings([
58 [todoActions.resize, this._resize],
59 [todoActions.toggleTodosPanel, this._toggleTodosPanel],
60 [todoActions.setTodosWebview, this._setTodosWebview],
61 [todoActions.handleHostMessage, this._handleHostMessage],
62 [todoActions.handleClientMessage, this._handleClientMessage],
63 [todoActions.toggleTodosFeatureVisibility, this._toggleTodosFeatureVisibility],
64 ]));
65
66 // REACTIONS
67
68 this._allReactions = createReactions([
69 this._setFeatureEnabledReaction,
70 this._updateTodosConfig,
71 this._firstLaunchReaction,
72 this._routeCheckReaction,
73 ]);
74
75 this._registerReactions(this._allReactions);
76
77 this.isFeatureActive = true;
78
79 if (this.settings.isFeatureEnabledByUser === undefined) {
80 this._updateSettings({
81 isFeatureEnabledByUser: DEFAULT_IS_FEATURE_ENABLED_BY_USER,
82 });
83 }
84 }
85
86 @action stop() {
87 super.stop();
88 debug('TodoStore::stop');
89 this.reset();
90 this.isFeatureActive = false;
91 }
92
93 // ========== PRIVATE METHODS ========= //
94
95 _updateSettings = (changes) => {
96 localStorage.setItem('todos', {
97 ...this.settings,
98 ...changes,
99 });
100 };
101
102 // Actions
103
104 @action _resize = ({ width }) => {
105 this._updateSettings({
106 width,
107 });
108 };
109
110 @action _toggleTodosPanel = () => {
111 this._updateSettings({
112 isTodosPanelVisible: !this.isTodosPanelVisible,
113 });
114 };
115
116 @action _setTodosWebview = ({ webview }) => {
117 debug('_setTodosWebview', webview);
118 this.webview = webview;
119 };
120
121 @action _handleHostMessage = (message) => {
122 debug('_handleHostMessage', message);
123 if (message.action === 'todos:create') {
124 this.webview.send(IPC.TODOS_HOST_CHANNEL, message);
125 }
126 };
127
128 @action _handleClientMessage = (message) => {
129 debug('_handleClientMessage', message);
130 switch (message.action) {
131 case 'todos:initialized': this._onTodosClientInitialized(); break;
132 case 'todos:goToService': this._goToService(message.data); break;
133 default:
134 debug('Unknown client message reiceived', message);
135 }
136 };
137
138 @action _toggleTodosFeatureVisibility = () => {
139 debug('_toggleTodosFeatureVisibility');
140
141 this._updateSettings({
142 isFeatureEnabledByUser: !this.settings.isFeatureEnabledByUser,
143 });
144 };
145
146 // Todos client message handlers
147
148 _onTodosClientInitialized = () => {
149 const { authToken } = this.stores.user;
150 const { isDarkThemeActive } = this.stores.ui;
151 const { locale } = this.stores.app;
152 if (!this.webview) return;
153 this.webview.send(IPC.TODOS_HOST_CHANNEL, {
154 action: 'todos:configure',
155 data: {
156 authToken,
157 locale,
158 theme: isDarkThemeActive ? ThemeType.dark : ThemeType.default,
159 },
160 });
161 };
162
163 _goToService = ({ url, serviceId }) => {
164 if (url) {
165 this.stores.services.one(serviceId).webview.loadURL(url);
166 }
167 this.actions.service.setActive({ serviceId });
168 };
169
170 // Reactions
171
172 _setFeatureEnabledReaction = () => {
173 const { isTodosEnabled } = this.stores.features.features;
174
175 this.isFeatureEnabled = isTodosEnabled;
176 };
177
178 _updateTodosConfig = () => {
179 // Resend the config if any part changes in Franz:
180 this._onTodosClientInitialized();
181 };
182
183 _firstLaunchReaction = () => {
184 const { stats } = this.stores.settings.all;
185
186 // Hide todos layer on first app start but show on second
187 if (stats.appStarts <= 1) {
188 this._updateSettings({
189 isTodosPanelVisible: false,
190 });
191 } else if (stats.appStarts <= 2) {
192 this._updateSettings({
193 isTodosPanelVisible: true,
194 });
195 }
196 };
197
198 _routeCheckReaction = () => {
199 const { pathname } = this.stores.router.location;
200
201 if (pathname === TODOS_ROUTES.TARGET) {
202 debug('Router is on todos route, show todos panel');
203 // todosStore.start(stores, actions);
204 this.stores.router.push('/');
205
206 if (!this.isTodosPanelVisible) {
207 this._updateSettings({
208 isTodosPanelVisible: true,
209 });
210 }
211 }
212 }
213}