diff options
author | 2022-06-27 00:02:24 +0200 | |
---|---|---|
committer | 2022-06-26 22:02:24 +0000 | |
commit | 43acb4145e0d19ec9a28a59583510499af624fb7 (patch) | |
tree | b6e0a17424b936f9478c41785c2cdee208d50d26 /src/components/layout/Sidebar.js | |
parent | chore: turned all auth containers into typescript (#375) (diff) | |
download | ferdium-app-43acb4145e0d19ec9a28a59583510499af624fb7.tar.gz ferdium-app-43acb4145e0d19ec9a28a59583510499af624fb7.tar.zst ferdium-app-43acb4145e0d19ec9a28a59583510499af624fb7.zip |
feat: remember collapsed state of hamburger menu on refresh/reboot (#373)
Diffstat (limited to 'src/components/layout/Sidebar.js')
-rw-r--r-- | src/components/layout/Sidebar.js | 331 |
1 files changed, 0 insertions, 331 deletions
diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js deleted file mode 100644 index 1d3c81dcd..000000000 --- a/src/components/layout/Sidebar.js +++ /dev/null | |||
@@ -1,331 +0,0 @@ | |||
1 | import { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import ReactTooltip from 'react-tooltip'; | ||
4 | import { defineMessages, injectIntl } from 'react-intl'; | ||
5 | import { inject, observer } from 'mobx-react'; | ||
6 | import { | ||
7 | mdiCheckAll, | ||
8 | mdiViewGrid, | ||
9 | mdiPlusBox, | ||
10 | mdiCog, | ||
11 | mdiBellOff, | ||
12 | mdiBell, | ||
13 | mdiLock, | ||
14 | mdiMenu, | ||
15 | mdiChevronDown, | ||
16 | mdiChevronRight, | ||
17 | mdiViewSplitVertical, | ||
18 | } from '@mdi/js'; | ||
19 | |||
20 | import Tabbar from '../services/tabs/Tabbar'; | ||
21 | import { | ||
22 | settingsShortcutKey, | ||
23 | lockFerdiumShortcutKey, | ||
24 | todosToggleShortcutKey, | ||
25 | workspaceToggleShortcutKey, | ||
26 | addNewServiceShortcutKey, | ||
27 | splitModeToggleShortcutKey, | ||
28 | muteFerdiumShortcutKey, | ||
29 | } from '../../environment'; | ||
30 | import { todosStore } from '../../features/todos'; | ||
31 | import { todoActions } from '../../features/todos/actions'; | ||
32 | import AppStore from '../../stores/AppStore'; | ||
33 | import SettingsStore from '../../stores/SettingsStore'; | ||
34 | import globalMessages from '../../i18n/globalMessages'; | ||
35 | import { Icon } from '../ui/icon'; | ||
36 | |||
37 | const messages = defineMessages({ | ||
38 | addNewService: { | ||
39 | id: 'sidebar.addNewService', | ||
40 | defaultMessage: 'Add new service', | ||
41 | }, | ||
42 | splitModeToggle: { | ||
43 | id: 'sidebar.splitModeToggle', | ||
44 | defaultMessage: 'Split Mode Toggle', | ||
45 | }, | ||
46 | mute: { | ||
47 | id: 'sidebar.muteApp', | ||
48 | defaultMessage: 'Disable notifications & audio', | ||
49 | }, | ||
50 | unmute: { | ||
51 | id: 'sidebar.unmuteApp', | ||
52 | defaultMessage: 'Enable notifications & audio', | ||
53 | }, | ||
54 | openWorkspaceDrawer: { | ||
55 | id: 'sidebar.openWorkspaceDrawer', | ||
56 | defaultMessage: 'Open workspace drawer', | ||
57 | }, | ||
58 | closeWorkspaceDrawer: { | ||
59 | id: 'sidebar.closeWorkspaceDrawer', | ||
60 | defaultMessage: 'Close workspace drawer', | ||
61 | }, | ||
62 | openTodosDrawer: { | ||
63 | id: 'sidebar.openTodosDrawer', | ||
64 | defaultMessage: 'Open Ferdium Todos', | ||
65 | }, | ||
66 | closeTodosDrawer: { | ||
67 | id: 'sidebar.closeTodosDrawer', | ||
68 | defaultMessage: 'Close Ferdium Todos', | ||
69 | }, | ||
70 | lockFerdium: { | ||
71 | id: 'sidebar.lockFerdium', | ||
72 | defaultMessage: 'Lock Ferdium', | ||
73 | }, | ||
74 | }); | ||
75 | |||
76 | class Sidebar extends Component { | ||
77 | static propTypes = { | ||
78 | openSettings: PropTypes.func.isRequired, | ||
79 | closeSettings: PropTypes.func.isRequired, | ||
80 | setActive: PropTypes.func.isRequired, | ||
81 | reorder: PropTypes.func.isRequired, | ||
82 | reload: PropTypes.func.isRequired, | ||
83 | toggleNotifications: PropTypes.func.isRequired, | ||
84 | toggleAudio: PropTypes.func.isRequired, | ||
85 | toggleDarkMode: PropTypes.func.isRequired, | ||
86 | showServicesUpdatedInfoBar: PropTypes.bool.isRequired, | ||
87 | showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired, | ||
88 | showServiceNameSetting: PropTypes.bool.isRequired, | ||
89 | showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired, | ||
90 | deleteService: PropTypes.func.isRequired, | ||
91 | updateService: PropTypes.func.isRequired, | ||
92 | hibernateService: PropTypes.func.isRequired, | ||
93 | wakeUpService: PropTypes.func.isRequired, | ||
94 | toggleMuteApp: PropTypes.func.isRequired, | ||
95 | isAppMuted: PropTypes.bool.isRequired, | ||
96 | isWorkspaceDrawerOpen: PropTypes.bool.isRequired, | ||
97 | toggleWorkspaceDrawer: PropTypes.func.isRequired, | ||
98 | isTodosServiceActive: PropTypes.bool.isRequired, | ||
99 | stores: PropTypes.shape({ | ||
100 | app: PropTypes.instanceOf(AppStore).isRequired, | ||
101 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | ||
102 | }).isRequired, | ||
103 | actions: PropTypes.shape({ | ||
104 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | ||
105 | }).isRequired, | ||
106 | }; | ||
107 | |||
108 | state = { | ||
109 | tooltipEnabled: true, | ||
110 | isCollapsed: false | ||
111 | }; | ||
112 | |||
113 | componentDidUpdate() { | ||
114 | ReactTooltip.rebuild(); | ||
115 | } | ||
116 | |||
117 | enableToolTip() { | ||
118 | this.setState({ tooltipEnabled: true }); | ||
119 | } | ||
120 | |||
121 | disableToolTip() { | ||
122 | this.setState({ tooltipEnabled: false }); | ||
123 | } | ||
124 | |||
125 | collapseMenu() { | ||
126 | this.setState((prevState) => ({ isCollapsed: !prevState.isCollapsed })); | ||
127 | } | ||
128 | |||
129 | updateToolTip() { | ||
130 | this.disableToolTip(); | ||
131 | setTimeout(this.enableToolTip.bind(this)); | ||
132 | } | ||
133 | |||
134 | render() { | ||
135 | const { | ||
136 | openSettings, | ||
137 | toggleMuteApp, | ||
138 | isAppMuted, | ||
139 | isWorkspaceDrawerOpen, | ||
140 | toggleWorkspaceDrawer, | ||
141 | stores, | ||
142 | actions, | ||
143 | isTodosServiceActive, | ||
144 | } = this.props; | ||
145 | const { | ||
146 | hideCollapseButton, | ||
147 | hideRecipesButton, | ||
148 | hideWorkspacesButton, | ||
149 | hideNotificationsButton, | ||
150 | hideSettingsButton, | ||
151 | hideSplitModeButton, | ||
152 | useVerticalStyle, | ||
153 | splitMode, | ||
154 | } = stores.settings.app; | ||
155 | const { intl } = this.props; | ||
156 | const todosToggleMessage = todosStore.isTodosPanelVisible | ||
157 | ? messages.closeTodosDrawer | ||
158 | : messages.openTodosDrawer; | ||
159 | |||
160 | const workspaceToggleMessage = isWorkspaceDrawerOpen | ||
161 | ? messages.closeWorkspaceDrawer | ||
162 | : messages.openWorkspaceDrawer; | ||
163 | |||
164 | const numberActiveButtons = [ | ||
165 | !hideRecipesButton, | ||
166 | !hideWorkspacesButton, | ||
167 | !hideNotificationsButton, | ||
168 | !hideSettingsButton, | ||
169 | !hideSplitModeButton, | ||
170 | todosStore.isFeatureEnabledByUser | ||
171 | ].filter(Boolean).length; | ||
172 | |||
173 | return ( | ||
174 | <div className="sidebar"> | ||
175 | <Tabbar | ||
176 | {...this.props} | ||
177 | enableToolTip={() => this.enableToolTip()} | ||
178 | disableToolTip={() => this.disableToolTip()} | ||
179 | useVerticalStyle={stores.settings.all.app.useVerticalStyle} | ||
180 | /> | ||
181 | <> | ||
182 | {numberActiveButtons <= 1 || hideCollapseButton ? ( | ||
183 | null | ||
184 | ) : | ||
185 | <button | ||
186 | type="button" | ||
187 | onClick={() => this.collapseMenu()} | ||
188 | className="sidebar__button sidebar__button--hamburger-menu" | ||
189 | > | ||
190 | {this.state.isCollapsed ? | ||
191 | <Icon icon={mdiMenu} size={1.5} /> | ||
192 | : | ||
193 | (useVerticalStyle) ? | ||
194 | <Icon icon={mdiChevronRight} size={1.5} /> | ||
195 | : | ||
196 | <Icon icon={mdiChevronDown} size={1.5} /> | ||
197 | } | ||
198 | </button> | ||
199 | } | ||
200 | {!hideRecipesButton && !this.state.isCollapsed ? ( | ||
201 | <button | ||
202 | type="button" | ||
203 | onClick={() => openSettings({ path: 'recipes' })} | ||
204 | className="sidebar__button sidebar__button--new-service" | ||
205 | data-tip={`${intl.formatMessage( | ||
206 | messages.addNewService, | ||
207 | )} (${addNewServiceShortcutKey(false)})`} | ||
208 | > | ||
209 | <Icon icon={mdiPlusBox} size={1.5} /> | ||
210 | </button> | ||
211 | ) : null} | ||
212 | {!hideSplitModeButton && !this.state.isCollapsed ? ( | ||
213 | <button | ||
214 | type="button" | ||
215 | onClick={() => { | ||
216 | actions.settings.update({ | ||
217 | type: 'app', | ||
218 | data: { | ||
219 | splitMode: !splitMode, | ||
220 | }, | ||
221 | }); | ||
222 | }} | ||
223 | className="sidebar__button sidebar__button--split-mode-toggle" | ||
224 | data-tip={`${intl.formatMessage( | ||
225 | messages.splitModeToggle, | ||
226 | )} (${splitModeToggleShortcutKey(false)})`} | ||
227 | > | ||
228 | <Icon icon={mdiViewSplitVertical} size={1.5} /> | ||
229 | </button> | ||
230 | ) : null} | ||
231 | {!hideWorkspacesButton && !this.state.isCollapsed ? ( | ||
232 | <button | ||
233 | type="button" | ||
234 | onClick={() => { | ||
235 | toggleWorkspaceDrawer(); | ||
236 | this.updateToolTip(); | ||
237 | }} | ||
238 | className={`sidebar__button sidebar__button--workspaces ${ | ||
239 | isWorkspaceDrawerOpen ? 'is-active' : '' | ||
240 | }`} | ||
241 | data-tip={`${intl.formatMessage( | ||
242 | workspaceToggleMessage, | ||
243 | )} (${workspaceToggleShortcutKey(false)})`} | ||
244 | > | ||
245 | <Icon icon={mdiViewGrid} size={1.5} /> | ||
246 | </button> | ||
247 | ) : null} | ||
248 | {!hideNotificationsButton && !this.state.isCollapsed ? ( | ||
249 | <button | ||
250 | type="button" | ||
251 | onClick={() => { | ||
252 | toggleMuteApp(); | ||
253 | this.updateToolTip(); | ||
254 | }} | ||
255 | className={`sidebar__button sidebar__button--audio ${ | ||
256 | isAppMuted ? 'is-muted' : '' | ||
257 | }`} | ||
258 | data-tip={`${intl.formatMessage( | ||
259 | isAppMuted ? messages.unmute : messages.mute, | ||
260 | )} (${muteFerdiumShortcutKey(false)})`} | ||
261 | > | ||
262 | <Icon icon={isAppMuted ? mdiBellOff : mdiBell} size={1.5} /> | ||
263 | </button> | ||
264 | ) : null} | ||
265 | {todosStore.isFeatureEnabledByUser && !this.state.isCollapsed ? ( | ||
266 | <button | ||
267 | type="button" | ||
268 | onClick={() => { | ||
269 | todoActions.toggleTodosPanel(); | ||
270 | this.updateToolTip(); | ||
271 | }} | ||
272 | disabled={isTodosServiceActive} | ||
273 | className={`sidebar__button sidebar__button--todos ${ | ||
274 | todosStore.isTodosPanelVisible ? 'is-active' : '' | ||
275 | }`} | ||
276 | data-tip={`${intl.formatMessage( | ||
277 | todosToggleMessage, | ||
278 | )} (${todosToggleShortcutKey(false)})`} | ||
279 | > | ||
280 | <Icon icon={mdiCheckAll} size={1.5} /> | ||
281 | </button> | ||
282 | ) : null} | ||
283 | {stores.settings.all.app.lockingFeatureEnabled ? ( | ||
284 | <button | ||
285 | type="button" | ||
286 | className="sidebar__button" | ||
287 | onClick={() => { | ||
288 | actions.settings.update({ | ||
289 | type: 'app', | ||
290 | data: { | ||
291 | locked: true, | ||
292 | }, | ||
293 | }); | ||
294 | }} | ||
295 | data-tip={`${intl.formatMessage( | ||
296 | messages.lockFerdium, | ||
297 | )} (${lockFerdiumShortcutKey(false)})`} | ||
298 | > | ||
299 | <Icon icon={mdiLock} size={1.5} /> | ||
300 | </button> | ||
301 | ) : null} | ||
302 | </> | ||
303 | {this.state.tooltipEnabled && ( | ||
304 | <ReactTooltip place="right" type="dark" effect="solid" /> | ||
305 | )} | ||
306 | {!hideSettingsButton && !this.state.isCollapsed ? ( | ||
307 | <button | ||
308 | type="button" | ||
309 | onClick={() => openSettings({ path: 'app' })} | ||
310 | className="sidebar__button sidebar__button--settings" | ||
311 | data-tip={`${intl.formatMessage( | ||
312 | globalMessages.settings, | ||
313 | )} (${settingsShortcutKey(false)})`} | ||
314 | > | ||
315 | <Icon icon={mdiCog} size={1.5} /> | ||
316 | { | ||
317 | this.props.stores.settings.app.automaticUpdates && | ||
318 | (this.props.stores.app.updateStatus === this.props.stores.app.updateStatusTypes.AVAILABLE || | ||
319 | this.props.stores.app.updateStatus === this.props.stores.app.updateStatusTypes.DOWNLOADED || | ||
320 | this.props.showServicesUpdatedInfoBar) && ( | ||
321 | <span className="update-available">•</span> | ||
322 | ) | ||
323 | } | ||
324 | </button> | ||
325 | ) : null} | ||
326 | </div> | ||
327 | ); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | export default injectIntl(inject('stores', 'actions')(observer(Sidebar))); | ||