diff options
Diffstat (limited to 'src/features/todos/store.js')
-rw-r--r-- | src/features/todos/store.js | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/src/features/todos/store.js b/src/features/todos/store.js new file mode 100644 index 000000000..acf95df0d --- /dev/null +++ b/src/features/todos/store.js | |||
@@ -0,0 +1,147 @@ | |||
1 | import { ThemeType } from '@meetfranz/theme'; | ||
2 | import { | ||
3 | computed, | ||
4 | action, | ||
5 | observable, | ||
6 | } from 'mobx'; | ||
7 | import localStorage from 'mobx-localstorage'; | ||
8 | |||
9 | import { todoActions } from './actions'; | ||
10 | import { FeatureStore } from '../utils/FeatureStore'; | ||
11 | import { createReactions } from '../../stores/lib/Reaction'; | ||
12 | import { createActionBindings } from '../utils/ActionBinding'; | ||
13 | import { DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH, DEFAULT_TODOS_VISIBLE } from '.'; | ||
14 | import { IPC } from './constants'; | ||
15 | |||
16 | const debug = require('debug')('Franz:feature:todos:store'); | ||
17 | |||
18 | export default class TodoStore extends FeatureStore { | ||
19 | @observable isFeatureEnabled = false; | ||
20 | |||
21 | @observable isFeatureActive = false; | ||
22 | |||
23 | webview = null; | ||
24 | |||
25 | @computed get width() { | ||
26 | const width = this.settings.width || DEFAULT_TODOS_WIDTH; | ||
27 | |||
28 | return width < TODOS_MIN_WIDTH ? TODOS_MIN_WIDTH : width; | ||
29 | } | ||
30 | |||
31 | @computed get isTodosPanelVisible() { | ||
32 | if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; | ||
33 | |||
34 | return this.settings.isTodosPanelVisible; | ||
35 | } | ||
36 | |||
37 | @computed get settings() { | ||
38 | return localStorage.getItem('todos') || {}; | ||
39 | } | ||
40 | |||
41 | // ========== PUBLIC API ========= // | ||
42 | |||
43 | @action start(stores, actions) { | ||
44 | debug('TodoStore::start'); | ||
45 | this.stores = stores; | ||
46 | this.actions = actions; | ||
47 | |||
48 | // ACTIONS | ||
49 | |||
50 | this._registerActions(createActionBindings([ | ||
51 | [todoActions.resize, this._resize], | ||
52 | [todoActions.toggleTodosPanel, this._toggleTodosPanel], | ||
53 | [todoActions.setTodosWebview, this._setTodosWebview], | ||
54 | [todoActions.handleHostMessage, this._handleHostMessage], | ||
55 | [todoActions.handleClientMessage, this._handleClientMessage], | ||
56 | ])); | ||
57 | |||
58 | // REACTIONS | ||
59 | |||
60 | this._allReactions = createReactions([ | ||
61 | this._setFeatureEnabledReaction, | ||
62 | ]); | ||
63 | |||
64 | this._registerReactions(this._allReactions); | ||
65 | |||
66 | this.isFeatureActive = true; | ||
67 | } | ||
68 | |||
69 | @action stop() { | ||
70 | super.stop(); | ||
71 | debug('TodoStore::stop'); | ||
72 | this.reset(); | ||
73 | this.isFeatureActive = false; | ||
74 | } | ||
75 | |||
76 | // ========== PRIVATE METHODS ========= // | ||
77 | |||
78 | _updateSettings = (changes) => { | ||
79 | localStorage.setItem('todos', { | ||
80 | ...this.settings, | ||
81 | ...changes, | ||
82 | }); | ||
83 | }; | ||
84 | |||
85 | // Actions | ||
86 | |||
87 | @action _resize = ({ width }) => { | ||
88 | this._updateSettings({ | ||
89 | width, | ||
90 | }); | ||
91 | }; | ||
92 | |||
93 | @action _toggleTodosPanel = () => { | ||
94 | this._updateSettings({ | ||
95 | isTodosPanelVisible: !this.isTodosPanelVisible, | ||
96 | }); | ||
97 | }; | ||
98 | |||
99 | @action _setTodosWebview = ({ webview }) => { | ||
100 | debug('_setTodosWebview', webview); | ||
101 | this.webview = webview; | ||
102 | }; | ||
103 | |||
104 | @action _handleHostMessage = (message) => { | ||
105 | debug('_handleHostMessage', message); | ||
106 | if (message.action === 'todos:create') { | ||
107 | this.webview.send(IPC.TODOS_HOST_CHANNEL, message); | ||
108 | } | ||
109 | }; | ||
110 | |||
111 | @action _handleClientMessage = (message) => { | ||
112 | debug('_handleClientMessage', message); | ||
113 | switch (message.action) { | ||
114 | case 'todos:initialized': this._onTodosClientInitialized(); break; | ||
115 | case 'todos:goToService': this._goToService(message.data); break; | ||
116 | default: | ||
117 | debug('Unknown client message reiceived', message); | ||
118 | } | ||
119 | }; | ||
120 | |||
121 | // Todos client message handlers | ||
122 | |||
123 | _onTodosClientInitialized = () => { | ||
124 | this.webview.send(IPC.TODOS_HOST_CHANNEL, { | ||
125 | action: 'todos:configure', | ||
126 | data: { | ||
127 | authToken: this.stores.user.authToken, | ||
128 | theme: this.stores.ui.isDarkThemeActive ? ThemeType.dark : ThemeType.default, | ||
129 | }, | ||
130 | }); | ||
131 | }; | ||
132 | |||
133 | _goToService = ({ url, serviceId }) => { | ||
134 | if (url) { | ||
135 | this.stores.services.one(serviceId).webview.loadURL(url); | ||
136 | } | ||
137 | this.actions.service.setActive({ serviceId }); | ||
138 | }; | ||
139 | |||
140 | // Reactions | ||
141 | |||
142 | _setFeatureEnabledReaction = () => { | ||
143 | const { isTodosEnabled } = this.stores.features.features; | ||
144 | |||
145 | this.isFeatureEnabled = isTodosEnabled; | ||
146 | }; | ||
147 | } | ||