diff options
Diffstat (limited to 'src/stores')
-rw-r--r-- | src/stores/AppStore.ts | 104 | ||||
-rw-r--r-- | src/stores/UIStore.ts | 7 |
2 files changed, 111 insertions, 0 deletions
diff --git a/src/stores/AppStore.ts b/src/stores/AppStore.ts index b317d99fc..1c1336819 100644 --- a/src/stores/AppStore.ts +++ b/src/stores/AppStore.ts | |||
@@ -61,6 +61,22 @@ const CATALINA_NOTIFICATION_HACK_KEY = | |||
61 | 61 | ||
62 | const locales = generatedTranslations(); | 62 | const locales = generatedTranslations(); |
63 | 63 | ||
64 | interface Download { | ||
65 | id: string; | ||
66 | serviceId: string; | ||
67 | filename: string; | ||
68 | url: string; | ||
69 | savePath?: string; | ||
70 | state?: 'progressing' | 'interrupted' | 'completed' | 'cancelled'; | ||
71 | paused?: boolean; | ||
72 | canResume?: boolean; | ||
73 | progress?: number; | ||
74 | totalBytes?: number; | ||
75 | receivedBytes?: number; | ||
76 | startTime?: number; | ||
77 | endTime?: number; | ||
78 | } | ||
79 | |||
64 | export default class AppStore extends TypedStore { | 80 | export default class AppStore extends TypedStore { |
65 | updateStatusTypes = { | 81 | updateStatusTypes = { |
66 | CHECKING: 'CHECKING', | 82 | CHECKING: 'CHECKING', |
@@ -114,6 +130,10 @@ export default class AppStore extends TypedStore { | |||
114 | 130 | ||
115 | fetchDataInterval: null | NodeJS.Timer = null; | 131 | fetchDataInterval: null | NodeJS.Timer = null; |
116 | 132 | ||
133 | @observable downloads: Download[] = []; | ||
134 | |||
135 | @observable justFinishedDownloading: boolean = false; | ||
136 | |||
117 | constructor(stores: Stores, api: ApiInterface, actions: Actions) { | 137 | constructor(stores: Stores, api: ApiInterface, actions: Actions) { |
118 | super(stores, api, actions); | 138 | super(stores, api, actions); |
119 | 139 | ||
@@ -136,6 +156,14 @@ export default class AppStore extends TypedStore { | |||
136 | this._toggleCollapseMenu.bind(this), | 156 | this._toggleCollapseMenu.bind(this), |
137 | ); | 157 | ); |
138 | this.actions.app.clearAllCache.listen(this._clearAllCache.bind(this)); | 158 | this.actions.app.clearAllCache.listen(this._clearAllCache.bind(this)); |
159 | this.actions.app.addDownload.listen(this._addDownload.bind(this)); | ||
160 | this.actions.app.removeDownload.listen(this._removeDownload.bind(this)); | ||
161 | this.actions.app.updateDownload.listen(this._updateDownload.bind(this)); | ||
162 | this.actions.app.endedDownload.listen(this._endedDownload.bind(this)); | ||
163 | this.actions.app.stopDownload.listen(this._stopDownload.bind(this)); | ||
164 | this.actions.app.togglePauseDownload.listen( | ||
165 | this._togglePauseDownload.bind(this), | ||
166 | ); | ||
139 | 167 | ||
140 | this.registerReactions([ | 168 | this.registerReactions([ |
141 | this._offlineCheck.bind(this), | 169 | this._offlineCheck.bind(this), |
@@ -300,6 +328,10 @@ export default class AppStore extends TypedStore { | |||
300 | return this.getAppCacheSizeRequest.execute().result; | 328 | return this.getAppCacheSizeRequest.execute().result; |
301 | } | 329 | } |
302 | 330 | ||
331 | @computed get isDownloading() { | ||
332 | return this.downloads.some(download => download.state === 'progressing'); | ||
333 | } | ||
334 | |||
303 | @computed get debugInfo() { | 335 | @computed get debugInfo() { |
304 | const settings = cleanseJSObject(this.stores.settings.app); | 336 | const settings = cleanseJSObject(this.stores.settings.app); |
305 | settings.lockedPassword = '******'; | 337 | settings.lockedPassword = '******'; |
@@ -518,6 +550,78 @@ export default class AppStore extends TypedStore { | |||
518 | this.locale = value; | 550 | this.locale = value; |
519 | } | 551 | } |
520 | 552 | ||
553 | @action _addDownload(download: Download) { | ||
554 | this.downloads.unshift(download); | ||
555 | debug('Download added', this.downloads); | ||
556 | } | ||
557 | |||
558 | @action _removeDownload(id: string | null) { | ||
559 | debug(`Removed download ${id}`); | ||
560 | if (id === null) { | ||
561 | const indexesToRemove: number[] = []; | ||
562 | this.downloads.map(item => { | ||
563 | if (!item.state) return; | ||
564 | if (item.state === 'completed' || item.state === 'cancelled') { | ||
565 | indexesToRemove.push(this.downloads.indexOf(item)); | ||
566 | } | ||
567 | }); | ||
568 | |||
569 | if (indexesToRemove.length === 0) return; | ||
570 | |||
571 | this.downloads = this.downloads.filter( | ||
572 | (_, index) => !indexesToRemove.includes(index), | ||
573 | ); | ||
574 | |||
575 | debug('Removed all completed downloads'); | ||
576 | return; | ||
577 | } | ||
578 | |||
579 | const index = this.downloads.findIndex(item => item.id === id); | ||
580 | if (index !== -1) { | ||
581 | this.downloads.splice(index, 1); | ||
582 | } | ||
583 | |||
584 | debug(`Removed download ${id}`); | ||
585 | } | ||
586 | |||
587 | @action _updateDownload(download: Download) { | ||
588 | const index = this.downloads.findIndex(item => item.id === download.id); | ||
589 | if (index !== -1) { | ||
590 | this.downloads[index] = { ...this.downloads[index], ...download }; | ||
591 | } | ||
592 | |||
593 | debug('Download updated', this.downloads[index]); | ||
594 | } | ||
595 | |||
596 | @action _endedDownload(download: Download) { | ||
597 | const index = this.downloads.findIndex(item => item.id === download.id); | ||
598 | if (index !== -1) { | ||
599 | this.downloads[index] = { ...this.downloads[index], ...download }; | ||
600 | } | ||
601 | |||
602 | debug('Download ended', this.downloads[index]); | ||
603 | |||
604 | if (!this.isDownloading && download.state === 'completed') { | ||
605 | this.justFinishedDownloading = true; | ||
606 | |||
607 | setTimeout(() => { | ||
608 | this.justFinishedDownloading = false; | ||
609 | }, ms('2s')); | ||
610 | } | ||
611 | } | ||
612 | |||
613 | @action _stopDownload(downloadId: string | undefined) { | ||
614 | ipcRenderer.send('stop-download', { | ||
615 | downloadId, | ||
616 | }); | ||
617 | } | ||
618 | |||
619 | @action _togglePauseDownload(downloadId: string | undefined) { | ||
620 | ipcRenderer.send('toggle-pause-download', { | ||
621 | downloadId, | ||
622 | }); | ||
623 | } | ||
624 | |||
521 | _setLocale() { | 625 | _setLocale() { |
522 | if (this.stores.user?.isLoggedIn && this.stores.user?.data.locale) { | 626 | if (this.stores.user?.isLoggedIn && this.stores.user?.data.locale) { |
523 | this._changeLocale(this.stores.user.data.locale); | 627 | this._changeLocale(this.stores.user.data.locale); |
diff --git a/src/stores/UIStore.ts b/src/stores/UIStore.ts index 4ed45fc3b..a3330c2e6 100644 --- a/src/stores/UIStore.ts +++ b/src/stores/UIStore.ts | |||
@@ -18,6 +18,7 @@ export default class UIStore extends TypedStore { | |||
18 | makeObservable(this); | 18 | makeObservable(this); |
19 | 19 | ||
20 | // Register action handlers | 20 | // Register action handlers |
21 | this.actions.ui.openDownloads.listen(this._openDownloads.bind(this)); | ||
21 | this.actions.ui.openSettings.listen(this._openSettings.bind(this)); | 22 | this.actions.ui.openSettings.listen(this._openSettings.bind(this)); |
22 | this.actions.ui.closeSettings.listen(this._closeSettings.bind(this)); | 23 | this.actions.ui.closeSettings.listen(this._closeSettings.bind(this)); |
23 | this.actions.ui.toggleServiceUpdatedInfoBar.listen( | 24 | this.actions.ui.toggleServiceUpdatedInfoBar.listen( |
@@ -97,6 +98,12 @@ export default class UIStore extends TypedStore { | |||
97 | } | 98 | } |
98 | 99 | ||
99 | // Actions | 100 | // Actions |
101 | @action _openDownloads({ path = '/downloadmanager' }): void { | ||
102 | const downloadsPath = | ||
103 | path === '/downloadmanager' ? path : `/downloadmanager/${path}`; | ||
104 | this.stores.router.push(downloadsPath); | ||
105 | } | ||
106 | |||
100 | @action _openSettings({ path = '/settings' }): void { | 107 | @action _openSettings({ path = '/settings' }): void { |
101 | const settingsPath = path === '/settings' ? path : `/settings/${path}`; | 108 | const settingsPath = path === '/settings' ? path : `/settings/${path}`; |
102 | this.stores.router.push(settingsPath); | 109 | this.stores.router.push(settingsPath); |