diff options
author | 2021-12-19 15:43:09 +0100 | |
---|---|---|
committer | 2021-12-19 15:43:09 +0100 | |
commit | 4b909b13fbb6d8d72ab38700b91cf18920d72fc4 (patch) | |
tree | 556d998e72ce71fb97bf89a65edaa0bb394964ae | |
parent | Iterate on About Ferdi screen (diff) | |
download | ferdium-app-4b909b13fbb6d8d72ab38700b91cf18920d72fc4.tar.gz ferdium-app-4b909b13fbb6d8d72ab38700b91cf18920d72fc4.tar.zst ferdium-app-4b909b13fbb6d8d72ab38700b91cf18920d72fc4.zip |
Hotfix for requireAuthenticatedUser error
-rw-r--r-- | src/components/layout/Sidebar.js | 141 | ||||
-rw-r--r-- | src/components/services/content/Services.js | 37 | ||||
-rw-r--r-- | src/components/settings/navigation/SettingsNavigation.js | 46 | ||||
-rw-r--r-- | src/components/settings/recipes/RecipesDashboard.js | 5 | ||||
-rw-r--r-- | src/containers/layout/AppLayoutContainer.js | 10 |
5 files changed, 94 insertions, 145 deletions
diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js index 57ba170e8..e3df9c2ea 100644 --- a/src/components/layout/Sidebar.js +++ b/src/components/layout/Sidebar.js | |||
@@ -3,12 +3,10 @@ import PropTypes from 'prop-types'; | |||
3 | import ReactTooltip from 'react-tooltip'; | 3 | import ReactTooltip from 'react-tooltip'; |
4 | import { defineMessages, injectIntl } from 'react-intl'; | 4 | import { defineMessages, injectIntl } from 'react-intl'; |
5 | import { inject, observer } from 'mobx-react'; | 5 | import { inject, observer } from 'mobx-react'; |
6 | import { Link } from 'react-router'; | ||
7 | import { | 6 | import { |
8 | mdiCheckAll, | 7 | mdiCheckAll, |
9 | mdiViewGrid, | 8 | mdiViewGrid, |
10 | mdiPlusBox, | 9 | mdiPlusBox, |
11 | mdiLoginVariant, | ||
12 | mdiCog, | 10 | mdiCog, |
13 | mdiBellOff, | 11 | mdiBellOff, |
14 | mdiBell, | 12 | mdiBell, |
@@ -137,7 +135,6 @@ class Sidebar extends Component { | |||
137 | const workspaceToggleMessage = isWorkspaceDrawerOpen | 135 | const workspaceToggleMessage = isWorkspaceDrawerOpen |
138 | ? messages.closeWorkspaceDrawer | 136 | ? messages.closeWorkspaceDrawer |
139 | : messages.openWorkspaceDrawer; | 137 | : messages.openWorkspaceDrawer; |
140 | const isLoggedIn = Boolean(localStorage.getItem('authToken')); | ||
141 | 138 | ||
142 | return ( | 139 | return ( |
143 | <div className="sidebar"> | 140 | <div className="sidebar"> |
@@ -147,96 +144,86 @@ class Sidebar extends Component { | |||
147 | disableToolTip={() => this.disableToolTip()} | 144 | disableToolTip={() => this.disableToolTip()} |
148 | useVerticalStyle={stores.settings.all.app.useVerticalStyle} | 145 | useVerticalStyle={stores.settings.all.app.useVerticalStyle} |
149 | /> | 146 | /> |
150 | {isLoggedIn ? ( | 147 | <> |
151 | <> | 148 | <button |
152 | <button | 149 | type="button" |
153 | type="button" | 150 | onClick={() => openSettings({ path: 'recipes' })} |
154 | onClick={() => openSettings({ path: 'recipes' })} | 151 | className="sidebar__button sidebar__button--new-service" |
155 | className="sidebar__button sidebar__button--new-service" | 152 | data-tip={`${intl.formatMessage( |
156 | data-tip={`${intl.formatMessage( | 153 | messages.addNewService, |
157 | messages.addNewService, | 154 | )} (${addNewServiceShortcutKey(false)})`} |
158 | )} (${addNewServiceShortcutKey(false)})`} | 155 | > |
159 | > | 156 | <Icon icon={mdiPlusBox} size={1.5} /> |
160 | <Icon icon={mdiPlusBox} size={1.5} /> | 157 | </button> |
161 | </button> | 158 | <button |
159 | type="button" | ||
160 | onClick={() => { | ||
161 | toggleWorkspaceDrawer(); | ||
162 | this.updateToolTip(); | ||
163 | }} | ||
164 | className={`sidebar__button sidebar__button--workspaces ${ | ||
165 | isWorkspaceDrawerOpen ? 'is-active' : '' | ||
166 | }`} | ||
167 | data-tip={`${intl.formatMessage( | ||
168 | workspaceToggleMessage, | ||
169 | )} (${workspaceToggleShortcutKey(false)})`} | ||
170 | > | ||
171 | <Icon icon={mdiViewGrid} size={1.5} /> | ||
172 | </button> | ||
173 | {todosStore.isFeatureEnabledByUser ? ( | ||
162 | <button | 174 | <button |
163 | type="button" | 175 | type="button" |
164 | onClick={() => { | 176 | onClick={() => { |
165 | toggleWorkspaceDrawer(); | 177 | todoActions.toggleTodosPanel(); |
166 | this.updateToolTip(); | 178 | this.updateToolTip(); |
167 | }} | 179 | }} |
168 | className={`sidebar__button sidebar__button--workspaces ${ | 180 | disabled={isTodosServiceActive} |
169 | isWorkspaceDrawerOpen ? 'is-active' : '' | 181 | className={`sidebar__button sidebar__button--todos ${ |
182 | todosStore.isTodosPanelVisible ? 'is-active' : '' | ||
170 | }`} | 183 | }`} |
171 | data-tip={`${intl.formatMessage( | 184 | data-tip={`${intl.formatMessage( |
172 | workspaceToggleMessage, | 185 | todosToggleMessage, |
173 | )} (${workspaceToggleShortcutKey(false)})`} | 186 | )} (${todosToggleShortcutKey(false)})`} |
174 | > | 187 | > |
175 | <Icon icon={mdiViewGrid} size={1.5} /> | 188 | <Icon icon={mdiCheckAll} size={1.5} /> |
176 | </button> | 189 | </button> |
177 | {todosStore.isFeatureEnabledByUser ? ( | 190 | ) : null} |
178 | <button | 191 | <button |
179 | type="button" | 192 | type="button" |
180 | onClick={() => { | 193 | onClick={() => { |
181 | todoActions.toggleTodosPanel(); | 194 | toggleMuteApp(); |
182 | this.updateToolTip(); | 195 | this.updateToolTip(); |
183 | }} | 196 | }} |
184 | disabled={isTodosServiceActive} | 197 | className={`sidebar__button sidebar__button--audio ${ |
185 | className={`sidebar__button sidebar__button--todos ${ | 198 | isAppMuted ? 'is-muted' : '' |
186 | todosStore.isTodosPanelVisible ? 'is-active' : '' | 199 | }`} |
187 | }`} | 200 | data-tip={`${intl.formatMessage( |
188 | data-tip={`${intl.formatMessage( | 201 | isAppMuted ? messages.unmute : messages.mute, |
189 | todosToggleMessage, | 202 | )} (${muteFerdiShortcutKey(false)})`} |
190 | )} (${todosToggleShortcutKey(false)})`} | 203 | > |
191 | > | 204 | <Icon icon={isAppMuted ? mdiBellOff : mdiBell} size={1.5} /> |
192 | <Icon icon={mdiCheckAll} size={1.5} /> | 205 | </button> |
193 | </button> | 206 | |
194 | ) : null} | 207 | {stores.settings.all.app.lockingFeatureEnabled ? ( |
195 | <button | 208 | <button |
196 | type="button" | 209 | type="button" |
210 | className="sidebar__button" | ||
197 | onClick={() => { | 211 | onClick={() => { |
198 | toggleMuteApp(); | 212 | actions.settings.update({ |
199 | this.updateToolTip(); | 213 | type: 'app', |
214 | data: { | ||
215 | locked: true, | ||
216 | }, | ||
217 | }); | ||
200 | }} | 218 | }} |
201 | className={`sidebar__button sidebar__button--audio ${ | ||
202 | isAppMuted ? 'is-muted' : '' | ||
203 | }`} | ||
204 | data-tip={`${intl.formatMessage( | 219 | data-tip={`${intl.formatMessage( |
205 | isAppMuted ? messages.unmute : messages.mute, | 220 | messages.lockFerdi, |
206 | )} (${muteFerdiShortcutKey(false)})`} | 221 | )} (${lockFerdiShortcutKey(false)})`} |
207 | > | 222 | > |
208 | <Icon icon={isAppMuted ? mdiBellOff : mdiBell} size={1.5} /> | 223 | <Icon icon={mdiLock} size={1.5} /> |
209 | </button> | 224 | </button> |
210 | 225 | ) : null} | |
211 | {stores.settings.all.app.lockingFeatureEnabled ? ( | 226 | </> |
212 | <button | ||
213 | type="button" | ||
214 | className="sidebar__button" | ||
215 | onClick={() => { | ||
216 | actions.settings.update({ | ||
217 | type: 'app', | ||
218 | data: { | ||
219 | locked: true, | ||
220 | }, | ||
221 | }); | ||
222 | }} | ||
223 | data-tip={`${intl.formatMessage( | ||
224 | messages.lockFerdi, | ||
225 | )} (${lockFerdiShortcutKey(false)})`} | ||
226 | > | ||
227 | <Icon icon={mdiLock} size={1.5} /> | ||
228 | </button> | ||
229 | ) : null} | ||
230 | </> | ||
231 | ) : ( | ||
232 | <Link | ||
233 | to="/auth/welcome" | ||
234 | className="sidebar__button sidebar__button--new-service" | ||
235 | data-tip="Login" | ||
236 | > | ||
237 | <Icon icon={mdiLoginVariant} size={1.5} /> | ||
238 | </Link> | ||
239 | )} | ||
240 | <button | 227 | <button |
241 | type="button" | 228 | type="button" |
242 | onClick={() => openSettings({ path: 'app' })} | 229 | onClick={() => openSettings({ path: 'app' })} |
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js index cbc70563d..9b43ea177 100644 --- a/src/components/services/content/Services.js +++ b/src/components/services/content/Services.js | |||
@@ -9,7 +9,6 @@ import injectSheet from 'react-jss'; | |||
9 | 9 | ||
10 | import ServiceView from './ServiceView'; | 10 | import ServiceView from './ServiceView'; |
11 | import Appear from '../../ui/effects/Appear'; | 11 | import Appear from '../../ui/effects/Appear'; |
12 | import serverlessLogin from '../../../helpers/serverless-helpers'; | ||
13 | 12 | ||
14 | const messages = defineMessages({ | 13 | const messages = defineMessages({ |
15 | getStarted: { | 14 | getStarted: { |
@@ -52,7 +51,6 @@ class Services extends Component { | |||
52 | update: PropTypes.func.isRequired, | 51 | update: PropTypes.func.isRequired, |
53 | userHasCompletedSignup: PropTypes.bool.isRequired, | 52 | userHasCompletedSignup: PropTypes.bool.isRequired, |
54 | classes: PropTypes.object.isRequired, | 53 | classes: PropTypes.object.isRequired, |
55 | actions: PropTypes.object.isRequired, | ||
56 | isSpellcheckerEnabled: PropTypes.bool.isRequired, | 54 | isSpellcheckerEnabled: PropTypes.bool.isRequired, |
57 | }; | 55 | }; |
58 | 56 | ||
@@ -66,12 +64,6 @@ class Services extends Component { | |||
66 | 64 | ||
67 | _confettiTimeout = null; | 65 | _confettiTimeout = null; |
68 | 66 | ||
69 | constructor(props) { | ||
70 | super(props); | ||
71 | |||
72 | this.useLocalServer = this.useLocalServer.bind(this); | ||
73 | } | ||
74 | |||
75 | componentDidMount() { | 67 | componentDidMount() { |
76 | this._confettiTimeout = window.setTimeout(() => { | 68 | this._confettiTimeout = window.setTimeout(() => { |
77 | this.setState({ | 69 | this.setState({ |
@@ -86,10 +78,6 @@ class Services extends Component { | |||
86 | } | 78 | } |
87 | } | 79 | } |
88 | 80 | ||
89 | useLocalServer() { | ||
90 | serverlessLogin(this.props.actions); | ||
91 | } | ||
92 | |||
93 | render() { | 81 | render() { |
94 | const { | 82 | const { |
95 | services, | 83 | services, |
@@ -108,7 +96,6 @@ class Services extends Component { | |||
108 | const { showConfetti } = this.state; | 96 | const { showConfetti } = this.state; |
109 | 97 | ||
110 | const { intl } = this.props; | 98 | const { intl } = this.props; |
111 | const isLoggedIn = Boolean(localStorage.getItem('authToken')); | ||
112 | 99 | ||
113 | return ( | 100 | return ( |
114 | <div className="services"> | 101 | <div className="services"> |
@@ -129,33 +116,13 @@ class Services extends Component { | |||
129 | alt="Logo" | 116 | alt="Logo" |
130 | style={{ maxHeight: '50vh' }} | 117 | style={{ maxHeight: '50vh' }} |
131 | /> | 118 | /> |
132 | {!isLoggedIn && ( | ||
133 | <> | ||
134 | <p>{intl.formatMessage(messages.login)}</p> | ||
135 | <p>{intl.formatMessage(messages.serverInfo)}</p> | ||
136 | </> | ||
137 | )} | ||
138 | <Appear timeout={300} transitionName="slideUp"> | 119 | <Appear timeout={300} transitionName="slideUp"> |
139 | <Link | 120 | <Link |
140 | to={isLoggedIn ? '/settings/recipes' : '/auth/welcome'} | 121 | to='/settings/recipes' |
141 | className="button" | 122 | className="button" |
142 | > | 123 | > |
143 | {isLoggedIn | 124 | {intl.formatMessage(messages.getStarted)} |
144 | ? intl.formatMessage(messages.getStarted) | ||
145 | : 'Login'} | ||
146 | </Link> | 125 | </Link> |
147 | {!isLoggedIn && ( | ||
148 | <button | ||
149 | type="button" | ||
150 | className="button" | ||
151 | style={{ | ||
152 | marginLeft: 10, | ||
153 | }} | ||
154 | onClick={this.useLocalServer} | ||
155 | > | ||
156 | {intl.formatMessage(messages.serverless)} | ||
157 | </button> | ||
158 | )} | ||
159 | </Appear> | 126 | </Appear> |
160 | </div> | 127 | </div> |
161 | </Appear> | 128 | </Appear> |
diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.js index 953760fec..e8370d2ef 100644 --- a/src/components/settings/navigation/SettingsNavigation.js +++ b/src/components/settings/navigation/SettingsNavigation.js | |||
@@ -57,40 +57,34 @@ class SettingsNavigation extends Component { | |||
57 | workspaceCount: PropTypes.number.isRequired, | 57 | workspaceCount: PropTypes.number.isRequired, |
58 | }; | 58 | }; |
59 | 59 | ||
60 | handleLoginLogout() { | 60 | handleLogout() { |
61 | const isLoggedIn = Boolean(localStorage.getItem('authToken')); | ||
62 | const isUsingWithoutAccount = | 61 | const isUsingWithoutAccount = |
63 | this.props.stores.settings.app.server === LOCAL_SERVER; | 62 | this.props.stores.settings.app.server === LOCAL_SERVER; |
64 | 63 | ||
65 | if (isLoggedIn) { | 64 | // Remove current auth token |
66 | // Remove current auth token | 65 | localStorage.removeItem('authToken'); |
67 | localStorage.removeItem('authToken'); | ||
68 | 66 | ||
69 | if (isUsingWithoutAccount) { | 67 | if (isUsingWithoutAccount) { |
70 | // Reset server back to Ferdi API | 68 | // Reset server back to Ferdi API |
71 | this.props.actions.settings.update({ | 69 | this.props.actions.settings.update({ |
72 | type: 'app', | 70 | type: 'app', |
73 | data: { | 71 | data: { |
74 | server: LIVE_FERDI_API, | 72 | server: LIVE_FERDI_API, |
75 | }, | 73 | }, |
76 | }); | 74 | }); |
77 | } | ||
78 | this.props.stores.user.isLoggingOut = true; | ||
79 | } | 75 | } |
76 | this.props.stores.user.isLoggingOut = true; | ||
80 | 77 | ||
81 | this.props.stores.router.push('/auth/welcome'); | 78 | this.props.stores.router.push('/auth/welcome'); |
82 | 79 | ||
83 | if (isLoggedIn) { | 80 | // Reload Ferdi, otherwise many settings won't sync correctly with the server |
84 | // Reload Ferdi, otherwise many settings won't sync correctly with the server | 81 | // after logging into another account |
85 | // after logging into another account | 82 | window.location.reload(); |
86 | window.location.reload(); | ||
87 | } | ||
88 | } | 83 | } |
89 | 84 | ||
90 | render() { | 85 | render() { |
91 | const { serviceCount, workspaceCount, stores } = this.props; | 86 | const { serviceCount, workspaceCount, stores } = this.props; |
92 | const { intl } = this.props; | 87 | const { intl } = this.props; |
93 | const isLoggedIn = Boolean(localStorage.getItem('authToken')); | ||
94 | const isUsingWithoutAccount = stores.settings.app.server === LOCAL_SERVER; | 88 | const isUsingWithoutAccount = stores.settings.app.server === LOCAL_SERVER; |
95 | const isUsingFranzServer = stores.settings.app.server === LIVE_FRANZ_API; | 89 | const isUsingFranzServer = stores.settings.app.server === LIVE_FRANZ_API; |
96 | 90 | ||
@@ -107,7 +101,6 @@ class SettingsNavigation extends Component { | |||
107 | to="/settings/services" | 101 | to="/settings/services" |
108 | className="settings-navigation__link" | 102 | className="settings-navigation__link" |
109 | activeClassName="is-active" | 103 | activeClassName="is-active" |
110 | disabled={!isLoggedIn} | ||
111 | > | 104 | > |
112 | {intl.formatMessage(messages.yourServices)}{' '} | 105 | {intl.formatMessage(messages.yourServices)}{' '} |
113 | <span className="badge">{serviceCount}</span> | 106 | <span className="badge">{serviceCount}</span> |
@@ -116,7 +109,6 @@ class SettingsNavigation extends Component { | |||
116 | to="/settings/workspaces" | 109 | to="/settings/workspaces" |
117 | className="settings-navigation__link" | 110 | className="settings-navigation__link" |
118 | activeClassName="is-active" | 111 | activeClassName="is-active" |
119 | disabled={!isLoggedIn} | ||
120 | > | 112 | > |
121 | {intl.formatMessage(messages.yourWorkspaces)}{' '} | 113 | {intl.formatMessage(messages.yourWorkspaces)}{' '} |
122 | <span className="badge">{workspaceCount}</span> | 114 | <span className="badge">{workspaceCount}</span> |
@@ -126,7 +118,6 @@ class SettingsNavigation extends Component { | |||
126 | to="/settings/user" | 118 | to="/settings/user" |
127 | className="settings-navigation__link" | 119 | className="settings-navigation__link" |
128 | activeClassName="is-active" | 120 | activeClassName="is-active" |
129 | disabled={!isLoggedIn} | ||
130 | > | 121 | > |
131 | {intl.formatMessage(messages.account)} | 122 | {intl.formatMessage(messages.account)} |
132 | </Link> | 123 | </Link> |
@@ -136,7 +127,6 @@ class SettingsNavigation extends Component { | |||
136 | to="/settings/team" | 127 | to="/settings/team" |
137 | className="settings-navigation__link" | 128 | className="settings-navigation__link" |
138 | activeClassName="is-active" | 129 | activeClassName="is-active" |
139 | disabled={!isLoggedIn} | ||
140 | > | 130 | > |
141 | {intl.formatMessage(messages.team)} | 131 | {intl.formatMessage(messages.team)} |
142 | </Link> | 132 | </Link> |
@@ -158,11 +148,11 @@ class SettingsNavigation extends Component { | |||
158 | <span className="settings-navigation__expander" /> | 148 | <span className="settings-navigation__expander" /> |
159 | <button | 149 | <button |
160 | type="button" | 150 | type="button" |
161 | to={isLoggedIn ? '/auth/logout' : '/auth/welcome'} | 151 | to='/auth/logout' |
162 | className="settings-navigation__link" | 152 | className="settings-navigation__link" |
163 | onClick={this.handleLoginLogout.bind(this)} | 153 | onClick={this.handleLogout.bind(this)} |
164 | > | 154 | > |
165 | {isLoggedIn && !isUsingWithoutAccount | 155 | {!isUsingWithoutAccount |
166 | ? intl.formatMessage(messages.logout) | 156 | ? intl.formatMessage(messages.logout) |
167 | : 'Exit session'} | 157 | : 'Exit session'} |
168 | </button> | 158 | </button> |
diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js index 0ba295369..4f19a6116 100644 --- a/src/components/settings/recipes/RecipesDashboard.js +++ b/src/components/settings/recipes/RecipesDashboard.js | |||
@@ -148,8 +148,6 @@ class RecipesDashboard extends Component { | |||
148 | const communityRecipes = recipes.filter(r => !r.isDevRecipe); | 148 | const communityRecipes = recipes.filter(r => !r.isDevRecipe); |
149 | const devRecipes = recipes.filter(r => r.isDevRecipe); | 149 | const devRecipes = recipes.filter(r => r.isDevRecipe); |
150 | 150 | ||
151 | const isLoggedIn = Boolean(localStorage.getItem('authToken')); | ||
152 | |||
153 | return ( | 151 | return ( |
154 | <div className="settings__main"> | 152 | <div className="settings__main"> |
155 | <div className="settings__header"> | 153 | <div className="settings__header"> |
@@ -240,7 +238,6 @@ class RecipesDashboard extends Component { | |||
240 | key={recipe.id} | 238 | key={recipe.id} |
241 | recipe={recipe} | 239 | recipe={recipe} |
242 | onClick={() => | 240 | onClick={() => |
243 | isLoggedIn && | ||
244 | showAddServiceInterface({ recipeId: recipe.id }) | 241 | showAddServiceInterface({ recipeId: recipe.id }) |
245 | } | 242 | } |
246 | /> | 243 | /> |
@@ -253,7 +250,6 @@ class RecipesDashboard extends Component { | |||
253 | key={customWebsiteRecipe.id} | 250 | key={customWebsiteRecipe.id} |
254 | recipe={customWebsiteRecipe} | 251 | recipe={customWebsiteRecipe} |
255 | onClick={() => | 252 | onClick={() => |
256 | isLoggedIn && | ||
257 | showAddServiceInterface({ | 253 | showAddServiceInterface({ |
258 | recipeId: customWebsiteRecipe.id, | 254 | recipeId: customWebsiteRecipe.id, |
259 | }) | 255 | }) |
@@ -274,7 +270,6 @@ class RecipesDashboard extends Component { | |||
274 | key={recipe.id} | 270 | key={recipe.id} |
275 | recipe={recipe} | 271 | recipe={recipe} |
276 | onClick={() => | 272 | onClick={() => |
277 | isLoggedIn && | ||
278 | showAddServiceInterface({ recipeId: recipe.id }) | 273 | showAddServiceInterface({ recipeId: recipe.id }) |
279 | } | 274 | } |
280 | /> | 275 | /> |
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index 536083c4f..c70144c8e 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js | |||
@@ -40,8 +40,18 @@ class AppLayoutContainer extends Component { | |||
40 | requests, | 40 | requests, |
41 | user, | 41 | user, |
42 | workspaces, | 42 | workspaces, |
43 | router | ||
43 | } = this.props.stores; | 44 | } = this.props.stores; |
44 | 45 | ||
46 | /* HOTFIX for: | ||
47 | [mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: 'Reaction[bound ]' TypeError: Cannot read properties of null (reading 'push') | ||
48 | at RouterStore.push (store.js:25) | ||
49 | at UserStore._requireAuthenticatedUser | ||
50 | */ | ||
51 | if (!user.isLoggedIn) { | ||
52 | router.push('/auth/welcome'); | ||
53 | } | ||
54 | |||
45 | const { | 55 | const { |
46 | setActive, | 56 | setActive, |
47 | handleIPCMessage, | 57 | handleIPCMessage, |