diff options
author | 2022-10-25 18:14:55 +0530 | |
---|---|---|
committer | 2022-10-25 12:44:55 +0000 | |
commit | b77663a3752467b7be3eff8a765a71330548d8e0 (patch) | |
tree | 16aad95e8d781684b543482f5b4423674f45be08 /src/components/layout/Sidebar.tsx | |
parent | Transform 'AuthLayoutContainer' component hierarchy to tsx (#699) (diff) | |
download | ferdium-app-b77663a3752467b7be3eff8a765a71330548d8e0.tar.gz ferdium-app-b77663a3752467b7be3eff8a765a71330548d8e0.tar.zst ferdium-app-b77663a3752467b7be3eff8a765a71330548d8e0.zip |
refactor: convert Sidebar to typescript (#703)
Diffstat (limited to 'src/components/layout/Sidebar.tsx')
-rw-r--r-- | src/components/layout/Sidebar.tsx | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx new file mode 100644 index 000000000..a81229dca --- /dev/null +++ b/src/components/layout/Sidebar.tsx | |||
@@ -0,0 +1,337 @@ | |||
1 | import { Component } from 'react'; | ||
2 | import ReactTooltip from 'react-tooltip'; | ||
3 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; | ||
4 | import { inject, observer } from 'mobx-react'; | ||
5 | import { | ||
6 | mdiCheckAll, | ||
7 | mdiViewGrid, | ||
8 | mdiPlusBox, | ||
9 | mdiCog, | ||
10 | mdiBellOff, | ||
11 | mdiBell, | ||
12 | mdiLock, | ||
13 | mdiMenu, | ||
14 | mdiChevronDown, | ||
15 | mdiChevronRight, | ||
16 | mdiViewSplitVertical, | ||
17 | } from '@mdi/js'; | ||
18 | |||
19 | import Tabbar from '../services/tabs/Tabbar'; | ||
20 | import { | ||
21 | settingsShortcutKey, | ||
22 | lockFerdiumShortcutKey, | ||
23 | todosToggleShortcutKey, | ||
24 | workspaceToggleShortcutKey, | ||
25 | addNewServiceShortcutKey, | ||
26 | splitModeToggleShortcutKey, | ||
27 | muteFerdiumShortcutKey, | ||
28 | } from '../../environment'; | ||
29 | import { todosStore } from '../../features/todos'; | ||
30 | import { todoActions } from '../../features/todos/actions'; | ||
31 | import globalMessages from '../../i18n/globalMessages'; | ||
32 | import Icon from '../ui/icon'; | ||
33 | import { Actions } from '../../actions/lib/actions'; | ||
34 | import { RealStores } from '../../stores'; | ||
35 | import Service from '../../models/Service'; | ||
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 | interface IProps extends WrappedComponentProps { | ||
77 | services: Service[]; | ||
78 | showServicesUpdatedInfoBar: boolean; | ||
79 | showMessageBadgeWhenMutedSetting: boolean; | ||
80 | showServiceNameSetting: boolean; | ||
81 | showMessageBadgesEvenWhenMuted: boolean; | ||
82 | isAppMuted: boolean; | ||
83 | isMenuCollapsed: boolean; | ||
84 | isWorkspaceDrawerOpen: boolean; | ||
85 | isTodosServiceActive: boolean; | ||
86 | actions?: Actions; | ||
87 | stores?: RealStores; | ||
88 | |||
89 | deleteService: () => void; | ||
90 | updateService: () => void; | ||
91 | hibernateService: () => void; | ||
92 | wakeUpService: () => void; | ||
93 | toggleMuteApp: () => void; | ||
94 | toggleCollapseMenu: () => void; | ||
95 | toggleWorkspaceDrawer: () => void; | ||
96 | openSettings: (arg: { path: string }) => void; | ||
97 | closeSettings: () => void; | ||
98 | setActive: () => void; | ||
99 | reorder: () => void; | ||
100 | reload: () => void; | ||
101 | toggleNotifications: () => void; | ||
102 | toggleAudio: () => void; | ||
103 | toggleDarkMode: () => void; | ||
104 | } | ||
105 | |||
106 | interface IState { | ||
107 | tooltipEnabled: boolean; | ||
108 | } | ||
109 | |||
110 | @observer | ||
111 | @inject('stores', 'actions') | ||
112 | class Sidebar extends Component<IProps, IState> { | ||
113 | constructor(props) { | ||
114 | super(props); | ||
115 | |||
116 | this.state = { | ||
117 | tooltipEnabled: true, | ||
118 | }; | ||
119 | } | ||
120 | |||
121 | componentDidUpdate() { | ||
122 | ReactTooltip.rebuild(); | ||
123 | } | ||
124 | |||
125 | enableToolTip() { | ||
126 | this.setState({ tooltipEnabled: true }); | ||
127 | } | ||
128 | |||
129 | disableToolTip() { | ||
130 | this.setState({ tooltipEnabled: false }); | ||
131 | } | ||
132 | |||
133 | updateToolTip() { | ||
134 | this.disableToolTip(); | ||
135 | setTimeout(this.enableToolTip.bind(this)); | ||
136 | } | ||
137 | |||
138 | render() { | ||
139 | const { | ||
140 | openSettings, | ||
141 | toggleMuteApp, | ||
142 | toggleCollapseMenu, | ||
143 | isAppMuted, | ||
144 | isWorkspaceDrawerOpen, | ||
145 | toggleWorkspaceDrawer, | ||
146 | stores, | ||
147 | actions, | ||
148 | isTodosServiceActive, | ||
149 | } = this.props; | ||
150 | const { | ||
151 | hideCollapseButton, | ||
152 | hideRecipesButton, | ||
153 | hideWorkspacesButton, | ||
154 | hideNotificationsButton, | ||
155 | hideSettingsButton, | ||
156 | hideSplitModeButton, | ||
157 | useHorizontalStyle, | ||
158 | splitMode, | ||
159 | } = stores!.settings.app; | ||
160 | const { intl } = this.props; | ||
161 | const todosToggleMessage = todosStore.isTodosPanelVisible | ||
162 | ? messages.closeTodosDrawer | ||
163 | : messages.openTodosDrawer; | ||
164 | |||
165 | const workspaceToggleMessage = isWorkspaceDrawerOpen | ||
166 | ? messages.closeWorkspaceDrawer | ||
167 | : messages.openWorkspaceDrawer; | ||
168 | |||
169 | const numberActiveButtons = [ | ||
170 | !hideRecipesButton, | ||
171 | !hideWorkspacesButton, | ||
172 | !hideNotificationsButton, | ||
173 | !hideSettingsButton, | ||
174 | !hideSplitModeButton, | ||
175 | todosStore.isFeatureEnabledByUser, | ||
176 | ].filter(Boolean).length; | ||
177 | |||
178 | const { isMenuCollapsed } = stores!.settings.all.app; | ||
179 | |||
180 | return ( | ||
181 | <div className="sidebar"> | ||
182 | <Tabbar | ||
183 | {...this.props} | ||
184 | enableToolTip={() => this.enableToolTip()} | ||
185 | disableToolTip={() => this.disableToolTip()} | ||
186 | useHorizontalStyle={stores!.settings.all.app.useHorizontalStyle} | ||
187 | /> | ||
188 | <> | ||
189 | {numberActiveButtons <= 1 || hideCollapseButton ? null : ( | ||
190 | <button | ||
191 | type="button" | ||
192 | onClick={() => toggleCollapseMenu()} | ||
193 | className="sidebar__button sidebar__button--hamburger-menu" | ||
194 | > | ||
195 | {isMenuCollapsed ? <Icon icon={mdiMenu} size={1.5} /> : null} | ||
196 | |||
197 | {!isMenuCollapsed && !useHorizontalStyle ? ( | ||
198 | <Icon icon={mdiChevronDown} size={1.5} /> | ||
199 | ) : null} | ||
200 | |||
201 | {!isMenuCollapsed && useHorizontalStyle ? ( | ||
202 | <Icon icon={mdiChevronRight} size={1.5} /> | ||
203 | ) : null} | ||
204 | </button> | ||
205 | )} | ||
206 | {!hideRecipesButton && !isMenuCollapsed ? ( | ||
207 | <button | ||
208 | type="button" | ||
209 | onClick={() => openSettings({ path: 'recipes' })} | ||
210 | className="sidebar__button sidebar__button--new-service" | ||
211 | data-tip={`${intl.formatMessage( | ||
212 | messages.addNewService, | ||
213 | )} (${addNewServiceShortcutKey(false)})`} | ||
214 | > | ||
215 | <Icon icon={mdiPlusBox} size={1.5} /> | ||
216 | </button> | ||
217 | ) : null} | ||
218 | {!hideSplitModeButton && !isMenuCollapsed ? ( | ||
219 | <button | ||
220 | type="button" | ||
221 | onClick={() => { | ||
222 | actions!.settings.update({ | ||
223 | type: 'app', | ||
224 | data: { | ||
225 | splitMode: !splitMode, | ||
226 | }, | ||
227 | }); | ||
228 | }} | ||
229 | className="sidebar__button sidebar__button--split-mode-toggle" | ||
230 | data-tip={`${intl.formatMessage( | ||
231 | messages.splitModeToggle, | ||
232 | )} (${splitModeToggleShortcutKey(false)})`} | ||
233 | > | ||
234 | <Icon icon={mdiViewSplitVertical} size={1.5} /> | ||
235 | </button> | ||
236 | ) : null} | ||
237 | {!hideWorkspacesButton && !isMenuCollapsed ? ( | ||
238 | <button | ||
239 | type="button" | ||
240 | onClick={() => { | ||
241 | toggleWorkspaceDrawer(); | ||
242 | this.updateToolTip(); | ||
243 | }} | ||
244 | className={`sidebar__button sidebar__button--workspaces ${ | ||
245 | isWorkspaceDrawerOpen ? 'is-active' : '' | ||
246 | }`} | ||
247 | data-tip={`${intl.formatMessage( | ||
248 | workspaceToggleMessage, | ||
249 | )} (${workspaceToggleShortcutKey(false)})`} | ||
250 | > | ||
251 | <Icon icon={mdiViewGrid} size={1.5} /> | ||
252 | </button> | ||
253 | ) : null} | ||
254 | {!hideNotificationsButton && !isMenuCollapsed ? ( | ||
255 | <button | ||
256 | type="button" | ||
257 | onClick={() => { | ||
258 | toggleMuteApp(); | ||
259 | this.updateToolTip(); | ||
260 | }} | ||
261 | className={`sidebar__button sidebar__button--audio ${ | ||
262 | isAppMuted ? 'is-muted' : '' | ||
263 | }`} | ||
264 | data-tip={`${intl.formatMessage( | ||
265 | isAppMuted ? messages.unmute : messages.mute, | ||
266 | )} (${muteFerdiumShortcutKey(false)})`} | ||
267 | > | ||
268 | <Icon icon={isAppMuted ? mdiBellOff : mdiBell} size={1.5} /> | ||
269 | </button> | ||
270 | ) : null} | ||
271 | {todosStore.isFeatureEnabledByUser && !isMenuCollapsed ? ( | ||
272 | <button | ||
273 | type="button" | ||
274 | onClick={() => { | ||
275 | todoActions.toggleTodosPanel(); | ||
276 | this.updateToolTip(); | ||
277 | }} | ||
278 | disabled={isTodosServiceActive} | ||
279 | className={`sidebar__button sidebar__button--todos ${ | ||
280 | todosStore.isTodosPanelVisible ? 'is-active' : '' | ||
281 | }`} | ||
282 | data-tip={`${intl.formatMessage( | ||
283 | todosToggleMessage, | ||
284 | )} (${todosToggleShortcutKey(false)})`} | ||
285 | > | ||
286 | <Icon icon={mdiCheckAll} size={1.5} /> | ||
287 | </button> | ||
288 | ) : null} | ||
289 | {stores!.settings.all.app.lockingFeatureEnabled ? ( | ||
290 | <button | ||
291 | type="button" | ||
292 | className="sidebar__button" | ||
293 | onClick={() => { | ||
294 | actions!.settings.update({ | ||
295 | type: 'app', | ||
296 | data: { | ||
297 | locked: true, | ||
298 | }, | ||
299 | }); | ||
300 | }} | ||
301 | data-tip={`${intl.formatMessage( | ||
302 | messages.lockFerdium, | ||
303 | )} (${lockFerdiumShortcutKey(false)})`} | ||
304 | > | ||
305 | <Icon icon={mdiLock} size={1.5} /> | ||
306 | </button> | ||
307 | ) : null} | ||
308 | </> | ||
309 | {this.state.tooltipEnabled && ( | ||
310 | <ReactTooltip place="right" type="dark" effect="solid" /> | ||
311 | )} | ||
312 | {!hideSettingsButton && !isMenuCollapsed ? ( | ||
313 | <button | ||
314 | type="button" | ||
315 | onClick={() => openSettings({ path: 'app' })} | ||
316 | className="sidebar__button sidebar__button--settings" | ||
317 | data-tip={`${intl.formatMessage( | ||
318 | globalMessages.settings, | ||
319 | )} (${settingsShortcutKey(false)})`} | ||
320 | > | ||
321 | <Icon icon={mdiCog} size={1.5} /> | ||
322 | {stores!.settings.app.automaticUpdates && | ||
323 | (stores!.app.updateStatus === | ||
324 | stores!.app.updateStatusTypes.AVAILABLE || | ||
325 | stores!.app.updateStatus === | ||
326 | stores!.app.updateStatusTypes.DOWNLOADED || | ||
327 | this.props.showServicesUpdatedInfoBar) && ( | ||
328 | <span className="update-available">•</span> | ||
329 | )} | ||
330 | </button> | ||
331 | ) : null} | ||
332 | </div> | ||
333 | ); | ||
334 | } | ||
335 | } | ||
336 | |||
337 | export default injectIntl(Sidebar); | ||