diff options
-rw-r--r-- | src/actions/service.js | 3 | ||||
-rw-r--r-- | src/api/LocalApi.js | 4 | ||||
-rw-r--r-- | src/api/ServicesApi.js | 7 | ||||
-rw-r--r-- | src/api/server/LocalApi.js | 11 | ||||
-rw-r--r-- | src/components/settings/services/EditServiceForm.js | 30 | ||||
-rw-r--r-- | src/containers/settings/EditServiceScreen.js | 11 | ||||
-rw-r--r-- | src/i18n/locales/en-US.json | 2 | ||||
-rw-r--r-- | src/stores/ServicesStore.js | 9 | ||||
-rw-r--r-- | src/styles/button.scss | 12 |
9 files changed, 88 insertions, 1 deletions
diff --git a/src/actions/service.js b/src/actions/service.js index e3100e986..5d483b12a 100644 --- a/src/actions/service.js +++ b/src/actions/service.js | |||
@@ -25,6 +25,9 @@ export default { | |||
25 | serviceId: PropTypes.string.isRequired, | 25 | serviceId: PropTypes.string.isRequired, |
26 | redirect: PropTypes.string, | 26 | redirect: PropTypes.string, |
27 | }, | 27 | }, |
28 | clearCache: { | ||
29 | serviceId: PropTypes.string.isRequired, | ||
30 | }, | ||
28 | setUnreadMessageCount: { | 31 | setUnreadMessageCount: { |
29 | serviceId: PropTypes.string.isRequired, | 32 | serviceId: PropTypes.string.isRequired, |
30 | count: PropTypes.object.isRequired, | 33 | count: PropTypes.object.isRequired, |
diff --git a/src/api/LocalApi.js b/src/api/LocalApi.js index 6f2b049d6..d52e9cd10 100644 --- a/src/api/LocalApi.js +++ b/src/api/LocalApi.js | |||
@@ -15,4 +15,8 @@ export default class LocalApi { | |||
15 | removeKey(key) { | 15 | removeKey(key) { |
16 | return this.local.removeKey(key); | 16 | return this.local.removeKey(key); |
17 | } | 17 | } |
18 | |||
19 | clearAppCache() { | ||
20 | return this.local.clearAppCache(); | ||
21 | } | ||
18 | } | 22 | } |
diff --git a/src/api/ServicesApi.js b/src/api/ServicesApi.js index 3cb40ba0d..36ed9482f 100644 --- a/src/api/ServicesApi.js +++ b/src/api/ServicesApi.js | |||
@@ -1,5 +1,6 @@ | |||
1 | export default class ServicesApi { | 1 | export default class ServicesApi { |
2 | constructor(server) { | 2 | constructor(server, local) { |
3 | this.local = local; | ||
3 | this.server = server; | 4 | this.server = server; |
4 | } | 5 | } |
5 | 6 | ||
@@ -30,4 +31,8 @@ export default class ServicesApi { | |||
30 | reorder(data) { | 31 | reorder(data) { |
31 | return this.server.reorderService(data); | 32 | return this.server.reorderService(data); |
32 | } | 33 | } |
34 | |||
35 | clearCache(serviceId) { | ||
36 | return this.local.clearCache(serviceId); | ||
37 | } | ||
33 | } | 38 | } |
diff --git a/src/api/server/LocalApi.js b/src/api/server/LocalApi.js index 79ac6e12f..fec89f948 100644 --- a/src/api/server/LocalApi.js +++ b/src/api/server/LocalApi.js | |||
@@ -1,3 +1,7 @@ | |||
1 | import { remote } from 'electron'; | ||
2 | |||
3 | const { session } = remote; | ||
4 | |||
1 | export default class LocalApi { | 5 | export default class LocalApi { |
2 | // App | 6 | // App |
3 | async updateAppSettings(data) { | 7 | async updateAppSettings(data) { |
@@ -30,4 +34,11 @@ export default class LocalApi { | |||
30 | localStorage.setItem('app', JSON.stringify(settings)); | 34 | localStorage.setItem('app', JSON.stringify(settings)); |
31 | } | 35 | } |
32 | } | 36 | } |
37 | |||
38 | // Services | ||
39 | async clearCache(serviceId) { | ||
40 | console.debug(`Clearing cache for persist:service-${serviceId}`); | ||
41 | const s = session.fromPartition(`persist:service-${serviceId}`); | ||
42 | await new Promise(resolve => s.clearCache(resolve)); | ||
43 | } | ||
33 | } | 44 | } |
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index 4458c4c5a..b5300f605 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js | |||
@@ -71,6 +71,14 @@ const messages = defineMessages({ | |||
71 | id: 'settings.service.form.isMutedInfo', | 71 | id: 'settings.service.form.isMutedInfo', |
72 | defaultMessage: '!!!When disabled, all notification sounds and audio playback are muted', | 72 | defaultMessage: '!!!When disabled, all notification sounds and audio playback are muted', |
73 | }, | 73 | }, |
74 | buttonClearCache: { | ||
75 | id: 'settings.service.form.buttonClearCache', | ||
76 | defaultMessage: '!!!Clear cache', | ||
77 | }, | ||
78 | buttonClearingCache: { | ||
79 | id: 'settings.service.form.buttonClearingCache', | ||
80 | defaultMessage: '!!!Clearing cache', | ||
81 | }, | ||
74 | headlineNotifications: { | 82 | headlineNotifications: { |
75 | id: 'settings.service.form.headlineNotifications', | 83 | id: 'settings.service.form.headlineNotifications', |
76 | defaultMessage: '!!!Notifications', | 84 | defaultMessage: '!!!Notifications', |
@@ -102,8 +110,10 @@ export default class EditServiceForm extends Component { | |||
102 | form: PropTypes.instanceOf(Form).isRequired, | 110 | form: PropTypes.instanceOf(Form).isRequired, |
103 | onSubmit: PropTypes.func.isRequired, | 111 | onSubmit: PropTypes.func.isRequired, |
104 | onDelete: PropTypes.func.isRequired, | 112 | onDelete: PropTypes.func.isRequired, |
113 | onClearCache: PropTypes.func.isRequired, | ||
105 | isSaving: PropTypes.bool.isRequired, | 114 | isSaving: PropTypes.bool.isRequired, |
106 | isDeleting: PropTypes.bool.isRequired, | 115 | isDeleting: PropTypes.bool.isRequired, |
116 | isClearingCache: PropTypes.bool.isRequired, | ||
107 | }; | 117 | }; |
108 | 118 | ||
109 | static defaultProps = { | 119 | static defaultProps = { |
@@ -158,7 +168,9 @@ export default class EditServiceForm extends Component { | |||
158 | form, | 168 | form, |
159 | isSaving, | 169 | isSaving, |
160 | isDeleting, | 170 | isDeleting, |
171 | isClearingCache, | ||
161 | onDelete, | 172 | onDelete, |
173 | onClearCache, | ||
162 | } = this.props; | 174 | } = this.props; |
163 | const { intl } = this.context; | 175 | const { intl } = this.context; |
164 | 176 | ||
@@ -181,6 +193,23 @@ export default class EditServiceForm extends Component { | |||
181 | /> | 193 | /> |
182 | ); | 194 | ); |
183 | 195 | ||
196 | const clearCacheButton = isClearingCache ? ( | ||
197 | <Button | ||
198 | buttonType="secondary" | ||
199 | className="settings__clear-cache-button" | ||
200 | loaded={false} | ||
201 | label={intl.formatMessage(messages.buttonClearingCache)} | ||
202 | disabled | ||
203 | /> | ||
204 | ) : ( | ||
205 | <Button | ||
206 | buttonType="warning" | ||
207 | className="settings__clear-cache-button" | ||
208 | label={intl.formatMessage(messages.buttonClearCache)} | ||
209 | onClick={onClearCache} | ||
210 | /> | ||
211 | ); | ||
212 | |||
184 | let activeTabIndex = 0; | 213 | let activeTabIndex = 0; |
185 | if (recipe.hasHostedOption && service.team) { | 214 | if (recipe.hasHostedOption && service.team) { |
186 | activeTabIndex = 1; | 215 | activeTabIndex = 1; |
@@ -287,6 +316,7 @@ export default class EditServiceForm extends Component { | |||
287 | <div className="settings__settings-group"> | 316 | <div className="settings__settings-group"> |
288 | <h3>{intl.formatMessage(messages.headlineGeneral)}</h3> | 317 | <h3>{intl.formatMessage(messages.headlineGeneral)}</h3> |
289 | <Toggle field={form.$('isEnabled')} /> | 318 | <Toggle field={form.$('isEnabled')} /> |
319 | {clearCacheButton} | ||
290 | </div> | 320 | </div> |
291 | </div> | 321 | </div> |
292 | {recipe.message && ( | 322 | {recipe.message && ( |
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js index 3c52152b1..78f043e80 100644 --- a/src/containers/settings/EditServiceScreen.js +++ b/src/containers/settings/EditServiceScreen.js | |||
@@ -169,6 +169,14 @@ export default class EditServiceScreen extends Component { | |||
169 | } | 169 | } |
170 | } | 170 | } |
171 | 171 | ||
172 | clearCache() { | ||
173 | const { clearCache } = this.props.actions.service; | ||
174 | const { activeSettings: service } = this.props.stores.services; | ||
175 | clearCache({ | ||
176 | serviceId: service.id, | ||
177 | }); | ||
178 | } | ||
179 | |||
172 | render() { | 180 | render() { |
173 | const { recipes, services, user } = this.props.stores; | 181 | const { recipes, services, user } = this.props.stores; |
174 | const { action } = this.props.router.params; | 182 | const { action } = this.props.router.params; |
@@ -211,8 +219,10 @@ export default class EditServiceScreen extends Component { | |||
211 | status={services.actionStatus} | 219 | status={services.actionStatus} |
212 | isSaving={services.updateServiceRequest.isExecuting || services.createServiceRequest.isExecuting} | 220 | isSaving={services.updateServiceRequest.isExecuting || services.createServiceRequest.isExecuting} |
213 | isDeleting={services.deleteServiceRequest.isExecuting} | 221 | isDeleting={services.deleteServiceRequest.isExecuting} |
222 | isClearingCache={services.clearCacheRequest.isExecuting} | ||
214 | onSubmit={d => this.onSubmit(d)} | 223 | onSubmit={d => this.onSubmit(d)} |
215 | onDelete={() => this.deleteService()} | 224 | onDelete={() => this.deleteService()} |
225 | onClearCache={() => this.clearCache()} | ||
216 | /> | 226 | /> |
217 | ); | 227 | ); |
218 | } | 228 | } |
@@ -234,6 +244,7 @@ EditServiceScreen.wrappedComponent.propTypes = { | |||
234 | createService: PropTypes.func.isRequired, | 244 | createService: PropTypes.func.isRequired, |
235 | updateService: PropTypes.func.isRequired, | 245 | updateService: PropTypes.func.isRequired, |
236 | deleteService: PropTypes.func.isRequired, | 246 | deleteService: PropTypes.func.isRequired, |
247 | clearCache: PropTypes.func.isRequired, | ||
237 | }).isRequired, | 248 | }).isRequired, |
238 | }).isRequired, | 249 | }).isRequired, |
239 | }; | 250 | }; |
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 567537d75..2b5a3fc4b 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -124,6 +124,8 @@ | |||
124 | "settings.service.form.indirectMessages": "Show message badge for all new messages", | 124 | "settings.service.form.indirectMessages": "Show message badge for all new messages", |
125 | "settings.service.form.enableAudio": "Enable audio", | 125 | "settings.service.form.enableAudio": "Enable audio", |
126 | "settings.service.form.isMutedInfo": "When disabled, all notification sounds and audio playback are muted", | 126 | "settings.service.form.isMutedInfo": "When disabled, all notification sounds and audio playback are muted", |
127 | "settings.service.form.buttonClearCache": "Clear cache", | ||
128 | "settings.service.form.buttonClearingCache": "Clearing cache...", | ||
127 | "settings.service.form.headlineNotifications": "Notifications", | 129 | "settings.service.form.headlineNotifications": "Notifications", |
128 | "settings.service.form.headlineBadges": "Unread message badges", | 130 | "settings.service.form.headlineBadges": "Unread message badges", |
129 | "settings.service.form.headlineGeneral": "General", | 131 | "settings.service.form.headlineGeneral": "General", |
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index 66f37af26..237264bcc 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js | |||
@@ -16,6 +16,7 @@ export default class ServicesStore extends Store { | |||
16 | @observable updateServiceRequest = new Request(this.api.services, 'update'); | 16 | @observable updateServiceRequest = new Request(this.api.services, 'update'); |
17 | @observable reorderServicesRequest = new Request(this.api.services, 'reorder'); | 17 | @observable reorderServicesRequest = new Request(this.api.services, 'reorder'); |
18 | @observable deleteServiceRequest = new Request(this.api.services, 'delete'); | 18 | @observable deleteServiceRequest = new Request(this.api.services, 'delete'); |
19 | @observable clearCacheRequest = new Request(this.api.services, 'clearCache'); | ||
19 | 20 | ||
20 | @observable filterNeedle = null; | 21 | @observable filterNeedle = null; |
21 | 22 | ||
@@ -31,6 +32,7 @@ export default class ServicesStore extends Store { | |||
31 | this.actions.service.createFromLegacyService.listen(this._createFromLegacyService.bind(this)); | 32 | this.actions.service.createFromLegacyService.listen(this._createFromLegacyService.bind(this)); |
32 | this.actions.service.updateService.listen(this._updateService.bind(this)); | 33 | this.actions.service.updateService.listen(this._updateService.bind(this)); |
33 | this.actions.service.deleteService.listen(this._deleteService.bind(this)); | 34 | this.actions.service.deleteService.listen(this._deleteService.bind(this)); |
35 | this.actions.service.clearCache.listen(this._clearCache.bind(this)); | ||
34 | this.actions.service.setWebviewReference.listen(this._setWebviewReference.bind(this)); | 36 | this.actions.service.setWebviewReference.listen(this._setWebviewReference.bind(this)); |
35 | this.actions.service.focusService.listen(this._focusService.bind(this)); | 37 | this.actions.service.focusService.listen(this._focusService.bind(this)); |
36 | this.actions.service.focusActiveService.listen(this._focusActiveService.bind(this)); | 38 | this.actions.service.focusActiveService.listen(this._focusActiveService.bind(this)); |
@@ -205,6 +207,13 @@ export default class ServicesStore extends Store { | |||
205 | gaEvent('Service', 'delete', service.recipe.id); | 207 | gaEvent('Service', 'delete', service.recipe.id); |
206 | } | 208 | } |
207 | 209 | ||
210 | @action async _clearCache({ serviceId }) { | ||
211 | this.clearCacheRequest.reset(); | ||
212 | const request = this.clearCacheRequest.execute(serviceId); | ||
213 | await request._promise; | ||
214 | gaEvent('Service', 'clear cache'); | ||
215 | } | ||
216 | |||
208 | @action _setActive({ serviceId }) { | 217 | @action _setActive({ serviceId }) { |
209 | const service = this.one(serviceId); | 218 | const service = this.one(serviceId); |
210 | 219 | ||
diff --git a/src/styles/button.scss b/src/styles/button.scss index 75d2cb1d4..8d2adbbcc 100644 --- a/src/styles/button.scss +++ b/src/styles/button.scss | |||
@@ -48,6 +48,18 @@ | |||
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | &.franz-form__button--warning { | ||
52 | background: $theme-brand-warning; | ||
53 | |||
54 | &:hover { | ||
55 | background: darken($theme-brand-warning, 5%); | ||
56 | } | ||
57 | |||
58 | &:active { | ||
59 | background: lighten($theme-brand-warning, 5%); | ||
60 | } | ||
61 | } | ||
62 | |||
51 | &.franz-form__button--inverted { | 63 | &.franz-form__button--inverted { |
52 | background: none; | 64 | background: none; |
53 | padding: 10px 20px; | 65 | padding: 10px 20px; |